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

Nick Coghlan ncoghlan at gmail.com
Mon Oct 17 14:35:39 CEST 2011


On Mon, Oct 17, 2011 at 5:53 PM, Raymond Hettinger
<raymond.hettinger at gmail.com> wrote:
>
> On Oct 16, 2011, at 12:16 AM, Nick Coghlan wrote:
>
> The current draft of PEP 3150 is available on python.org:
> http://www.python.org/dev/peps/pep-3150/
>
> FWIW, I think the word "declarative" is being misused.
> In the context of programming languages, "declarative"
> is usually contrasted to "imperative" -- describing
> what you want done versus specifying how to do it.
> http://en.wikipedia.org/wiki/Declarative_programming
> I think what you probably meant to describe was something
> akin to top-down programming
> http://en.wikipedia.org/wiki/Top%E2%80%93down_and_bottom%E2%80%93up_design#Top.E2.80.93down_approach
> using forward declarations:
>  http://en.wikipedia.org/wiki/Forward_declaration .

Agreed, top-down vs bottom-up would be better terminology than
declarative vs imperative (although I *do* believe having the given
statement available would make it easier to write declarative APIs in
Python without abusing decorators or needing to delve into metaclass
programming).

> Looking at the substance of the proposal, I'm concerned that style gets in
> the way of fluid code development.
> Using the PEPs example as a starting point:
>
> sorted_data = sorted(data, key=sort_key) given:
>     def sort_key(item):
>         return item.attr1, item.attr2
>
> What if I then wanted to use itertools.groupby with the same key function?
> I would first have to undo the given-clause.
> AFAICT, anything in the given statement block becomes hard to re-use
> or to apply to more than one statement.  My guess is that code written
> using "given" would frequently have to be undone to allow code re-use.

Agreed, but is that really so different from lifting *any* inline code
out into a separate function for later reuse?

Consider that the standard recommendation for "multi-line lambdas" is
to define a function immediately before the statement where you want
to use it. If that statement is in module level code, fine, that
function is now available for reuse elsewhere (perhaps more places
than you really want, since it is now potentially part of the module
namespace). But in a class scope it's almost certainly more exposed
than you want (unless you delete it after use) and in a function scope
it isn't exposed any more than it would be in a given statement, and
will need to be moved before you can reuse it in a different function.

There's a reason the PEP's suggested additions to PEP 8 mention the
idea that given statements are a stepping stone towards splitting an
operation out into its own function - it's a discrete calculation or
other operation, so it could be separated out, but you don't actually
want to reuse it anywhere else (or can't come up with a good name), so
it makes more sense to leave the code in its current location.

It's definitely a concern (and is one of the reasons why I think this
PEP needs to bake for a *long* time before it can be considered
remotely justifiable), but I still think allowing people to express
top down thought processes clearly, and have the code be able to
execute in that form is potentially valuable, even if other software
engineering concerns soon result in the code being restructured when
it comes to application programs.

> Also, it looks like there is a typo in the attrgetter example (the "v." is
> wrong).
> It should read:
>    sorted_list = sorted(original, key=attrgetter('attr1', 'attr2')

Oops, you're right - I'll fix that in the next update.

> When used with real field names, that is perfectly readable:
>    sorted(employees, key=attrgetter('lastname', 'firstname')
> That isn't much harder on the eyes than:
>    SELECT * FROM employees ORDER BY lastname, firstname;

Again, agreed, but I don't think SQL rises to the bar of executable
pseudocode either ;)

I've actually been trying to think of an example where you'd want to
be normalising data on the fly, catching exceptions as you go along,
so that lambda expressions and the operator module can't help, with
bottom-up programming being the only alternative to the PEP's direct
reflection of a top-down thought process. No luck on that front so
far, though.

Cheers,
Nick.

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



More information about the Python-ideas mailing list