Some language proposals.

Michael Hudson mwh at python.net
Thu Feb 26 14:08:42 CET 2004


Jacek Generowicz <jacek.generowicz at cern.ch> writes:

> Michael Hudson <mwh at python.net> writes:
> 
> > Jacek Generowicz <jacek.generowicz at cern.ch> writes:
> > 
> > > Aaah, OK, _if_ you think that closures are _only_ a way of faking
> > > objects, _then_ claiming that Python is primarily OO does have a
> > > bearing on the use of closures. Forgive me for not pursuing
> > > this tangent any further.
> > 
> > OK, you really hadn't seen this argument before.  You must be new here
> > :-) (or at least, new to this particular dispute).
> 
> Yes, I usually switch off rather early in the "Python purity vs
> whatever" threads, 

Me too.  I wonder why we're both still in this one?

[...]
> > (trivially, you never *need* closures, just the same as you don't
> > *need* objects, there's a rather dull and unhelpful isomorphism
> > between the two concepts).
> 
> Yes, and we all know about Turing equivalence too. So we don't need
> Python at all.

Indeed.  Break out the infinitely long tapes.  But it does make "need"
a difficult word, is all.

> > > Sure. I have some stateful methods of classes (which I create
> > > dynamically and stick onto the class as the information about the
> > > existence of the method becomes available). By implementing them as
> > > closures I can just stick them on to the class. If I were to implement
> > > them as instances then I'd have to reimplement all the descriptors
> > > that take care of turning functions into bound or unbound methods.
> > 
> > Which isn't that hard...
> 
> It's not hard, but it's pointless, when there are ways of getting it
> for free.
> 
> > I think a code example might lend a bit more clarity.
> 
> What's unclear about it?  I get the impression that you understand
> exactly what the point is.

Well, now we're even on assuming too much about the other's
comprehension front :-)

> >>> class foo: pass
> ... 
> >>> class callable:
> ...     def __call__(self): print self
> ... 
> >>> instance = callable()
> >>> def meth(self): print self
> ... 
> >>> foo.meth = meth
> >>> foo.instance = instance
> >>> f = foo()
> >>> f
> <__main__.foo instance at 0x815fa64>
> >>> f.meth()
> <__main__.foo instance at 0x815fa64>  # self == f  
> >>> f.instance()
> <__main__.callable instance at 0x815f624>  # self != f
> >>> f.meth
> <bound method foo.meth of <__main__.foo instance at 0x815fa64>>
> >>> f.instance
> <__main__.callable instance at 0x815f624>  # Hmm, it's not a method
> >>> 
> 
> meth behaves like a Python method, instance does not.

Ah, ok.  To make it behave like a method, you need to make it a
descriptor, i.e. implement __get__ (and make everything in sight
new-style classes, of course).

> > > [At this point I'd love someone to step up and show me how to re-use
> > > the existing FunctionType descriptors in my own classes.]
> > 
> > Post some code, and I'll have a go.
> 
> Find some way of making callable [from above] use
> types.FunctionType.__get__.

I don't think I can do *that*:
import types

class foo(object):
    pass

class Callable(object):
    __get__ = types.FunctionType.__get__

foo.inst = Callable()

print foo.inst

yields:

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "/usr/tmp/python-10511jfs.py", line 11, in ?
    print foo.inst
TypeError: descriptor '__get__' requires a 'function' object but received a 'Callable'

but you can do something nearly equivalent:

import types

class foo(object):
    pass

class Callable(object):
    def __init__(self): # wonder why this is needed:
        self.__name__ = 'Callable'
    def __call__(self, ob):
        return ob
    def __get__(self, ob, cls=None):
        return types.UnboundMethodType(self, ob, cls)
    
foo.inst = Callable()

print foo.inst
print foo().inst()

(needs 2.3, for 2.2 use new.instancemethod instead).

> I don't see what code examples could possibly help in specifying the
> problem more clearly (unless the code is the solution, of course).
> 
> But please don't bother unless you really want to do it for your own
> entertainment. 

Well, I've signed up to give a talk on new-style classes at Python-UK,
so I'd hope not to have to work too hard for this :-)

[...]
> > > In short, whenever I want a _function_ which happens to have some
> > > internal state, I'd much rather use a closure than an instance of a
> > > class.
> > 
> > Maybe, once you've been assimilated into the Python Borg mindset, you
> > don't, actually.
> 
> Aaah, this thread is an attempt to assimilate me :-)  Now I understand.

Damn, you noticed.

> > There are sort of two extreme possibilities here:
> > 
> > 1) I am so blinded by the fact that I know Python as of 2.3 FAR better
> >    than any other language that I don't see how wonderful Python would
> >    be if "full closures" were added.
> > 
> > 2) Full closures just aren't that appropriate to Pythonic programming.
> > 
> > The truth, almost certainly, is somewhere in between these points.
> 
> An excellent summary, which, in my opinion says all that remains to be
> said in this thread.
> 
> And, with that, I take my leave. I bid you a good day, gentlemen.

And to you!

Cheers,
mwh

-- 
  It's actually a corruption of "starling".  They used to be carried.
  Since they weighed a full pound (hence the name), they had to be
  carried by two starlings in tandem, with a line between them.
                 -- Alan J Rosenthal explains "Pounds Sterling" on asr



More information about the Python-list mailing list