Express What, not How.

David Mertz mertz at gnosis.cx
Tue Oct 14 23:49:40 EDT 2003


OK, I'm weak in Haskell too, as much as I like what I've played with.
But McNamara's mistake really gets to the point of names:

gt5163b at prism.gatech.edu (Brian McNamara!) wrote previously:
|   nat :: Parser Int
|   nat = do {c <- digit; return charToInt c}
|         `chainl1` (return \x y -> 10*x+y)
|If I understand you correctly, you would insist I write something like
|   nat :: Parser Int
|   nat = do {c <- digit; return charToInt c}
|         `chainl1` combineDigits
|            where combineDigits = return \x y -> 10*x+y

What you'd actually write in Haskell is:

   nat = do {c <- digit; return charToInt c}
         `chainl1` (return combineDigits)
          where combineDigits x y = 10*x+y

That is, you don't just move the lambda down a line, you get rid of it.
The name 'combineDigits' is perhaps more verbose than needed.  But
defining the function without any lambda form is generally easier to
read.

Moreover, a lot of times, functions really are useful in other contexts
(even contexts not yet anticipated).  In that case, use:

   combineDigits x y = 10*x+y
   nat = do {c <- digit; return charToInt c}
         `chainl1` (return combineDigits)

And you have an extra (silly) utility function available whenever you
want it.  The implementation of 'combineDigits' is entirely outside of
'nat', and we can focus on the name when we read the definition of
'nat'.

Of course, McNamara's other mistake is less absolute.  It's this:
Programmers spend about TEN TIMES as much time READING code as WRITING
it.  Even if looking through your library documentation to find the name
'combineDigits' is the one used is extra work, it's much less work for
other programmers to read your definition of 'nat' if it uses a
descriptive name.  (admittedly, for a silly and trivial function, the
difference is small; but I think the stipulation applies that
'combineDigits' is a proxy in the discussion for a more complex
real-world function).

|There are more functional abstractions than there are reasonable names.

I believe it is rather easy to construct a one-to-one mapping
(bijection) between functional abstractions and strings.  Both are
countably infinite, after all.

Yours, David...

--
mertz@  | The specter of free information is haunting the `Net!  All the
gnosis  | powers of IP- and crypto-tyranny have entered into an unholy
.cx     | alliance...ideas have nothing to lose but their chains.  Unite
        | against "intellectual property" and anti-privacy regimes!
-------------------------------------------------------------------------






More information about the Python-list mailing list