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

Ron Adam ron3200 at gmail.com
Fri Oct 14 03:10:00 CEST 2011


On Fri, 2011-10-14 at 10:01 +1000, Nick Coghlan wrote:
> 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.

Yes, you are worrying too much about this. :-)

I like things that can be taken apart and put together again in a
program and by a program.  And even put together in new ways by a
program.

The special syntax and requirement that they be localized together
doesn't fit that.  Which means each time you want something similar to
it, but with maybe with a small variation, you must rewrite the whole
thing by hand.  (Yes, we saved a few keystrokes each time, but...)

To me that is going backwards and is a counter point to the purpose of
programming.  Hey lets keep those programmers working!  JK  ;-)



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

Decorators can be moved out of the way and reused multiple times.  I
don't think this syntax can do that.  It locks the two pieces together
so they can't be used separately.

Using your sort example.  Lets say we rewrite that concept so it's more
general using a decorator that can be reused.  In this case, the key
isn't the reusable part.  It's the part that changes when we do sorts,
so it's the part we put the decorator on to create a new sorted
variation.


def sorted_with(key):
    def _(seq):
        return sorted(seq, key=key)
    return _


@sorted_with
def key_sorted(item):
   return item.attr1, item.attr2

new_list = key_sorted(original_list)


We can reuse the sorted_with decorator with as may key functions as we
want.  That reuse is an important feature of decorators.

Cheers,
   Ron





More information about the Python-ideas mailing list