« The Derogatory Language of Types | Main | Injecting A Little Spring Into C++ »

January 24, 2007

Comments

forcing names is lame

Regarding the shorter names: I think the reasoning is that when considering whether to optimize for the first time you encounter a new function (which happens once), or the thousands of subsequent times that you type it out later, it is better to have a short name that pays off thousands of times rather than a long and descriptive name that pays off once when you've never seen it before (and has other drawbacks like making lines wrap more frequently and thus making the code harder to read).

Also, if you were new to functional programming, there is no name, no matter how long, that would make the function intuitive, since you wouldn't have encountered folds before. After you learn what a fold is, and that left and right describe two different orderings of operations, then foldl and foldr are very intuitive. Anybody who knows what a fold is will immediately know what they refer to. As to foldl1, you have to look it up, the first time. That doesn't seem like such a big deal. In Java, even with longer names and phenomenal IDEs, you still have to look at javadocs, and sometimes dig in to library code to figure out how something works or what it does.

Harald Korneliussen

Nope, I completely agree with you, Michael. The names are unnecesarily cryptic, and a short name doesn't save as much time as a descriptive name gives. To quote an Ada advocate: saving keystrokes is the job of the text editor, not the language. The names aren't even the same as in other functional languages, and they follow no consistent pattern. Show doesn't show anything, for instance, and scans don't scan anything - they are also called unfolds in scheme, which is slightly better on the naming business.

But haskell is just to cool to give up over such a small issue. As long as it doesn't turn out to be a symptom of a general careless attiude to readability, but I don't think it does.

emk

You wrote: "No, I don’t know whether it is the structure of the language or the culture, but there’s something which has pushed the community toward abbreviations and encoded names."

Well, short names are usually a sign of a "core" concept--something that you're expected to take for granted. For example, C programmers write "if (x) y else z;" instead of the more descriptive "if_the_value (x) is_true_then_do y else_do z." The second tells a better story, but it gets old fast. Or consider the C expression "a || b", which would read something like "evaluate (a) and_return_the_result_if_true otherwise_evaluate (b) and_return_that". Again, the cryptic abbreviation is a bit nicer, because it's a core concept.

Now, I'm going to claim something strange: "foldr" is as fundamental in Haskell as "if" statements are in C.

Sound strange? Go look at the source code for Prelude.List:

http://www.haskell.org/onlinereport/standard-prelude.html

Almost every function that manipulates lists is based on foldr or foldl!

So if you want to grok Haskell, you should try to figure out what's so fundamental about "fold", and how it relates to recursion. (See "Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire" for a detailed discussion. And consider the fact that both halves of Google's "MapReduce" architecture are folds!)

At this point, the observant Haskell newbie might say, "Well, I guess that could explain foldr. But half the Haskell libraries out there are also filled with short, cryptic names! Look at 'em: monads, arrows, etc., etc. Can all these things really be fundamental?"

And, terrifyingly enough, the answer is yes: The fundamental operations on monads are "map", "unit", and "join," and each of these is a fundamental as "if" or "||" in C. The fundamentals of arrows include such operators as "&&&" and "|||", and again, these are essential basics.

So that's life in Haskell: First, you'll need to learn a new set of fundamentals. And then, on a regular basis, some library author will try to pry your brain open and dump in even _more_ "fundamental" ideas.

This implies two things: (1) Haskell will teach you a staggering number of fascinating things, and (2) advanced Haskell code is basically impenetrable until you've mastered the underlying mathematical concepts it uses.

It can be a mixed blessing at times, I admit. :-)

Jules

You're thinking too procedurally ;-).

It's tail and not getTail because

> tail the_list

*is* the tail of the list, it doesn't get the tail of the list.

> tail [1,2,3]

and

> [2,3]

are exactly equivalent.

All functions in Haskell are get-functions: getFoldr, getMap, getProduct...so why would you want to put get in front of them?

scruzia

Re: short names: IMHO, it's not so much the CompSci as the Mathematics influences that led to the use of short names in FP in general, and in Haskell in particular.

Re: folds: Graham Hutton wrote a good paper that helps show the importance of folds in FP: "A tutorial on the universality and expressiveness of fold"

http://www.cs.nott.ac.uk/~gmh/bib.html#fold

Chris Rathman

The terminology of fold is not particularly unique to Haskell. In other languages, it is sometimes referred to as "Accumulate", "Reduce" or "Collect". Or you can use the actual technical term of Catamorphism.

Isaac Gouy

Michael Feathers wrote "If I say account.deposit(2) in an OO program, or account.getBalance() ... tail [1, 2, 3]. In this case, the function is given a noun name; it’s named after its result."

In a /Java/ program we might say
account.getBalance()

In a Smalltalk program we would say
account balance

Do you find it strange that Java Vector has methods named
firstElement()
lastElement()

Here's a snippet from an old Smalltalk style guide
- Use imperative verbs and phrases for methods which perform an action
- Use common nouns for methods which answer a specific object

Greg Buchholz

Fold *is* a verb. You fold your data structures up like a piece of paper. You start using a lot of folds/unfolds and you get origami programming. As for "head" and "tail" they look more like adjectives to me. Don't think of it as a verb drought, think of it as adding some of the other parts of speech.

mgsloan

I also think that part of it is the expression-form of the language itself.

Haskell expressions tend to bulk up width wise more than imperative languages. Perhaps the short names are partly due to attempting to keep these lengths manageable. Yes, I know that you can split lines, but sometimes it is unideal.

Bill Tozier

One is surprised that the "linguistic" affectations of APL didn't come up in the course of the conversation. Yet. Not sure whether I invoke it as a "could be worse" and "when I was a kid" kindof thing, or as a partial explanation of Haskell's parsimonious sensibility. I do honestly wonder if there's a relation in the latter case; surely the people behind Haskell learned functional programming in APL (like my wife and I did) way back when in the dark ages....

The comments to this entry are closed.