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