[Python-ideas] Statement local functions and classes (aka PEP 3150 is dead, say 'Hi!' to PEP 403)

Nick Coghlan ncoghlan at gmail.com
Fri Oct 14 02:01:58 CEST 2011


On Fri, Oct 14, 2011 at 7:01 AM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Withdrawing PEP 3150 altogether seems like an over-
> reaction to me. A lot of its problems would go away
> if the idea of trying to make the names local to the
> suite were dropped. That part doesn't seem particularly
> important to me -- we manage to live without the
> for-loop putting its variable into a local scope,
> even though it would be tidier if it did.

So, keep the PEP 3150 syntax, but don't make the inner suite special
aside from the out of order execution?

While that would work, it still feels overly heavy for what I consider
the primary use case of the construct:

    sorted_list = sorted(original, key=key_func) given:
        def key_func(item):
            return item.attr1, item.attr2

The heart of the problem is that the name 'key_func' is repeated
twice, encouraging short, cryptic throwaway names. Maybe I'm worrying
too much about that, though - it really is the out of order execution
that is needed in order to let the flow of the Python code match the
way the developer is thinking about their problem.

I'll note that the evolution from PEP 3150 (as shown above) to PEP 403
went as follows:

1. Make the inner suite a true anonymous function with the signature
on the header line after the 'given' clause. Reference the function
via '@' since it is otherwise inaccessible.

    sorted_list = sorted(original, key=@) given (item):
        return item.attr1, item.attr2

2. Huh, that 'given' keyword doesn't scream 'anonymous function'. How
about 'def' instead?

    sorted_list = sorted(original, key=@) def (item):
        return item.attr1, item.attr2

3. Huh, that looks almost exactly like decorator prefix syntax. And
the callable signature is way over on the RHS. What if we move it to
the next line?

    sorted_list = sorted(original, key=@)
    def (item):
        return item.attr1, item.attr2

4. We may as well let people add a name for debugging purposes, and
it's less work to just make it compulsory to match existing syntax. By
keeping the shorthand symbolic reference, we get the best of both
worlds: a descriptive name for debugging purposes, a short local name
for ease of use.

    sorted_list = sorted(original, key=@)
    def key_func(item):
        return item.attr1, item.attr2

5. Well, the parser won't like that and it's backwards incompatible
anyway. We need something to flag the prefix line as special. ':' will
do.

    :sorted_list = sorted(original, key=@)
    def key_func(item):
        return item.attr1, item.attr2

6. Keywords are better than symbols, so let's try that instead

    postdef sorted_list = sorted(original, key=def)
    def key_func(item):
        return item.attr1, item.attr2

PEP 403 really is just an extension of the principles behind
decorators at its heart, so I think it makes sense for those semantics
to have a decorator-style syntax. If we want to revert back to using
an indented suite, than I think it makes more sense to go all the way
back to PEP 3150 and discuss the relative importance of "out of order
execution" and "private scope to avoid namespace pollution".

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list