prototypes in Python [was: what is good in Prothon]

Discussion in 'Python' started by Michele Simionato, Apr 28, 2004.

  1. So far, I have not installed Prothon, nor I have experience with Io, Self
    or other prototype-based languages. Still, from the discussion on the
    mailing list, I have got the strong impression that you do not actually
    need to fork Python in order to implement prototypes. It seems to me
    that Python metaclasses + descriptors are more than powerful enough to
    implementing prototypes in pure Python.

    I wrote a module that implements part of what David MacQuigg discussed in
    http://apache.ece.arizona.edu/~edatools/Python/Prototypes.htm in few lines
    of code (disclaimer: this is an horrible hack that changes Python semantics
    and makes "super" and "self" kinda of implicit reserved
    keywords, highly unpythonic). It requires Python 2.2+.
    I have not read the whole David MacQuigg's document, nor I have done any
    serious testing of the module, nor I claim I do understand what prototypes
    are; also I guarantee there will be bugs and surprising behaviors, but
    still I think they could be fixed if I was willing to spend more time
    on the issue.

    Here is an example of usage:

    from prototype import Prototype # prototypes are implemented as classes

    class Animal(Prototype):
    numAnimals = 0
    home = "Earth"
    def __init__(): # no need to pass self around
    Animal.numAnimals += 1
    def show():
    print "Animals:", self.numAnimals

    class Feline(Animal):
    genus="Feline"
    def __init__(name,sound): # no need to pass self around
    super.__init__()
    self.name=name
    self.sound=sound
    def talk(): # no need to pass self around
    print "%s talking: %s!" % (self.genus,self.sound)

    class Cat(Feline): # how to call the super prototype
    numCats = 0
    def __init__ ( n = "unknown", s = "Meow" ):
    super.__init__(n,s)
    Cat.numCats += 1
    def show():
    super.show()
    print " Cats:", self.numCats
    def talk():
    print "My name is", self.name
    print "I am a %s from %s" % (self.genus, self.home)
    super.talk()

    cat1 = Cat() # abuse of notation: makes a new prototype, not an instance

    print cat1 # =>
    # <class '__main__.Prototype:Cat'>

    cat2 = Cat("Garfield")
    cat2.home = "Tucson"

    print cat2 # =>
    # <class '__main__.Prototype:Cat'>

    cat1.talk() # =>
    # My name is unknown
    # I am a Feline from Earth
    # Feline talking: Meow!

    cat2.talk()# =>
    # My name is Garfield
    # I am a Feline from Tucson
    # Feline talking: Meow!

    cat2.show() # =>
    # Animals: 2
    # Cats: 2

    I am not sure this does what prototype people wants, but still it is
    a nice example of how to abuse Python ;) Originally, I tried to use
    "_" for "self" and "__" for "super", but with my fonts it was
    difficult to distinguish between them. With a preprocessor one
    could replace .name -> self.name and ..name -> super.name, but
    I did no bother to do that.

    Here is the module (not at all optimized):

    $ cat prototype.py
    import sys
    from types import FunctionType
    from inspect import isfunction

    class methodwrapper(object): # descriptor
    def __init__(self,func,cls):
    self.__func__=func
    self.__cls__=cls
    def __get__(self,none,cls):
    globs=sys.modules[cls.__module__].__dict__.copy()
    globs["self"]=cls
    globs["super"]=super(self.__cls__,cls)
    return FunctionType(
    self.__func__.func_code,
    globs,
    self.__func__.func_name,
    self.__func__.func_defaults,
    self.__func__.func_closure)

    class _Prototype(type): # metaclass
    def __init__(cls,name,bases,dic):
    for k,v in dic.iteritems():
    if isfunction(v):
    setattr(cls,k,methodwrapper(v,cls))
    super(_Prototype,cls).__init__(name,bases,dic)
    def __call__(cls,*args,**kw):
    newcls = type("Prototype:%s" % cls.__name__,(cls,),
    {"__module__": cls.__module__})
    newcls.__init__(*args,**kw)
    return newcls

    class Prototype(object): # mother of all prototypes
    __metaclass__=_Prototype
    def __init__(*args,**kw):
    pass

    #### END ####

    Michele Simionato
     
    Michele Simionato, Apr 28, 2004
    #1
    1. Advertising

  2. Michele Simionato

    has Guest

    (Michele Simionato) wrote in message news:<>...
    > So far, I have not installed Prothon, nor I have experience with Io, Self
    > or other prototype-based languages. Still, from the discussion on the
    > mailing list, I have got the strong impression that you do not actually
    > need to fork Python in order to implement prototypes. It seems to me
    > that Python metaclasses + descriptors are more than powerful enough to
    > implementing prototypes in pure Python.


    "Metaclasses" and "prototypes"... <ouch> Now there's two words that
    should NEVER appear in the same sentence (or even on the same planet,
    for that matter). Metaclasses may be Manna for complexity junkies, but
    they're nothing but a viciously bad joke imposed by those who ought to
    have known better and perpetuated by those who never will.

    One of the great advantages of proto-OO is it shows up metaclasses for
    the ludicrous code masturbation they are. As to why they're still
    here, lingering like the stench of long-dead rat from under the floor
    when they should've been shitcanned years ago... well, draw your own
    conclusions. (Two words of my own: "politics" and "religion".)

    [BTW, this is a totally generic rant; please don't think it was meant
    personally! It's just that, well... if there's two words guaranteed to
    push ALL my wrong buttons, those two are it.<g> Anyway, <Rant Off> -
    and let's get back to our scheduled program...]

    --

    As far as doing proto-OOP in Python is concerned, you can, but it'd be
    a bit like doing OOP [of any flavour] in C. i.e. Not much fun. You
    basically have to roll your own structures and runtime support, and
    provide syntactic sugar via some kind of pre-processor or compiler
    extension if you want it to be halfway decent for users to code in.

    Here's a very simple, incomplete and very naive example to give you an
    idea of how you might start attacking it:

    #############################

    class _DelegateStub:
    """Terminates the delegate chain."""

    delegate = None
    copy = staticmethod(lambda:_DelegateStub)


    class Object:
    """This class defines the generic proto-OO object 'type' used to
    create all objects."""

    delegate = None # kludge
    _dict = None # kludge

    def __init__(self):
    self.delegate = _DelegateStub
    self._dict = {}

    def __getattr__(self, name):
    if self._dict.has_key(name):
    return self._dict[name]
    else:
    return getattr(self.delegate, name)

    def __setattr__(self, name, value):
    if name in ['delegate', '_dict']:
    self.__dict__[name] = value
    else:
    self._dict[name] = value

    def copy(self):
    """Clone this object."""
    new = Object()
    new.delegate = self.delegate.copy()
    new._dict = self._dict.copy()
    return new


    # Creating a new object from scratch:

    # Define object 'foo'
    foo = Object()
    foo.a = 3
    foo.b = 3
    foo.multiply = lambda target:target.a*target.b


    # Do stuff with object (note: due to lack of runtime magic, user
    # must pass the target object to an object's 'method' themselves):

    print foo.a, foo.b # --> 3 3
    print foo.multiply(foo) # --> 9


    # Creating a new object by cloning an existing one:

    # Create object 'bar' by duplicating object 'foo'
    bar = foo.copy()

    print bar.multiply(bar) # --> 9

    # Object 'bar' can be modified at will:

    bar.a = -5
    bar.c = 'hello world'

    print bar.c # --> 'hello world'

    print foo.multiply(foo) # --> 9
    print bar.multiply(bar) # --> -15


    # Behavioural composition through delegation:

    # Create object 'zib' containing method 'power' with 'bar' as its
    delegate
    zib = Object()
    zib.power = lambda target:target.a**target.b
    zib.delegate = bar

    print zib.c # --> 'hello world'
    print zib.power(zib) # --> -125

    #############################

    Obviously, implementing a complete proto-OO system in and atop
    Python's native class-OO system is going to be both tedious to use
    (due to lack of syntactic sugar) and slow to execute (as it's all
    interpreted Python code). Which is why it makes sense to start from
    scratch as Mark is doing, or at least fork an existing language and
    seriously strip down and rebuild it (which is a thought that's
    previously crossed my own mind, though I lack the time, patience and C
    skills to tacke such a project myself).
     
    has, Apr 28, 2004
    #2
    1. Advertising

  3. On 28 Apr 2004 02:20:06 -0700, (Michele
    Simionato) wrote:

    >So far, I have not installed Prothon, nor I have experience with Io, Self
    >or other prototype-based languages. Still, from the discussion on the
    >mailing list, I have got the strong impression that you do not actually
    >need to fork Python in order to implement prototypes. It seems to me
    >that Python metaclasses + descriptors are more than powerful enough to
    >implementing prototypes in pure Python.
    >
    >I wrote a module that implements part of what David MacQuigg discussed in
    >http://apache.ece.arizona.edu/~edatools/Python/Prototypes.htm in few lines
    >of code (disclaimer: this is an horrible hack that changes Python semantics
    >and makes "super" and "self" kinda of implicit reserved
    >keywords, highly unpythonic). It requires Python 2.2+.
    >I have not read the whole David MacQuigg's document, nor I have done any
    >serious testing of the module, nor I claim I do understand what prototypes
    >are; also I guarantee there will be bugs and surprising behaviors, but
    >still I think they could be fixed if I was willing to spend more time
    >on the issue.


    This is amazing! I don't understand how it works, but it does provide
    what I think the "classless" advocates are looking for, an ability to
    "clone" one object from another, and avoid any "two-tier" organization
    of instances and classes.

    >>> cat3 = cat1("Fluffy", "Purr") # Make a new cat from a previous.
    >>> cat3.talk()

    My name is Fluffy
    I am a Feline from Earth
    Feline talking: Purr!

    It is a shame that the discussion has degenerated to the point where
    most people are ignoring threads relating to prototypes. I have tried
    repeatedly to get a simple requirements statement or use case, and get
    nothing but sarcastic remarks. I have no experience with prototype
    languages either, except a little with Prothon. I started to read a
    paper, but fell asleep after a discussion on the "theory of
    knowledge".

    In spite of all this, there are some nuggets along the way. The
    unification of methods and functions is the one I am most interested
    in. The code below seems to have the machinery to do that, with the
    elimination of 'self' from the argument list. That alllows static
    methods to have exactly the same form as normal methods. ( The 'show'
    methods below are actually static methods if you remove any references
    to 'self', and replace them with explicit references, i.e.
    self.numAnimals --> Animal.numAnimals ).

    I agree with you that Python has the capability to implement
    prototypes. Perhaps we can do that using metaclasses for some initial
    experiments. Then if we get some constructive feedback, we can put
    together a PEP to make prototypes part of the core language, add
    better syntax, and fix whatever might not work quite right using
    metaclasses.

    I'm collecting ideas for Python 3 and 4 and putting them on my webpage
    at http://ece.arizona.edu/~edatools/Python Python 3 includes features
    that are not compatible with Python 2, but I believe are consistent to
    the extent that Python 2 programs can be automatically translated to
    Python 3. Python 4 has no such contraint. All that matters is that
    the language is simple and elegant, and does useful things, as opposed
    to things that are theoretically interesting. Your comments and
    suggestions are welcome.

    -- Dave

    >Here is an example of usage:
    >
    >from prototype import Prototype # prototypes are implemented as classes
    >
    >class Animal(Prototype):
    > numAnimals = 0
    > home = "Earth"
    > def __init__(): # no need to pass self around
    > Animal.numAnimals += 1
    > def show():
    > print "Animals:", self.numAnimals
    >
    >class Feline(Animal):
    > genus="Feline"
    > def __init__(name,sound): # no need to pass self around
    > super.__init__()
    > self.name=name
    > self.sound=sound
    > def talk(): # no need to pass self around
    > print "%s talking: %s!" % (self.genus,self.sound)
    >
    >class Cat(Feline): # how to call the super prototype
    > numCats = 0
    > def __init__ ( n = "unknown", s = "Meow" ):
    > super.__init__(n,s)
    > Cat.numCats += 1
    > def show():
    > super.show()
    > print " Cats:", self.numCats
    > def talk():
    > print "My name is", self.name
    > print "I am a %s from %s" % (self.genus, self.home)
    > super.talk()
    >
    >cat1 = Cat() # abuse of notation: makes a new prototype, not an instance
    >
    >print cat1 # =>
    ># <class '__main__.Prototype:Cat'>
    >
    >cat2 = Cat("Garfield")
    >cat2.home = "Tucson"
    >
    >print cat2 # =>
    ># <class '__main__.Prototype:Cat'>
    >
    >cat1.talk() # =>
    ># My name is unknown
    ># I am a Feline from Earth
    ># Feline talking: Meow!
    >
    >cat2.talk()# =>
    ># My name is Garfield
    ># I am a Feline from Tucson
    ># Feline talking: Meow!
    >
    >cat2.show() # =>
    ># Animals: 2
    ># Cats: 2
    >
    >I am not sure this does what prototype people wants, but still it is
    >a nice example of how to abuse Python ;) Originally, I tried to use
    >"_" for "self" and "__" for "super", but with my fonts it was
    >difficult to distinguish between them. With a preprocessor one
    >could replace .name -> self.name and ..name -> super.name, but
    >I did no bother to do that.
    >
    >Here is the module (not at all optimized):
    >
    >$ cat prototype.py
    >import sys
    >from types import FunctionType
    >from inspect import isfunction
    >
    >class methodwrapper(object): # descriptor
    > def __init__(self,func,cls):
    > self.__func__=func
    > self.__cls__=cls
    > def __get__(self,none,cls):
    > globs=sys.modules[cls.__module__].__dict__.copy()
    > globs["self"]=cls
    > globs["super"]=super(self.__cls__,cls)
    > return FunctionType(
    > self.__func__.func_code,
    > globs,
    > self.__func__.func_name,
    > self.__func__.func_defaults,
    > self.__func__.func_closure)
    >
    >class _Prototype(type): # metaclass
    > def __init__(cls,name,bases,dic):
    > for k,v in dic.iteritems():
    > if isfunction(v):
    > setattr(cls,k,methodwrapper(v,cls))
    > super(_Prototype,cls).__init__(name,bases,dic)
    > def __call__(cls,*args,**kw):
    > newcls = type("Prototype:%s" % cls.__name__,(cls,),
    > {"__module__": cls.__module__})
    > newcls.__init__(*args,**kw)
    > return newcls
    >
    >class Prototype(object): # mother of all prototypes
    > __metaclass__=_Prototype
    > def __init__(*args,**kw):
    > pass
    >
    >#### END ####
    >
    > Michele Simionato
     
    David MacQuigg, May 1, 2004
    #3
  4. David MacQuigg <> wrote in message news:<>...
    > The unification of methods and functions is the one I am most interested
    > in. The code below seems to have the machinery to do that, with the
    > elimination of 'self' from the argument list. That alllows static
    > methods to have exactly the same form as normal methods. ( The 'show'
    > methods below are actually static methods if you remove any references
    > to 'self', and replace them with explicit references, i.e.
    > self.numAnimals --> Animal.numAnimals ).


    Probably you do not realize that methods and functions are *already*
    unified in Python: they are both examples of descriptors. Descriptors
    are maybe the most important thing in Python 2.2+, since the whole new style
    object system is based on them. Not only: you can use descriptors to
    implement an object system of your choice, as I did in the prototype
    module; metaclasses just provide convenient syntactic sugar.

    BTW, descriptors are very well discussed here:
    http://users.rcn.com/python/download/Descriptor.htm

    > I agree with you that Python has the capability to implement
    > prototypes. Perhaps we can do that using metaclasses for some initial
    > experiments. Then if we get some constructive feedback, we can put
    > together a PEP to make prototypes part of the core language, add
    > better syntax, and fix whatever might not work quite right using
    > metaclasses.


    Actually, I do NOT support the idea of making prototypes part of the
    core language. If somebody wants to write and mantain a prototype module
    that's fine, but I would be opposed to have it in the standard library.
    There should be only one obvious object system in Python, and that
    object system is not a prototype based one ;)
    OTOH, there is nothing wrong about having a prototype module for people
    wanting to experiment with prototypes without being forced to
    abandon Python and its libraries.

    > I'm collecting ideas for Python 3 and 4 and putting them on my webpage
    > at http://ece.arizona.edu/~edatools/Python Python 3 includes features
    > that are not compatible with Python 2, but I believe are consistent to
    > the extent that Python 2 programs can be automatically translated to
    > Python 3. Python 4 has no such contraint. All that matters is that
    > the language is simple and elegant, and does useful things, as opposed
    > to things that are theoretically interesting. Your comments and
    > suggestions are welcome.
    >
    > -- Dave


    If I was writing a new language, I would do Python with prefix notation ;)

    Seriously, I think that everybody interested in language design should
    first study the existing languages and see what has already been
    tried in the last fifty years: then probably 99% of "new" proposal
    would be dismissed. I have not studied prototypes, so I may be wrong,
    but I have a gut feeling that they are not such a good idea.

    One thing I like about classes is that they are self-documenting: when you
    see a class, you know which methods are in it. Of course, you can add
    methods at run-time, but this is not good style: it is good to have the
    ability, but you should not abuse it. OTOH, in prototype languages you
    dynamically add methods all the time and the definitions are scattared in
    different places, so it is not obvious to know what an object is doing
    unless you read all the program (including imported modules).
    This is already a problem with regular inheritance, prototype inheritance
    would worsen the situation, at least ISTM and IMHO.


    Michele Simionato
     
    Michele Simionato, May 2, 2004
    #4
  5. (has) wrote in message news:<>...
    > # Define object 'foo'
    > foo = Object()
    > foo.a = 3
    > foo.b = 3
    > foo.multiply = lambda target:target.a*target.b
    >


    I think this is the syntactic sugar that is missing: anonymous
    functions come in one breed only: lambdas. This example fits neatly
    into a lambda function, but more complicated examples won't.

    For instance, you can't write:

    def foo.multiply(self):
    return self.a * self.b

    I would imagine an easy way to do this would be to have this be
    acceptable:

    foo.multiple = def(self):
    returns self.a * self.b

    This will create an anonymous function and store it in foo.multiple.

    I'll admit that classless OO programming looks neat. The only thing
    that I can't see an obvious way of doing is to share a value or method
    across multiple objects. For instance:

    class A:
    number = 0
    def __init__(self):
    number += 1
    def __del__(self):
    number -= 1

    How would you share "number" across a similar class of objects?

    Also, it kind of renders the question, "What kind of object is this?"
    meaningless. There are no /kinds/ anymore, at least not built into the
    language. You can go ahead and create objects that are classes, and
    then make objects that have an attribute called "class", I guess.

    I do enjoy seeing different perspectives from other communities. It
    helps me get a new perspective with my own programming.
     
    Jonathan Gardner, May 2, 2004
    #5
  6. Michele Simionato

    has Guest

    (Michele Simionato) wrote in message news:<>...

    > Actually, I do NOT support the idea of making prototypes part of the
    > core language.


    Ditto. [To paraphrase:] There should be one, and preferably only one,
    way of doing things. Including OOP.


    > If I was writing a new language, I would do Python with prefix notation ;)


    You sick disturbed Lisp lover, you... ;p


    > Seriously, I think that everybody interested in language design should
    > first study the existing languages and see what has already been
    > tried in the last fifty years: then probably 99% of "new" proposal
    > would be dismissed.


    Amen. (I figure in another ten or fifteen years somebody will finally
    get round to successfully re-inventing Lisp as the Next Big Thing, and
    then things can actually start moving forward again...)


    > I have not studied prototypes, so I may be wrong,
    > but I have a gut feeling that they are not such a good idea.


    I have a gut feeling you should study them first, before asking your
    gut for its opinion. A gut's gotta have something solid to chew on. ;)


    > One thing I like about classes is that they are self-documenting: when you
    > see a class, you know which methods are in it.


    <cough>Dylan</cough>

    (And Dylan is one of those languages that makes me tear up at the
    thought of it. Perhaps someday its prince will come? One can but
    hope...)


    > Of course, you can add
    > methods at run-time, but this is not good style: it is good to have the
    > ability, but you should not abuse it. OTOH, in prototype languages you
    > dynamically add methods all the time and the definitions are scattared in
    > different places, so it is not obvious to know what an object is doing
    > unless you read all the program (including imported modules).


    I would say proto-OO philosophy is a bit closer to Lisp philosophy
    than Java philosophy. However, I think you'll find good proto-OO
    programmers have no more problems staying disciplined than good
    class-based programmers.

    Now, whether mediocre programmers would manage to screw up any worse
    in proto-OO than class-OO is a separate question; but then, spaghetti
    is spaghetti whatever the language. Sure you can spread object
    behaviour from one end of the source to the other if you want to, but
    you can also write 1000-line procedures in C - and it's not like you
    can blame C's object model for that because it doesn't even have one.


    So perhaps the solution isn't creating a more restrictive, less
    flexible language (and then retroactively slapping all sorts of mad
    complexity on top to cater for the competent users who quickly object
    to the limitations it indiscriminately imposes upon them); but
    creating a simple, open language that can scale extremely well as-is,
    and providing training wheels to the more thoughtless, naive users
    till they learn some responsibility for themselves.

    Of course, that leaves you with the political problem that no l33t
    hAx0r would ever admit to needing training wheels and will insist on
    taking the biggest baddest Ferrari regardless of whether they're
    competent to handle it or not. But then, it's not my responsibility to
    keep them from wrapping their dumb selves round the first lamppost
    they meet if that's what they'll insist on doing. Plus it's one less
    doofus to be getting in my road later.;)


    > This is already a problem with regular inheritance, prototype inheritance
    > would worsen the situation, at least ISTM and IMHO.


    Feel free to check out any of my proto-OO programming efforts, and
    critique away. <g>

    You might also check out my HTMLTemplate Python module, which although
    it uses MI for behavioural composition retains many other aspects of
    its original proto-OO design and philosophy. In a field dominated by
    vast, lumbering PHP-copycats and wannabes, I think it rather makes for
    one of those "breaths of fresh air" somebody mentioned earlier. ;)
     
    has, May 2, 2004
    #6
  7. Michele Simionato

    has Guest

    (Jonathan Gardner) wrote in message news:<>...

    > I'll admit that classless OO programming looks neat. The only thing
    > that I can't see an obvious way of doing is to share a value or method
    > across multiple objects.


    A couple of ways I can think of:

    1. Store the value in a module-level variable. This is not so odd an
    idea as it seems; e.g. see Dylan as one example of a [class-based] OO
    language where encapsulation primarily happens at module rather than
    class level. My own proto-OO code is generous in its use of modules
    and procedures. BTW, this may work particularly well in a language
    that has first-class syntactic support for declaring objects, as
    that'll allow you to put multiple modules within a single file (and
    modules within those modules, and so on, if that's what you want).

    2. Create a single shared object to store this value, and pop a
    reference to it into a slot in every object that uses it so they can
    access it there. If you also want this value available to the objects'
    clients as well as the objects themselves, you can always make that
    slot into a parent slot so that external requests for the value are
    automatically delegated to it.


    > Also, it kind of renders the question, "What kind of object is this?"
    > meaningless. There are no /kinds/ anymore, at least not built into the
    > language.


    Yep. In its purest form, a proto-OO language would have only a single
    'type' - object - and no 'classes' at all. While folk who are used to
    relying on type/class information to make their programs work may
    freak a bit at the thought of this, languages like Python and Ruby
    have already demonstrated that 'duck typing' can work well. (Again,
    it's mostly just a matter of the developer having a bit of discipline
    in the first place than relying on the compiler to pick up their slop
    after the event. I actually regard this particular justification for
    static typing - "it helps reduce bugs" - as a physical abuse of the
    type system. Anyway, if I ever feel the need for strong compile-time
    typing I'll go learn OCaml or something else with a really smart,
    sophisticated type system, not C/C++/Java. Or Dylan, which'll give me
    best of both worlds.)


    > I do enjoy seeing different perspectives from other communities. It
    > helps me get a new perspective with my own programming.


    Absolutely! Personally I'm only fluent in two languages - AppleScript
    (my alma mater) and Python (my current development platform of choice)
    - but I've tinkered with a few others (a little C, Perl, JavaScript,
    for example), and read up on at least a dozen more (Lisp, Forth, Java,
    Smalltalk, Eiffel, ML/OCaml, Ruby, Dylan, HyperCard, Obj-C to pop some
    names off the top of my head; and various niche languages I can't even
    remember the names of). Often I just get a vague impression of what
    these languages are trying to do, particularly on my first attempt to
    understand them, but after a while the pieces start to slot into place
    and I'll maybe go read some more. Sure I'm a shallow dilletante who
    clearly hasn't got enough Real Work to go do with themselves, but just
    wait till I REALLY get started! (Which is sure to be any day now, oh
    yes; any day...;)
     
    has, May 2, 2004
    #7
  8. Michele Simionato

    has Guest

    David MacQuigg <> wrote in message news:<>...

    > This is amazing! I don't understand how it works, but it does provide
    > what I think the "classless" advocates are looking for, an ability to
    > "clone" one object from another, and avoid any "two-tier" organization
    > of instances and classes.


    I posted an incomplete implementation of a simple proto-OO model built
    on top of Python the other day. (As opposed to trying to mix it into
    Python's existing class-based object system, which doesn't really gel
    so well.) Here's the link:


    > It is a shame that the discussion has degenerated to the point where
    > most people are ignoring threads relating to prototypes.


    Well, it has little direct bearing on Python discussions so most folk
    probably aren't interested anyway.

    > I have tried
    > repeatedly to get a simple requirements statement or use case, and get
    > nothing but sarcastic remarks. I have no experience with prototype
    > languages either,


    That would probably be your problem then. I think you need to knuckle
    down and do some self-motivated research before trying to wade in at
    the deep end. I mean, if a forty-watter like me can manage to digest
    it, a smart person like yourself shouldn't have any trouble [as long
    as you go into it with a completely open mind].

    > except a little with Prothon.


    Pick a language that's a bit more established and mature (and isn't
    currently right in the middle of a great philosophical war;).

    > I started to read a paper, but fell asleep after a discussion on the "theory of
    > knowledge".


    Well, you still got further than me. Reading/writing papers is
    definitely _not_ one of my strong points; I'm much more the hands-on
    "give it a go and see what happens" type. I'm not averse to lightly
    skimming the odd bit of high-falutin' academic papery, however, and
    even when I really don't understand what it's about at least I come
    away with the vague notion that there are Other Ideas that exist out
    there, rather than hiding in my own self-imposed box pretending that's
    really all there is. Better to serve [fries] in heaven than rule in
    [cobol] hell, I say.


    > In spite of all this, there are some nuggets along the way. The
    > unification of methods and functions is the one I am most interested
    > in.


    This is not a proto-OO issue.

    BTW, if you want to see _really_ interesting things done with methods
    and functions, go check out, say, Dylan. Multimethods are one of those
    things that can sound really complex and intimidating at first
    encounter - especially if you're only ever thought of OOP in terms of
    how Java, Python, etc. do it - but are actually _incredibly_simple_,
    not to mention rather beautiful. Go grok 'em; it'll really broaden
    your mind.


    > I agree with you that Python has the capability to implement
    > prototypes. Perhaps we can do that using metaclasses for some initial
    > experiments. Then if we get some constructive feedback, we can put
    > together a PEP to make prototypes part of the core language, add
    > better syntax, and fix whatever might not work quite right using
    > metaclasses.


    Wrong strategy. You cannot simplify an already complex thing by adding
    even more stuff to it. I for one am already absolutely convinced that
    proto-OO is ultimately the right way forward for the future of OOP on
    dynamic languages, and that all the stuff we see and hear about Next
    Big Things in [traditional] OOP, such as metaclasses and aspects, is
    all just an almighty cloud of smoke generated by faddish, under-read
    folk who have failed/refused to see/acknowledge that the problems they
    are currently trying to solve now were/are A. already solved years
    ago, but ignored then as now because they didn't fit neatly with the
    then/current orthodoxy and would require significant backtracking to
    adopt; and B. mostly generated by the various Really Bright Ideas To
    Solve Our Problems they cooked up the last time round.

    Of course, the longer that invested parties refuse to acknowledge the
    fundamental flaws and mis-features in the foundation of their great
    and grandiose sand castles in the sky and persist in pretending that
    the solution is slopping even more flaws and mis-features on top, the
    worse it's going to be for everybody when the whole lot _finally_
    collapses under its own weight. So when that day comes, expect to see
    me standing well to the side laughing my ass off.;)

    has
     
    has, May 2, 2004
    #8
  9. On 1 May 2004 22:34:27 -0700, (Michele
    Simionato) wrote:

    >David MacQuigg <> wrote in message news:<>...
    >> The unification of methods and functions is the one I am most interested
    >> in. The code below seems to have the machinery to do that, with the
    >> elimination of 'self' from the argument list. That alllows static
    >> methods to have exactly the same form as normal methods. ( The 'show'
    >> methods below are actually static methods if you remove any references
    >> to 'self', and replace them with explicit references, i.e.
    >> self.numAnimals --> Animal.numAnimals ).

    >
    >Probably you do not realize that methods and functions are *already*
    >unified in Python: they are both examples of descriptors. Descriptors
    >are maybe the most important thing in Python 2.2+, since the whole new style
    >object system is based on them. Not only: you can use descriptors to
    >implement an object system of your choice, as I did in the prototype
    >module; metaclasses just provide convenient syntactic sugar.


    Interesting! I wish that unification at the primitive level had been
    provided in the original design of Python. Seems like the multiple
    method styles we have now are just an historical accident.

    >BTW, descriptors are very well discussed here:
    >http://users.rcn.com/python/download/Descriptor.htm


    Good article, but beyond my current capabilities and available time.
    I'll keep this on my reference list.

    >> I agree with you that Python has the capability to implement
    >> prototypes. Perhaps we can do that using metaclasses for some initial
    >> experiments. Then if we get some constructive feedback, we can put
    >> together a PEP to make prototypes part of the core language, add
    >> better syntax, and fix whatever might not work quite right using
    >> metaclasses.

    >
    >Actually, I do NOT support the idea of making prototypes part of the
    >core language. If somebody wants to write and mantain a prototype module
    >that's fine, but I would be opposed to have it in the standard library.
    >There should be only one obvious object system in Python, and that
    >object system is not a prototype based one ;)
    >OTOH, there is nothing wrong about having a prototype module for people
    >wanting to experiment with prototypes without being forced to
    >abandon Python and its libraries.


    I'm coming to the same conclusion, especially now I see that
    prototypes can be done so easily in Python. If there is serious
    interest in prototypes, someone will make the effort to finish your
    module and commit to maintaining it. So far, I've seen too few
    reasonable people favoring prototypes, and too many thoreticians,
    egotistical fools, and anonymous trolls. :>)

    >> I'm collecting ideas for Python 3 and 4 and putting them on my webpage
    >> at http://ece.arizona.edu/~edatools/Python Python 3 includes features
    >> that are not compatible with Python 2, but I believe are consistent to
    >> the extent that Python 2 programs can be automatically translated to
    >> Python 3. Python 4 has no such contraint. All that matters is that
    >> the language is simple and elegant, and does useful things, as opposed
    >> to things that are theoretically interesting. Your comments and
    >> suggestions are welcome.

    >
    >If I was writing a new language, I would do Python with prefix notation ;)
    >
    >Seriously, I think that everybody interested in language design should
    >first study the existing languages and see what has already been
    >tried in the last fifty years: then probably 99% of "new" proposal
    >would be dismissed. I have not studied prototypes, so I may be wrong,
    >but I have a gut feeling that they are not such a good idea.


    So many languages. So little time. :>) Actually, I have found my
    study of Ruby and Prothon to be helpful in learning Python better, and
    it re-inforced my opinion that Python is the best choice for my own
    project -- a circuit-design platform that I hope will be useful for
    many years. Key factors in this choice are the excellent libraries,
    third-party software, books, and large community that have been built
    over the last ten years. The flaws in Python syntax are really minor
    compared to all this.

    Still, I wish there was something I could do about the flaws. From my
    study of Ruby, I know that Python's string methods could be improved.
    From Prothon, I know that all forms of functions and methods could be
    unified in one simple form. It doesn't look like there is much
    interest in these problems in the Python community, however, so I
    think it is time to get back to my real job.

    >One thing I like about classes is that they are self-documenting: when you
    >see a class, you know which methods are in it. Of course, you can add
    >methods at run-time, but this is not good style: it is good to have the
    >ability, but you should not abuse it. OTOH, in prototype languages you
    >dynamically add methods all the time and the definitions are scattared in
    >different places, so it is not obvious to know what an object is doing
    >unless you read all the program (including imported modules).
    >This is already a problem with regular inheritance, prototype inheritance
    >would worsen the situation, at least ISTM and IMHO.


    I couldn't have said it better. With an interactive interpreter and a
    good editor, it is real easy to change any class or module. When I
    want to make such a change, I don't rely on my memory to make changes
    "on-the-fly". I find that class and spend a few minutes looking at it
    to make sure my changes don't have unintended consequences. Then I
    spend even longer re-running old tests to make sure I haven't broken
    something totally unexpected. The new IDLE editor is nice, because I
    can just hit F5 after every edit, and it re-initializes everything.

    This is not to say that "on-the-fly" programming is wrong. It just
    doesn't fit my need, which is a well-organized hierarchical system of
    classes and instances, one that I can maintain, and expect others to
    work on. I just can't imagine writing something like this by sticking
    in last-minute "with" blocks containing numerous variables I forgot to
    put in the original class definition.

    -- Dave
     
    David MacQuigg, May 3, 2004
    #9
  10. Michele Simionato

    has Guest

    (has) wrote in message news:<>...

    > I posted an incomplete implementation of a simple proto-OO model built
    > on top of Python the other day. (As opposed to trying to mix it into
    > Python's existing class-based object system, which doesn't really gel
    > so well.) Here's the link:


    Oops, no, duh. HERE'S the link:

    http://groups.google.com/groups?hl=
     
    has, May 3, 2004
    #10
  11. Michele Simionato

    Greg Ewing Guest

    David MacQuigg wrote:

    > On 1 May 2004 22:34:27 -0700, (Michele
    > Simionato) wrote:
    >
    >>Probably you do not realize that methods and functions are *already*
    >>unified in Python: they are both examples of descriptors.

    >
    > Interesting! I wish that unification at the primitive level had been
    > provided in the original design of Python.


    It was. Methods have always been no more than functions that
    happen to live in classes, and they still are. Descriptors are
    a red herring here; they're just a generalisation that allows for
    some new things. They don't unify anything that was previously
    existing but not unified.

    --
    Greg Ewing, Computer Science Dept,
    University of Canterbury,
    Christchurch, New Zealand
    http://www.cosc.canterbury.ac.nz/~greg
     
    Greg Ewing, May 4, 2004
    #11
  12. On Tue, 04 May 2004 16:54:34 +1200, Greg Ewing
    <> wrote:

    >David MacQuigg wrote:
    >
    >> On 1 May 2004 22:34:27 -0700, (Michele
    >> Simionato) wrote:
    > >
    >>>Probably you do not realize that methods and functions are *already*
    >>>unified in Python: they are both examples of descriptors.

    > >
    >> Interesting! I wish that unification at the primitive level had been
    >> provided in the original design of Python.

    >
    >It was. Methods have always been no more than functions that
    >happen to live in classes, and they still are. Descriptors are
    >a red herring here; they're just a generalisation that allows for
    >some new things. They don't unify anything that was previously
    >existing but not unified.


    The unification I'm talking about is what the *user* sees. Currently
    in Python , depending on the method style, you might need obj1.func()
    or obj2.func(obj1) depending on the types of obj1 and obj2. This is
    unnecessary complexity. It adds nothing to the fundamental
    capabilities of the language. All methods and functions *should* look
    the same to the user.

    For an example of how this *could* be done see the PrototypeSyntax
    documents at http://ece.arizona.edu/~edatools/Python/ For an example
    of how the presentation of OOP in Python could be cut in half, see the
    Prototypes documents linked on that same page.

    Ruby and Prothon got it right. There are no special "static methods".
    Python should have done the same in its original design. Now it will
    take an incompatible change in Python to fix it. I'm hoping this will
    be done in Python 3. If not, something like Prothon will eventually
    replace Python.

    -- Dave
     
    David MacQuigg, May 4, 2004
    #12
  13. (has) wrote in message news:<>...
    > > Also, it kind of renders the question, "What kind of object is this?"
    > > meaningless. There are no /kinds/ anymore, at least not built into the
    > > language.

    >
    > Yep. In its purest form, a proto-OO language would have only a single
    > 'type' - object - and no 'classes' at all. While folk who are used to
    > relying on type/class information to make their programs work may
    > freak a bit at the thought of this, languages like Python and Ruby
    > have already demonstrated that 'duck typing' can work well. (Again,
    > it's mostly just a matter of the developer having a bit of discipline
    > in the first place than relying on the compiler to pick up their slop
    > after the event.


    I have spent some time thinking about this and looking at my own code.
    Isn't it currently discouraged to use "type" to classify objects, and
    then depend on the type returned? Instead, we should look at the
    actual interface to see if it implements what we need rather than
    trying to force it to descend from a particular class.

    Shared class data is trivial to implement in a classless system, as
    you demonstrated. In fact, so is typing - just have an attribute
    called "__class__" and methods for determining if a particular class
    is in the inheritance tree of this object's class. We can even go as
    far as to implement a system of calling the class's methods or
    attributes if they are not present in the object itself. (Looks
    familiar? Isn't this the way Python works right now?)

    Because implementing the current Python object system in classless
    objects is so easy to do, it is apparent that classless objects are a
    superset (IE, contain all the features of and perhaps some more) of
    classful objects. Therefore, if Python were to approach a classless
    object system, it would be enhancing its featureset while being able
    to simultaneously maintain backwards compatibility. (At least,
    theoretically. I know that the internals of the python interpreter and
    run time engine depend heavily on objects behaving the way that they
    do.)

    The question then becomes: Which is more programmer-friendly: classful
    or classless programming?

    The only practical limitation is that with classes, you can stuff all
    the shared attributes and method into a neat package. However, with
    classless, whenever you copy an object, you would have to implement
    the behavior of copying all of the available attributes and methods.
    How to share that data between multiple copied instances and the
    original in an efficient manner is non-trivial.
     
    Jonathan Gardner, May 7, 2004
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Michael
    Replies:
    2
    Views:
    280
    Stephen Horne
    Apr 1, 2004
  2. Joe Mason
    Replies:
    2
    Views:
    350
    Joe Mason
    Apr 1, 2004
  3. Jacek Generowicz
    Replies:
    4
    Views:
    289
    Jacek Generowicz
    Apr 2, 2004
  4. Mark Hahn
    Replies:
    41
    Views:
    916
    Paul Boddie
    May 27, 2004
  5. Mark Hahn
    Replies:
    20
    Views:
    593
    Mark Hahn
    Jul 13, 2004
Loading...

Share This Page