RE: Unification of Methods and Functions

Discussion in 'Python' started by Delaney, Timothy C (Timothy), May 11, 2004.

  1. Antoon Pardon wrote:

    > I'm a bit sick of this argument. There is a lot om implicity
    > going on in python. if obj belongs to cls then obj.method()
    > is syntactic sugar for cls.method(obj). That looks like
    > a big implicite way to handle things in python.


    Actually, they're not strictly the same. The instance knows which class
    it is an instance of - that's why the syntactic sugar can work.

    What you've stated is saying:

    class C:
    def f (self):
    pass

    c = C()

    then c.f() is identical to calling C.f(c)

    Now, in the above case that's correct. However, when subclasses get
    introduced that goes out the door.

    class D (C):
    def f (self):
    pass

    d = D()

    Now, d.f() is *not* identical to C.f(d). Instead it should be D.f(d).
    Without knowing the class that d is an instance of, it is not possible
    to call the correct method without the syntactic sugar.

    d.f() is closer to syntactic sugar for d.__class__.f(d). However, even
    that's not strictly correct, because c.f and d.f are bound methods -
    they know which instance they are bound to without any further reference
    to that instance.

    Yes - there is a lot hidden here - but what is hidden is purely
    implementation details.

    Tim Delaney
    Delaney, Timothy C (Timothy), May 11, 2004
    #1
    1. Advertising

  2. Op 2004-05-11, Delaney, Timothy C (Timothy) schreef <>:
    > Antoon Pardon wrote:
    >
    >> I'm a bit sick of this argument. There is a lot om implicity
    >> going on in python. if obj belongs to cls then obj.method()
    >> is syntactic sugar for cls.method(obj). That looks like
    >> a big implicite way to handle things in python.

    >
    > Actually, they're not strictly the same. The instance knows which class
    > it is an instance of - that's why the syntactic sugar can work.
    >
    > What you've stated is saying:
    >
    > class C:
    > def f (self):
    > pass
    >
    > c = C()
    >
    > then c.f() is identical to calling C.f(c)
    >
    > Now, in the above case that's correct. However, when subclasses get
    > introduced that goes out the door.
    >
    > class D (C):
    > def f (self):
    > pass
    >
    > d = D()
    >
    > Now, d.f() is *not* identical to C.f(d). Instead it should be D.f(d).
    > Without knowing the class that d is an instance of, it is not possible
    > to call the correct method without the syntactic sugar.


    I don't see how this contradicts what I want to say. In both case you have
    something of the form

    obj = cls()

    And in both obj.method() is equivallent to cls.method(obj)

    > d.f() is closer to syntactic sugar for d.__class__.f(d). However, even
    > that's not strictly correct, because c.f and d.f are bound methods -
    > they know which instance they are bound to without any further reference
    > to that instance.
    >
    > Yes - there is a lot hidden here - but what is hidden is purely
    > implementation details.


    That it is an implementation detail doesn't contradict that it
    is implicit.

    --
    Antoon Pardon
    Antoon Pardon, May 11, 2004
    #2
    1. Advertising

  3. On Tue, 11 May 2004 18:10:36 +1000, "Delaney, Timothy C (Timothy)"
    <> wrote:

    >Antoon Pardon wrote:
    >
    >> I'm a bit sick of this argument. There is a lot om implicity
    >> going on in python. if obj belongs to cls then obj.method()
    >> is syntactic sugar for cls.method(obj). That looks like
    >> a big implicite way to handle things in python.


    <snip examples>
    >Yes - there is a lot hidden here - but what is hidden is purely
    >implementation details.


    It should never bother the user, right?

    Pop Quiz:
    Which of the four outputs below is possible. Hints: Add a statement or
    two in front of these commands, then test your assumptions by running
    the sequence in your Python interpreter.

    >>> cat2 = cat1()
    >>> Cat.f = cat1.func
    >>> cat1.f = Cat.func
    >>> Cat.func, Cat.f, cat1.func, cat1.f

    A)
    (<unbound method Cat.func>, <function func at 0x00A89530>, <function
    func at 0x00A89530>, <unbound method Cat.func>)
    B)
    (<function meth at 0x00A89530>, <unbound method cat1.meth>, <bound
    method cat1.func of <__main__.cat1 instance at 0x00A5A5F8>>, <unbound
    method cat1.meth>)
    C)
    (<function meth at 0x00A89530>, <unbound method cat1.meth>, <unbound
    method cat1.meth>, <unbound method cat1.meth>)
    D)
    (<unbound method Cat.func>, <unbound method Cat.f>, <bound method
    cat1.func of <__main__.cat1 instance at 0x00A5A5F8>>, <bound method
    cat1.f of <__main__.cat1 instance at 0x00A5A5F8>>)

    In spite of all this, I still favor Python's implicit binding over the
    alternatives I have seen. To make binding really clear and explicit,
    you need to burden some very simple calls like cat1.method1() with
    extra syntax. So we pay a price on edge cases like the above, to make
    the normal use easy.

    Prothon is trying to make binding explicit, and they have a mess IMHO.
    This happens when you treat all possibilities as equally important,
    and don't exercise good judgement on what is overall the best
    compromise.

    -- Dave

    The one rule that trumps all others: Practicality beats purity.
    David MacQuigg, May 11, 2004
    #3
  4. Delaney, Timothy C (Timothy)

    Terry Reedy Guest

    "Antoon Pardon" <> wrote in message
    news:...
    > I don't see how this contradicts what I want to say. In both case you

    have
    > something of the form
    >
    > obj = cls()
    >
    > And in both obj.method() is equivallent to cls.method(obj)


    I believe Timothy's point was that inst.meth() is more general than any
    specific clas.meth(inst) whenever there is more than one possible meaning
    of 'clas'. In the following snippet, one can only replace 'animal.speak',
    without changing semantics, with 'animal.__class__.speak(animal)' and not
    with any specific versioon of clas.speak(animal). If something cannot be
    substituted without changing meaning, in a particular context, then, in
    that context, it literally does not mean the same thing.

    class mammal:
    def speak(self): print 'umf'

    class dog(mammal):
    def speak(self): print 'arf'

    class cat(mammal):
    def speak(self): print 'meow'

    for animal in [mammal(), dog(), cat()]: animal.speak()
    >>>

    umf
    arf
    meow
    >>>


    Terry J. Reedy
    Terry Reedy, May 11, 2004
    #4
  5. Delaney, Timothy C (Timothy)

    Greg Ewing Guest

    David MacQuigg wrote:
    > Prothon is trying to make binding explicit,


    That's not entirely true. Prothon currently has
    cat1.meth() doing binding just as implicitly as
    Python.

    What it doesn't do is bind implicitly when you're
    not going to call the method right away, which
    from a Python perspective is decidedly odd,
    not to mention rather inconsistent.

    --
    Greg Ewing, Computer Science Dept,
    University of Canterbury,
    Christchurch, New Zealand
    http://www.cosc.canterbury.ac.nz/~greg
    Greg Ewing, May 12, 2004
    #5
  6. Op 2004-05-11, Terry Reedy schreef <>:
    >
    > "Antoon Pardon" <> wrote in message
    > news:...
    >> I don't see how this contradicts what I want to say. In both case you

    > have
    >> something of the form
    >>
    >> obj = cls()
    >>
    >> And in both obj.method() is equivallent to cls.method(obj)

    >
    > I believe Timothy's point was that inst.meth() is more general than any
    > specific clas.meth(inst) whenever there is more than one possible meaning
    > of 'clas'. In the following snippet, one can only replace 'animal.speak',
    > without changing semantics, with 'animal.__class__.speak(animal)' and not
    > with any specific versioon of clas.speak(animal). If something cannot be
    > substituted without changing meaning, in a particular context, then, in
    > that context, it literally does not mean the same thing.


    Fine it is more general, it is like a curried function. IMO this is just
    a tangent that has litlle to do with my main point but if you really
    want to be accurate, I don't mind its just illustrates how much python
    is doing implicitly.

    > class mammal:
    > def speak(self): print 'umf'
    >
    > class dog(mammal):
    > def speak(self): print 'arf'
    >
    > class cat(mammal):
    > def speak(self): print 'meow'
    >
    > for animal in [mammal(), dog(), cat()]: animal.speak()
    >>>>

    > umf
    > arf
    > meow
    >>>>

    >
    > Terry J. Reedy


    def curry(f):

    def f1(*h):

    def fh(*t):

    return apply(f , h + t)

    return fh

    return f1


    class obj:
    pass


    def mammal():

    def speak(self): print 'umf'

    self = obj()
    self.speak = curry(speak)(self)
    return self


    def dog():

    def speak(self): print 'arf'

    self = obj()
    self.speak = curry(speak)(self)
    return self


    def cat():

    def speak(self): print 'meow'

    self = obj()
    self.speak = curry(speak)(self)
    return self


    for animal in [mammal(), dog(), cat()]: animal.speak()


    >>>

    umf
    arf
    meow
    >>>



    --
    Antoon Pardon
    Antoon Pardon, May 12, 2004
    #6
  7. On Wed, 12 May 2004 15:42:56 +1200, Greg Ewing
    <> wrote:

    >David MacQuigg wrote:
    >> Prothon is trying to make binding explicit,

    >
    >That's not entirely true. Prothon currently has
    >cat1.meth() doing binding just as implicitly as
    >Python.


    You are correct.

    >What it doesn't do is bind implicitly when you're
    >not going to call the method right away, which
    >from a Python perspective is decidedly odd,
    >not to mention rather inconsistent.


    Yes. The example I had in mind was

    cat1 = Cat() # instance of class Cat
    bound_func = cat1.func
    unbound_func = Cat.func

    Python's implicit rule, which Prothon is not following, is -- You get
    a bound function if you access it from an instance. You get the
    equivalent unbound function if you access it from the instance's
    class. I made my example deliberately perverse by not following
    Python's conventions on capitalizing class names, and by naming my
    function 'meth' and my method 'func'.

    As long as we follow the conventions, and we don't chose misleading
    names, I'm happy with the way Python handles binding, even thought it
    is "implicit". I would change my mind if it became apparent that many
    users were confused. In that case, a little extra typing to show an
    explicit binding would be justified.

    In my proposed syntax, the default bindings follow Python's current
    rules. If you ever need to *over-ride* those rules, you can do so by
    explicitly setting __self__. Except for code intended for
    diagnostics, or for introspection, I believe the user can safely
    ignore __self__.

    -- Dave
    David MacQuigg, May 12, 2004
    #7
    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. Rim
    Replies:
    3
    Views:
    288
    Moshe Zadka
    Jul 14, 2003
  2. Skip Montanaro
    Replies:
    2
    Views:
    295
    Paul Moore
    Aug 19, 2003
  3. David MacQuigg

    Unification of Methods and Functions

    David MacQuigg, Apr 30, 2004, in forum: Python
    Replies:
    133
    Views:
    1,949
    Duncan Booth
    Jun 1, 2004
  4. talin at acm dot org

    Fun with decorators and unification dispatch

    talin at acm dot org, Sep 11, 2005, in forum: Python
    Replies:
    3
    Views:
    281
    Talin
    Sep 11, 2005
  5. Charles Lowe

    Unification of variables and methods

    Charles Lowe, Feb 17, 2007, in forum: Ruby
    Replies:
    0
    Views:
    72
    Charles Lowe
    Feb 17, 2007
Loading...

Share This Page