nameless code blocks (was RE: What does Python fix?)

James_Althoff at i2.com James_Althoff at i2.com
Fri Jan 25 15:08:45 EST 2002


[Tim Peters]
>... nameless code blocks are easier to reuse if they're named <wink>.

[David Eppstein]
>Ok, you've convinced me that expanding lambda into unnamed code-blocks
>is unnecessary, and confirmed Tim's point that naming the code blocks can
>be better than lambdas for readability.

[Tim Peters]
>I was just pulling James Althoff's leg -- he expected it ...

Yes, I did -- guilty as charged. ;-)

[Tim Peters]
>Still, this is just another variant of "the eff-bot's favourite lambda
>refactoring rule" (from a post by Fredrik Lundh):
>
>    1) write a lambda function
>    2) write a comment explaining what the heck that lambda does
>    3) study the comment for a while, and think of a name that captures
>       the essence of the comment
>    4) convert the lambda to a def statement, using that name
>    5) remove the comment
>
>lambdas didn't really add anything to Python, except to give ex-Schemers
>false hope <wink>.

Perhaps surprisingly, I actually agree with all of the above, except but
however ...

It's not really the requirement of a name that is the issue for me (even
though I did say "nameless code blocks").  In fact, I often have a hard
time understanding elegantly convoluted lambdas and appreciate seeing such
things broken into more prosaic, nicely-named, reusable, and understandable
chunks as advised above.

I'm actually interested in one particular case, though: namely, the
situation where you want to wrap a piece of code with some encapsulated
"before/after" stuff.

For (a GUI-ish) example:
(assuming nested scopes)

application.showStatusDuring(message='Doing search ...',lambda:
    queryForm.validate()
    doSomethingSpecial()
    resultsView.doQuery(queryForm))

As pointed out by Tim (and others in prior posts) one can handle this
easily in Python with something like:

def validateAndDoQuery():
    queryForm.validate()
    doSomethingSpecial()
    resultsView.doQuery(queryForm)

application.showStatusDuring(message='Doing search ...',validateAndQuery)

(And doing so does make validateAndDoQuery reusable <wink>).  But however
nonetheless ...

I don't see this idiom used much in my neck of the woods (YMMV).  Instead,
9 times out of 10, I will see something more like:

savedMessage = application.getCurrentMessage()
application.showStatus('Doing search ...')
try:
    queryForm.validate()
    doSomethingSpecial()
    resultsView.doQuery(queryForm)
finally:
    application.showStatus(savedMessage) # be sure to restore prior message

To me the former approach -- the one with the imagined "nameless code
block" -- shows the intent more clearly than the latter "try/finally"
approach (although this might be just stylistic preference / brain-twist on
my part).  But more importantly, the former encapsulates and hides the
details of the implementation of the save/restore bit and *promotes* reuse
of *those* lower-level details.  The latter exposes those details and
forces the programmer to re-implement them over and over.  Note that in
this case (its *my* example, after all <wink>), the save/restore stuff is
deemed to be more important for reuse than the validate/doQuery bit.

I think that there are two reasons why the latter approach is often seen
rather than the former.  Having to pick a name for a very small amount of
"use-once" functionality is to me the minor issue.  I'm guessing that the
bigger factor is the need to define the block *ahead* of its use rather
than defining it "in place".  This small amount of extra baggage seems to
be enough to discourage use of the former -- and in my view better --
idiom.

Not-a-disappointed-Schemer-though <wink>,

Jim






More information about the Python-list mailing list