What is good about Prothon?

David MacQuigg dmq at gain.com
Tue Apr 27 10:56:11 EDT 2004


On Mon, 26 Apr 2004 12:36:51 -0700, "Mark Hahn" <mark at prothon.org>
wrote:
<snip>
>Ignoring the problem of  calling the ancestor's version of a method by just
>using the same old obj.func() will not work.  You don't have to use the
>current suggestion of obj$func() (we Prothonites may not use it either), but
>you cannot live in denial about the need for it.

I'll take this as a 
Question: How does the iterpreter know that Mammal.talk is an unbound
function and not a new binding to Mammal?

Answer: For reference, I have marked the line in question with !!!

proto Cat(Feline):
    numCats = 0
    __init__ :( n = "unknown", s = "Meow" ):
        Feline.__init__()
        Cat.numCats += 1
        .name  = n         # Set instance variables.
        .sound = s
    show :():              # Define a "static method".
        Feline.show()
        print "    Cats:", Cat.numCats
    talk :():
        print "My name is ...", .name
        print "I am a %s from %s" % (.genus, .home)
        Mammal.talk()      # Call an unbound function. <== <== !!!
        print __self__     ### Diagnostic check.
      
I am assuming the same implicit rule that Python follows.  Mammal is a
prototype (class).  When you access a function from a class in Python,
you get an unbound function.  When you access that same function from
an instance, you get a function bound to that instance.

>>> cat1 = Cat("Garfield","Meow")
>>> cat2 = Cat("Fluffy","Purr")

>>> bf = cat1.talk  # function Cat.talk bound to cat1
>>> bf
<bound function Cat.talk of <__main__.Cat object at 0x00A83D10>>
>>> bf()
My name is ... Garfield
I am a feline from Earth
Mammal sound:  Meow
<__main__.Cat object at 0x00A83D10>

>>> uf = Mammal.talk  # unbound function
>>> uf
<unbound function Mammal.talk>

In the rare situation where we need to explicitly change the current
instance:
>>> __self__ = cat2  
>>> uf()
Mammal sound:  Purr
>>> 

Python's syntax does violate the "Explicit" rule, but it seems in this
case the "Practicality" rule over-rides.  By making the function bound
or unbound, depending implicitly on the type of the object before the
dot, Python has avoided the need for an explicit binding syntax.

If we could come up with an explicit binding syntax that was not a
burden on either readability or clarity, then I would vote for a
change.  To summarize the current proposals:

Prothon:
$var    # var is attribute of self
^var    # var is an attribute of a proto of self
obj.func()    # func is an attribute of obj and bound to obj
obj$func()    # func is an attribute of obj and bound to current self
x = obj.func    # x is bound method of func attribute of obj and obj
x = obj$func     # x is bound method of func attribute of obj and self
x = obj.attr(func)    # x is unbound func

Python 3:
bf = cat1.talk # bound function
uf = Cat.talk  # unbound function
bf()  # call a bound function
uf()  # call unbound function with current __self__

__self__ = cat2  # change __self__  ... rarely needed
uf()  # call with cat2

The "Python 3" proposal follows current Python syntax except for the
use of a global __self__ variable instead of a special first argument.

-- Dave




More information about the Python-list mailing list