Some language proposals.

Jacek Generowicz jacek.generowicz at cern.ch
Thu Feb 26 09:28:01 CET 2004


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, and the "The current state of Python is programming
language Nirvana" threads. You see, I use Python because it lets me
gets certain jobs done easily and enjoyably, and don't really much
care for language patriotism. I will fiercely defend Python on its
merits (which are legion), but that does not preclude me from
sometimes noting that it would be handy if something were different
than it is right now.

My contribution to this thread started with a question: I paraphrase
"why are Python closures read only?". Paul gave me an answer which has
some merit and I am satisfied with that answer. Frankly, I have no
time for, or interest in discussing how often I should on should not be
using closures in Python. When they are convenient for me, I will use
them, and when callable instances are more convenient, I will use
those, regardless of what you and Paul might say, so there,
na-na-na-naaa-naaah !

> (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.

> > 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.

>>> 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.

> > [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 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. My not having found a way to do it, is in no way
stopping me from achieving my goals. (Which is more than can be said
for contributing to this thread :-) There being perfectly viable
alternatives to doing it, means that I haven't invested much time in
finding an answer, so it may well be that there is as simple solution.

> > Another example. I make quite heavy use of a trivial memoizer. The
> > closure verison is much shorter, clearer and faster.
> 
> I'll grant you this: I've done the same.

That's my point. Closures are there, sometimes they are more
appropriate than instances, so use them. No point in discussing the
merits and demerits of the two alternatives and pontificating on what
is Pythonic or not.

> > (I want it to be writeable because I sometimes want to 'prime' the
> > cache, or do other things to it ... so I'm giving myself access to
> > the cache by binding the cache as a function attribute of the
> > closure, before returning it from the memoizer)
> 
> Um, here, unless I misunderstand you, you don't want to mutate the
> closed over binding (which is what Python currently doesn't let you
> do) but mutate the object the closed over binding is bound to.  In
> this respect, Python is no different from anything else, you need to
> arrange some way to expose said object outside the closure.
> 
> What am I missing?

Nothing. It was an inappropriate example.

> > 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.

> 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.



More information about the Python-list mailing list