[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 07:55:50 CEST 2011


On Fri, 2011-10-14 at 13:20 +1000, Nick Coghlan wrote:
> On Fri, Oct 14, 2011 at 11:10 AM, Ron Adam <ron3200 at gmail.com> wrote:
> > 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)
> 
> Seriously? You're suggesting that mess of symbols and indentation as a
> good answer to the programming task "I want to sort the items in this
> sequence according to the values of attr1 and attr2"?

It's just a simple example of how you could do this.  I'd probably just
use a lmabda expression myself.

I think the concept you are looking for is, how can you express a
dependency in a natural order that also reads well.  In this case, the
end result cannot be built until all the parts are present.

Class's are constructed top down.  You create the framework and then
fill in the parts.  Functions (including decorators) are constructed
from the inside out.  That isn't always the easiest way to think about a
problem.

So a second separate goal is to have very concise one time expressions
or statements.


> Both of those work, but neither of them reaches the bar of "executable
> pseudocode" the language prides itself on.
> 
> PEP 403 also fails pretty abysmally (alas) on that front:
> 
>     postdef sorted_list = sorted(original, key=sort_key)
>     def sort_key(item):
>         return item.attr1, item.attr2
> 
> The named function version fails because it gets things out of order:

Right and also, the 'postdef" keyword looks like it should result in a
defined function, but it's actually a call here.  Thats probably because
I'm so used to seeing the 'def' in that way.


>     def sort_key(item):
>         return item.attr1, item.attr2
> 
>     sorted_list = sorted(original, key=sort_key)
> 
> That's more like pseudo code for "First, define a function that
> returns an object's attr1 and attr2 values. Than use that function to
> sort our list", a far cry from the originally requested operation.

I think "far cry" is over stating it a bit.  I think this sort of issue
is only a problem for very new programmers.  Once they understand
functions and how to used them together to make more complex things,
they get used to this.


> PEP 3150, on the other hand, actually gets close to achieving the
> pseudocode standard:
> 
>     sorted_list = sorted(original, key=sort_key) given:
>         def sort_key(item):
>             return item.attr1, item.attr2
> 
> "Sort the items in this sequence according to the supplied key
> function. The key function returns the values of attr1 and attr2 for
> each item."

Right, we are constructing the framework first, and then the sub parts.

But more specifically, we are suspending a piece of code, until it is
safe to unsuspend it.  I suppose you could use the '$' in some way to
indicate a suspended bit of code.  An 'S' with a line through it does
map well to 'suspended'.


> > We can reuse the sorted_with decorator with as may key functions as we
> > want.  That reuse is an important feature of decorators.
> 
> No, no, no - this focus on reusability is *exactly* the problem. It's
> why callback programming in Python sucks - we force people to treat
> one-shot functions as if they were reusable ones, *even when those
> functions aren't going to be reused in any other statement*.

We have to use functions in call backs because an expression executes
immediately rather than when it's needed.  Also a call back usually
needs some sort of input at the time it's used which isn't available
before hand.

Because python's functions are objects, it makes it much easier to do,
So it's not really that bad once you figure it out.  Non objective
languages are more difficult in this respect.


> You don't *care* about reusability in those cases -
> you care about handing the code you're currently writing over to be
> executed by some other piece of code

I think that is 'reusable'. And most likely it will be reused over and
over if we are referring to a GUI.

Some call back examples might be good. 


Cheers,
   Ron





More information about the Python-ideas mailing list