abstraction, names, and lack thereof

Alex Martelli aleax at aleax.it
Sat Apr 6 04:43:16 EST 2002


Jarno J Virtanen wrote:
        ...
>> def specificSquirker(): self.squirkIt(23, 45)
>> Button(buttonsFrame, text='Squirk', command=specificSquirker)
>> 
>> It's generally not hard to come up with a name which helps readability.
>> I think un-lambdaing your code in this way is a good thing...
> 
> I agree.  Furthermore, I don't even think that un-lambdaing that way is
> about the maintainability issue per se (ie., 'the "functional" features
> make python code unreadable' [1]); 
        ...
> [1] Which I might or might not agree.

I wouldn't.  map, filter, list comprehensions (from Haskell), lazy
evaluation (aka iterators), are all examples of typical functional
programming features that make Python powerful and readable.

lambda, specifically, isn't, IMHO.


> it's just that abstracting everywhere
> is a good thing.  

I'd nuance that to ALMOST everywhere.  Sometimes you DO want to think
about the plumbing, so naked tuples or dicts can be more useful than
the various abstractions they could stand for.  Guido makes this point
in his essay on graphs, and a speaker at IPC10 made it about his use
of Python to teach a university course in algorithms and data structures.


But such cases ARE the exception, not the rule.  So,

try: abstraction is good
except WhenYouAreStudyingThePlumbingItself:
    (a, rare, case)

would seem to be the Pythonic approach to this.  A slightly expanded
version of your:

> [2] Unless writing a programming language compiler or interpreter.


> The highest level of logic at that point is not about
> lambdas, it's about "squirking" and that's what you should see in the
> source code.  Making routines and giving them names that represent the
> highest level of logic, which is not about the actual programming
> language code statements [2], is a very powerful tool (available in
> other languages too, of course :-).

The ABILITY to name things is almost always good -- if the "things"
are well-identified (and a function almost invariably is).  Insert
diatribe pro/con macros, hygienic or otherwise, to taste.

The REQUIREMENT to name things you'd rather leave unnamed could be
argued to be bad.  Naming gives identity and conceptual dignity to
something you might perhaps prefer to sweep more under the carpet.

When extracting a few things from a tuple I might code:

    fleep, gorp, __, __, swant, plosk, __ = subberTuplest(lark)

where the __ plays the role of an "anonymous name" (somewhat of
an oxymoron perhaps...:-).  Two underscores, not one, to avoid any
issues wrt interactive interpreter sessions or i18n via gettext,
is what I like to use here -- it also stands out just the right
amount (IMHO) as a place-holder.

Consider the alternatives when you do need to give names to items
0, 1, 4 and 5 of a 7-item tuple returned by a function call.  You
could bind the function call's result to a name -- but that would
"give identity and conceptual dignity" to what's probably a mere
artefact, a way for the function to "return several results" --
and would the resulting indexing over several statements be as
readable and clear as this unpacking?  Or you could build some
more elaborate special-purpose infrastructure, e.g.:

def indexedSelector(sequence, *indices):
    return [sequence[index] for index in indices]

fleep, gorp, swant, plosk = indexedSelector(
    subberTuplest(lark), 0, 1, 4, 5)

Worth it to avoid the "anonymous names"?  Maybe.  But it seems
to me that my preferred alternative remains more readable, in a
typical situation where those index numbers mean nothing special
to the human reader.  The visual "pattern matching" of the
original unpacking assignment seems to work pretty well.


I'd like to make "__ as anonymous name" a widespread convention
in Python, for such purposes as this one.  Should it ever catch
on, then, for those rare cases where you just can't abide naming
(giving identity and conceptual dignity) a small "throwaway"
function that you syntactically need, you COULD sensibly code:

def __(): self.squirkIt(23, 45)
Button(buttonsFrame, text='Squirk', command=__)

I wouldn't do it today, because readers would puzzle over the
unfamiliar usage (strangely enough, use of __ in unpacking
assignments doesn't seem to provoke similar puzzlement, even
today).  But language's pragmatics are molded by usage and
familiarity, so it's conceivable that such an idiom may become
acceptable one day.

It IS peculiar to go to such lengths to avoid naming a _function_.
Most often it's OK to give it identity and conceptual dignity.
Still, when exceptions to this DO arise...


> (There are other issues, but this abstraction thingy has been
> haunting me last couple of days and I had to let out the steam. ;-)

Just a couple of days?  This abstraction thingy (how best to
achieve it, where it gets in the way, and so on) haunts _me_
since at least a couple of decades...:-).


Alex




More information about the Python-list mailing list