Express What, not How.

Raffael Cavallaro raffaelcavallaro at junk.mail.me.not.mac.com
Tue Oct 14 20:41:28 EDT 2003


In article <pan.2003.10.14.23.19.11.733879 at knm.org.pl>,
 Marcin 'Qrczak' Kowalczyk <qrczak at knm.org.pl> wrote:


> Sometimes a function is so simple that its body is more clear than any
> name. A name is an extra level of indirection. You must follow it to be
> 100% sure what the function means, or to understand what does it really
> mean that it does what it's named after.

Your argument is based on the assumption that whenever people express 
_what_ a function does, they do so badly, with an inappropriate name.

We should choose our mode of expression based on how things work when 
used correctly, not based on what might happen when used foolishly. We 
don't write novels based on how they might be misread by the 
semi-litterate.

Anonymous functions add no clarity except to our understaning of 
_implementation_, i.e., _how_ not _what_. Higher level abstractions 
should express _what_. Implementation details should remain separate, 
both for clarity of exposition, and for maintanence and change of 
implementation.

> The code also gets longer 

No, it gets shorter, because you don't repeat your use of the same 
abstraction over and over. You define it once, then reference it by name 
everywhere you use it.

> - not
> only more verbose but the structure of the code gets more complex with
> more interdependent parts.

No, there are _fewer_ interdependent parts, because the parts that 
correspond to the anonymous function bodies are _completely gone_ from 
the main exposition of what is happening. These formerly anonymous 
function bodies are now elswhere, where they will only be consulted when 
it is necessary to modify them.

You seem to take the view that client code can't trust the interfaces it 
uses, that you have to see how things are implemented to make sure they 
do what they represent to do.

This is a very counterproductive attitude. Code should provide high 
level abstractions, and clients of this code should be able to tell what 
it does just by looking at the interface, and maybe a line of 
documentation. It shouldn't be necessary to understand the internals of 
code one uses just to use it. And it certainly isn't necessary to 
include the internals of code one uses where one is using it (i.e., 
anonymous functions). That's what named functions and macros are for. 
Inlining should be done by compilers, not programmers.

Anonymous functions are a form of unnecessary information overload. If I 
don't need to see how something works right here, in this particular 
context, then don't put its implementation here. Just refer to it by 
name.

> When you have lots of short functions, it's
> harder to find them. There are many names to invent for the writer and
> many names to rememner for a reader.

Which is why names should be descriptive. Then, there's little to 
remember. I don't need to remember what add-offset does, nor look up 
it's definition, to understand its use in some client code. Anonymous 
functions are sometimes used as a crutch by those who can't be bothered 
to take the time to attend to the social and communicative aspects of 
programming. Ditto for overly long function bodies. How to express 
intent to human readers is just as important as getting the compiler to 
do what you want. These same programmers seem enamored of 
crack-smokingly short and cryptic identifier and function names, as if 
typing 10 characters instead of 3 is the real bottleneck in modern 
software development. (Don't these people know how to touch type?)



> Function headers are administrative
> stuff, it's harder to find real code among abstractions being introduced
> and used.


Seemingly to you, the only "real code" is low level implementation. In 
any non-trivial software, however, the "real code" is the interplay of 
high level abstractions. At each level, we craft a _what_ from some less 
abstract _how_, and the _what_ we have just defined, is, in turn used as 
part of the _how_ for an even higher level of abstraction or 
functionality.


> Why do you insist on naming *functions*? You could equally well say that
> every list should be named, so you would see its purpose rather than its
> contents.

I think this concept is called variable bindings ;^)


> Perhaps every number should be named, so you can see what it
> represents rather than its value.

Actually, they are _already_ named. The numerals we use _are_ names, not 
numbers themselves. I'm surprised you aren't advocating the use of 
Church Numerals for all numerical calculation.

> You could say that each statement of
> a compound statement should be moved to a separate function, so you can
> see what it does by its name, not how it does it by its contents. It's
> all equally absurd.

In the Smalltalk community the rule of thumb is that if a method body 
gets to be more than a few lines, you've failed to break it down into 
smaller abstractions (i.e., methods).

> A program should balance named and unnamed objects. Both are useful,
> there is a continuum between cases where one or the other is more clear
> and it's subjective in border cases, but there is place for unnamed
> functions - they are not that special. Most high level languages have
> anonymous functions for a reason.

Yes, but they should live inside the bodies of named functions. Not lie 
exposed in the middle of higher level abstractions. Please also see my 
reply to Joe Marshall/Prunesquallor a few posts up in this thread.




More information about the Python-list mailing list