[Python-3000] Sky pie: a "var" keyword

Josiah Carlson jcarlson at uci.edu
Tue Oct 10 23:17:10 CEST 2006


"Mike Krell" <mbk.lists at gmail.com> wrote:
> 
> > there's no connection whatsoever between things that are raised now and
> > then in various forums, and things that are real "seriously hurts people
> > trying to get things done in Python" warts.
> 
> Fair enough.
> 
> > the vast majority of all Python programmers never uses nested functions
> > at all.
> 
> Yes, but part of the reason for this may be this very wart.  I know
> I'm campaigning for this as a fix for what the OP calls the "read only
> lexical scoping gotcha".  A fix for that makes it much more convienent
> to write closures that modify closed-over values, which in turn makes
> a much more compelling use case for using nested functions.

Every use that does not involve shadowing variables can be handled with
a list indexing variant.  Is it ugly and a bit slower?  Maybe.  But no
one who really wants to use nested functions is (in my opinion) hurt by
Python's lack of the equivalent of 'outer' or the variant 'my'.

That's one of the reasons I've been -1 for a while, but also because
nested functions can essentially be seen as shared namespaces, which can
also be implemented as methods on an instance, or even just attributes
off of a shared 'namespace' object.  The fact that a 'namespace object'
(not to be confused with local and lexical scopes) has slower access
times is an implementation detail that shouldn't concern users as much
as clarity and perhaps modularity, both of which can (and usually do)
become second-class citizens to speed.

For example, a user had been using the following type of thing in a
sudoku solver...

    def solve(...):
        state = set(...)
        def update_state(...):
            ...
            state ^= ...
            ...
        ...

Of course the ^= didn't work because state was a variable in a parent
scope.  The 'make it work' solution used:

    def solve(...):
        state = [set(...)]
        def update_state(...):
            ...
            state[0] ^= ...
            ...
        ...

Either way, the following would be more clear (at least in my opinion)...

    class namespace: pass

    def update_state(ns, ...):
        ...
        ns.state ^= ...
        ...

    def solve(...):
        ns = namespace()
        ns.state = set(...)
        ...

Why?  Because the shared namespace is explicit, both in the solve() and
update_state() definitions.  One could also then use the same
update_state() function anywhere else, thus increasing modularity and
potential for code reuse.  There is also the fact that it follows the
"flat is better than nested" zen, but the "explicit is better than
implicit" zen could be applied to either the explicit namespace, or even
the 'outer' or 'my' variants.


> In any event, as you pointed out yourself, at last check Guido is +1
> on this general idea.  Maybe you should ask him why he's in favor of
> it :-)

I'm only guessing here, but I would say it is because it removes a
(small) wart with regards to nested scopes, and it gets people to stop
complaining about this little thing (nevermind the functional
programming people who have been crying that Python ruins functional
programming for not having this included with the language).

 - Josiah



More information about the Python-3000 mailing list