After reading the OOP section of falcon survival guide, especially the
"hacking-like"
prototype model in falcon, I raised some thoughts, which, personally,
looks more
consistent in language syntax level. I would like to post it here, to
request for
comments :-)
First, I'd like to refer a paper on this topic:
http://web.media.mit.edu/~lieber/Lieberary/OOP/Delegation/Delegation.html
And the basic concepts:
    http://en.wikipedia.org/wiki/Class-based_programming
    http://en.wikipedia.org/wiki/Prototype-based_programming
And here are the thoughts:
    * The paradigm should support both Class-based OOP and Prototype-
based OOP;
    * Basic elements in this paradigm are: <object>, <class>,
<instance>;
    * <object> is the basic element, an <object> consists of
properties and methods;
    * <object> implements the "prototype" concept in Prototype-based
OOP;
    * <object> is standalone and unique, and is not an <instance> of
any <class>;
* Example syntax of an <object> definition:
        object falcon
            creator = 'Giancarlo Niccolai'
            version = '0.9.6.2'
            paradigms = ['procedure', 'object-oriented', 'functional',
'message', 'tabular']
            function introduce()
                > 'Falcon is created by ' + self.creator + ', current
version is ' + self.version
            end
        end
* <object> can derive from another <object>, for example:
        object python
            // properties and methods for python
        end
        object lua
            // properties and methods for lua
        end
        object falcon from python, lua
            // properties and methods for falcon
        end
      Here, falcon inherits properties and methods from both python
and lua.
      Inside the syntax, falcon maintains a prototype-chain, which
support accessing
      missing properties and methods following the chain. This is
called "delegating";
    * <class> is a special <object>, it can be instanciated to create
many <instance>s;
    * <class> abstracts common properties and methods of a group of
<instance>s;
    * <instance> is NOT <object>, and <object> is NOT <instance>
either;
* Example syntax of a <class> definition:
        class committer(name)
            // class property
            static project = 'falcon'
            // instance member
            name = nil
            init
                this.name = name
            end
            // class method
            static function get_project()
                return self.project
            end
            // instance method
            function say()
                > 'I am ' + this.name + ', a committer of ' +
self.get_project() . ' project'
            end
        end
        jonnymind = committer('Giancarlo Niccolai')
        jonnymind.say()
* <class> can derive from another <class>, for example:
        class web_committer(name, category) from committer(name)
            // class property
            static svn_repository = 'svn://falcon.org/...'
            // instance property
            category = category
            // instance method
            function say()
                super.say()
                > 'And I work in ' + this.category . ' sub-project'
            end
        end
        diogin = web_committer('Jingcheng Zhang', 'nest')
        diogin.say()
      Of course, <class> can inherits from multiple <class>es just
like <object>;
    * So, properties in <object> are equivalent as static properties
in <class>,
      and methods in <object> are equivalent to static methods in
<class>, they
      all follow the rules of delegation to access the prototype-
chain;
    * <object> members or static members of <class> are referred with
"self.",
      and <instance> members are referred with "this.", which helps
developer
      differentiate the member-level easily.
Your ideas have some interesting points, which I'd like to keep into 
consideration; read below.
However, let me warn the audience about one very practical 
consideration. In my short and limited experience as a language 
designer, I have noticed that special syntax addressing a special 
problem is not always helpful as it may seem at first glance.
For example, LISP, one of the most powerful languages of all times, has 
nearly zero special syntax constructs, and a very simple set of basic 
syntax elements.
Conversely, languages having special syntax for everything tend to be 
rather "rigid". Often, problems resolved with special syntax constructs 
have been better profiled and resolved through a "function library" 
approach. Consider rules and constraint programming as solved by Prolog 
and as solved by C, Java and Python libraries. Despite the fact that the 
former was specifically meant to address that particular class of 
problems, the same problems expressed through "rules" object sets are 
even more readable and compact.
A still valid reason to provide special constructs may be assistance of 
the compiler in optimizing during compile time. However, modern 
approaches to compilation process has lessened this need; consider, just 
for instance, the special Python function "min(a,b)", which is resolved 
at compile time into VM opcodes and doesn't generate a real call to a 
function called "min".
Considering all this, the "hacking" approach to prototype OOP doesn't 
seem so "hacking" at all. Conversely, caging prototype OOP into a 
language-defined set of structures may deprive the final users of some 
potential that make POOP so interesting. In Falcon, Prototype OOP can be 
"programmed" from the inside and the outside, with the ability to 
dynamically change the structure of prototype "objects", (let's call 
them b-dict, blessed dictionaries, to avoid confusion with "instances"), 
without the need of special grammar to address this problem. Forcing a 
grammar into the current model would inevitably give off some of the 
potential of this paradigm, trading it off with a "clarity" which may be 
more a matter of personal taste than of an objective advantage.
Also, "grammarizing" the approach to prototype OOP seems to go against 
the modern 5th generation languages tendency which goes on the other 
direction. Consider the case of Lua, which is totally prototype OOP 
oriented and proudly refuses to introduce any grammar construct to deal 
with prototype OOP. Their tables, not unlike our dictionaries, are a 
perfect abstraction of the  media that should carry POOP values; or in 
other words, if you had to write a POOP support, you'd need to write a 
structure similar or identical to Lua tables to drive your POOP system. 
So, Lua ppl said: "Hey, we got the tables to make POOP; what about 
giving THEM to the users, so THEY do POOP instead of us doing it for them?"
As you can see, this approach has the disadvantage of taking some of the 
control a grammar framework can grant away from the compiler; but it has 
two relevant advantages of 1) making the compiler and the underlying 
language support simpler (and so, more efficient) and 2) making it more 
powerful and extensible.
We're in the same situation of Lua ppl, with some minor difference in 
the structure of our dictionaries with respect to their table; 
differences that do not affect the way POOP can be built.
Now, and here I follow your ideas, what we can do to make our POOP 
support stronger is twicefold:
1) providing some poop oriented method or function for dictionaries. For 
example, create a sort of inheritance declaration via
Dictionary.inherit( d1, d2 .... dn )
Even without special grammar, we may be able to perform some type 
inference (when we introduce type contracts) and be able to even solve 
part of this inheritances at compile time.
2) Providing language bound POOP "class" system (either in core or as a 
separate module). For a reference, search for the various Lua class 
libraries, which expose an "ordinary" POOP entity they call "class", 
with its own inheritance schemes, and the ability to create "instances" 
via a call to one of their member. Creation of an instance (entity) 
includes the addition of the "base class" automatically as one of its 
members.
However, whatever we do we cannot call "object" a POOP entity, mostly 
for historical reasons (because of the special meaning of the keyword 
"object" in Falcon), but we can use another term to name them. For 
example, we may go for "entity", or if you want to sound more 
"scientific", "p-entity".
About forking "self" and "this" I can't see any practical advantage, as 
the context of self or this is always the same: "the thing I am 
currently in". You'd just bring the same confusion you have in C (not 
C++) when you can access structures by "." or "->". The only interesting 
thing of having them different is that the compiler will slap you if you 
mistake one for  the other, and you'll have to go back and put in the 
right one. And then, the semantic difference between "." and "->" is 
even greater than the semantic difference between "this" object being an 
"instance", a "p-entity" or an "object".
However, you know I am open to change my mind if proven wrong; we did it 
several times since the beginning and we'll do it again for sure. So, if 
you feel my arguments are weak, don't be afraid to bash them :-)
Bests,
Giancarlo.
Your ideas have some interesting points, which I'd like to keep into consideration; read below.
However, let me warn the audience about one very practical consideration. In my short and limited experience as a language designer, I have noticed that special syntax addressing a special problem is not always helpful as it may seem at first glance.
For example, LISP, one of the most powerful languages of all times, has nearly zero special syntax constructs, and a very simple set of basic syntax elements.
Conversely, languages having special syntax for everything tend to be rather "rigid". Often, problems resolved with special syntax constructs have been better profiled and resolved through a "function library" approach. Consider rules and constraint programming as solved by Prolog and as solved by C, Java and Python libraries. Despite the fact that the former was specifically meant to address that particular class of problems, the same problems expressed through "rules" object sets are even more readable and compact.
A still valid reason to provide special constructs may be assistance of the compiler in optimizing during compile time. However, modern approaches to compilation process has lessened this need; consider, just for instance, the special Python function "min(a,b)", which is resolved at compile time into VM opcodes and doesn't generate a real call to a function called "min".
Considering all this, the "hacking" approach to prototype OOP doesn't seem so "hacking" at all. Conversely, caging prototype OOP into a language-defined set of structures may deprive the final users of some potential that make POOP so interesting. In Falcon, Prototype OOP can be "programmed" from the inside and the outside, with the ability to dynamically change the structure of prototype "objects", (let's call them b-dict, blessed dictionaries, to avoid confusion with "instances"), without the need of special grammar to address this problem. Forcing a grammar into the current model would inevitably give off some of the potential of this paradigm, trading it off with a "clarity" which may be more a matter of personal taste than of an objective advantage.
Also, "grammarizing" the approach to prototype OOP seems to go against the modern 5th generation languages tendency which goes on the other direction. Consider the case of Lua, which is totally prototype OOP oriented and proudly refuses to introduce any grammar construct to deal with prototype OOP. Their tables, not unlike our dictionaries, are a perfect abstraction of the media that should carry POOP values; or in other words, if you had to write a POOP support, you'd need to write a structure similar or identical to Lua tables to drive your POOP system. So, Lua ppl said: "Hey, we got the tables to make POOP; what about giving THEM to the users, so THEY do POOP instead of us doing it for them?"
As you can see, this approach has the disadvantage of taking some of the control a grammar framework can grant away from the compiler; but it has two relevant advantages of 1) making the compiler and the underlying language support simpler (and so, more efficient) and 2) making it more powerful and extensible.
We're in the same situation of Lua ppl, with some minor difference in the structure of our dictionaries with respect to their table; differences that do not affect the way POOP can be built.
Now, and here I follow your ideas, what we can do to make our POOP support stronger is twicefold:
1) providing some poop oriented method or function for dictionaries. For example, create a sort of inheritance declaration via
Dictionary.inherit( d1, d2 .... dn )
Even without special grammar, we may be able to perform some type inference (when we introduce type contracts) and be able to even solve part of this inheritances at compile time.
2) Providing language bound POOP "class" system (either in core or as a separate module). For a reference, search for the various Lua class libraries, which expose an "ordinary" POOP entity they call "class", with its own inheritance schemes, and the ability to create "instances" via a call to one of their member. Creation of an instance (entity) includes the addition of the "base class" automatically as one of its members.
However, whatever we do we cannot call "object" a POOP entity, mostly for historical reasons (because of the special meaning of the keyword "object" in Falcon), but we can use another term to name them. For example, we may go for "entity", or if you want to sound more "scientific", "p-entity".
About forking "self" and "this" I can't see any practical advantage, as the context of self or this is always the same: "the thing I am currently in". You'd just bring the same confusion you have in C (not C++) when you can access structures by "." or "->". The only interesting thing of having them different is that the compiler will slap you if you mistake one for the other, and you'll have to go back and put in the right one. And then, the semantic difference between "." and "->" is even greater than the semantic difference between "this" object being an "instance", a "p-entity" or an "object".
However, you know I am open to change my mind if proven wrong; we did it several times since the beginning and we'll do it again for sure. So, if you feel my arguments are weak, don't be afraid to bash them :-)
Bests,
Giancarlo.
--
You received this message because you are subscribed to the Google Groups "FalconPL" group.
To post to this group, send email to falc...@googlegroups.com.
To unsubscribe from this group, send email to falconpl+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/falconpl?hl=en.
Gian.
I am open to suggestions
GN.