Re: Higher-order functions in Python?

Steven D. Majewski (sdm7g@virginia.edu)
Tue, 27 Sep 1994 11:47:12 -0400 (EDT)

On Mon, 26 Sep 1994, Chet Murthy wrote:

> I've been rooting around in Python, and it doesn't seem to me that
> Python supports a notion of closures -- for implementing higher-order
> functions.
>
> While I'm not one of those lambda-calculus nuts, I do like using
> closure every now and then. If the answer to this request is "use
> objects", I'll be happy to do so. But I was wondering if this was a
> purposeful omission or not.
>

Guido says "use objects", and I don't disagree.

However, I'll point out that Python's functions really are composite
objects that contain code and bindings and other attributes, so they
are more like scheme closures than they are like scheme functions.
Python code-objects are a better analogue to scheme functions.

However, in Python, all this is mechanism that you're really not
suposed to see ( or even, perhaps, depend on in future implementations )

>>> def f( x ):
... return x + a + 1
...
>>> f.__members__
['func_argcount', 'func_argdefs', 'func_code', 'func_globals', 'func_name']
>>> f.func_code
<code object f at 20068bc8, file "<stdin>", line 1>
>>> f.func_code.__members__
['co_code', 'co_consts', 'co_filename', 'co_name', 'co_names']
>>>

f.func_globals has the outer scope or global bindings - either the
module the function was defined in, or the __main__ module for
functions defined interactively at the top level.

These attributes of function objects and code objects are read only
objects, so you can't modify the bindings. But, with the
routines in newmodule.c, you can create a new object, taking the
code object from a previously defined function, and a new dictionary
of bindings.

But, you shouldn't normally have to do this sort of thing.

"Objects are the poor man's closures" ( or did that phrase go the
*other* way around? ) - and they are the "cleaner" way in Python. I
have had exactly 3 occasions to use this facility: two were Python
"research" projects, and the other was rendered unnecessary when Guido
added default values to lambda. I expect to use it again, but not for
"typical" python code. ( The same *doesn't* go for new.module, which is
much cleaner that importing an empty module and playing with it's
dictionary, and is used in ImportModule, and is needed for an
import-via-url, as noted in another thread. )

-- Steve Majewski (804-982-0831) <sdm7g@Virginia.EDU> --
-- UVA Department of Molecular Physiology and Biological Physics --
-- Box 449 Health Science Center Charlottesville,VA 22908 --
[ "Cheese is more macho?" ]