Ketil Malde wrote:
Also, good names are harder than they sound: I don't think
'belowLimit' is a good name for 'takeWhile (<10000)', for instance.
I certainly couldn't guess what it was for without looking at the
implementation, which kind of defeats the purpose of names for improving code clarity, don't you think?

I don't. I would not expect to understand the behavior of a piece of code just by reading its name.

However, a good name can help you understand the purpose of the code while reading it, and after reading the code, you may link the name to the same concept as the original author did. This way, the original author can help you rediscover his understanding of the problem by structuring the code accordingly.

But that means that names should not be introduced to break long expressions into short ones, but to point out structure. For example, the structure of the oddSquareSum example is a (.)-pipeline. We could highlight this fact by giving a name to each function in the pipeline.

  oddSquareSum
    = sum . belowLimit . onlyOdd . squareAll $ numbers
    where
      belowLimit = takeWhile (< 10000)
      onlyOdd = filter odd
      squareAll = map (^ 2)
      numbers = [1..]

However, in this version of the code, we obfuscate an important aspect of the structure of the pipeline: It is a pipeline working on lists. I would like to make this more visible, e.g. like this:

  oddSquareSum
    = sum . takeWhile belowLimit . filter odd . map square $ numbers
    where
      belowLimit x = x < 10000
      square x = x * x
      numbers = [1..]

In this version, we see the structure of the code in the pipeline, and the details in the local definitions. Furthermore, I would expect a reader to be able to remember the meaning of the names after having read the definitions.

  Tillmann
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to