lexical closures and python

Alex Martelli aleax at aleax.it
Thu Sep 6 09:31:02 CEST 2001


"John Beppu" <beppu at binq.org> wrote in message
news:mailman.999755048.7248.python-list at python.org...
> Hi,
>
> My understanding is that Python does not support lexical closures.
> I've also heard that it should not be expected to appear any time
> in the near future.  Can anyone confirm or deny this?

Python 2.2, currently in alpha-2, has full support for closures
including lexically nested scopes; in Python 2.1, currently released
as 2.1.1, support is there, too, but needs to be explicitly enabled
by placing at the start of the module:
    from __future__ import nested_scopes

What you *can't* do in Python (just as you can't in FP languages
such as Haskell or ML dialects) is have a function *re-bind*
names in scopes it's nested in.  If you choose to say that this
means "no support for lexical closures", be sure to let the
functional programming guys know -- they'll surely be very
interested to hear that, having never suspected it before:-).

(Python is not as pure as Haskell &c in making data immutable
and names non-rebindable -- other names CAN be re-bound, and
Python supports many kinds of mutable data objects, which can
perfectly well be mutated even when their names cannot be
re-bound -- but that's another issue, and, it seems to me, not
connected to whether a language supports lexical closures).


> I'm asking about closures here, because I didn't want to misrepresent
> Python in my writing.  If lexical closures are on the horizon, I'd
> like to know about it.  If not, I guess I could mention that Python
> provides a lambda function, but it's not what a Schemer would expect
> it to be.  I'm trying to be correct, here.

I think the limitations of Python's lambda (which is not a function,
but a syntax special-form) may be worth mentioning, although they have
nothing to do with lexical closures: a Python lambda is limited to
an *expression*, and Python distinguishes between expressions and
statements, so the limitation is meaningful.  On the other hand, it's
again strictly an issue of having to bind a name: wherever you might
use a lambda special-form, you can instead choose to define a local
function and pass the function's name instead.

For example, you CANNOT, in Python, write:
    x=map(lambda y:
        global z
        z += y
        z, range(23))
because lambda can only wrap an expression and "global z" as well as
"z += y" are *statements* instead.  You can, however, perfectly well
write, to the same effect as that intended in the above invalid code:
    def cumulator(y):
        global z
        z += y
        return z
    x=map(cumulator, range(23))


Alex






More information about the Python-list mailing list