After a couple of aborted attempts in the past, I’m learning Haskell in earnest now. I think it’s because I’m just tired of feeling stupid. I hang around programming.reddit.com quite a bit and Haskell is a big topic of conversation there. In fact, I can’t remember the last time I visited without reading some little bit of proselytizing or some effusive post about the productivity of the language. I’m not knocking that; I’m all for it actually. The thing is, I was tired of not really knowing what a monad was, or how to really go about programming anything substantial without side effects, and it was getting to me; so off I went in the stray moments around Christmas vacation with my old dog-eared copy of The Haskell School of Expression. And, like anyone who has been programming in a completely different paradigm for years, I started to try to make sense of what I was learning in terms of what I know.

For the most part, it’s been a good ride. It took me a little while to figure out that when a Haskeller declares an algebraic data type, the constructors are, in a sense, like the states of an object in an OO language. In the Haskell School of Expression, Paul Hudak uses a running example of a program manipulating shapes. He declares a Shape data type with constructors for Square, Rectangle, Circle, etc. All the while, he starts to declare functions which operate on values constructed via each of these constructors. In the back of my mind, of course, I was screaming what connects all of these things? In OO, you’d have common shared behavior but here you have to treat each construction separately. Eventually, when I started looking at recursive data types, it made more sense.

The other hurdle I’ve been getting over is the Haskell approach to naming. An example: there is a function in the standard prelude called foldr1. What that means, for the uninitiated, is: perform a list fold operation from the right to the left and use the last elements in the list as the basis of the fold. Now, I don’t know how to make a better name than that for what foldr1 does, but it’s hard not to feel bad about it. Names should really communicate. Yes, in C we had names like sscanf and fprintf but, when those names were settled, compilers and linkers only cared about so many characters, right?

From what I’ve seen so far, this approach to naming is pretty common in Haskell. In Simon Thompson’s book Haskell: The Craft of Functional Programming, he starts with an example that has two functions: flipV and flipH. They could’ve been named flipVertical and flipHorizontal, but it seems that the Haskell way is to use abbreviations and short identifiers. It’s great when you already know what the function names mean, but if you don’t you have to do a bit of hunting around to decipher code.

I’ve been thinking a bit about why Haskellers approach naming this way, and I have a couple of ideas. One is that Haskell came, essentially, from the computer science community. Most Haskell tutorials and books make more than passing mention that Haskell programs are easy to reason about and can serve as launching points for proofs of correctness. Haskell also looks a lot like math. List comprehensions look very much like set notation. If you have symbol y you can have distinct symbols named y’ and y’’. It’s cool and mathematical; you can almost hear the chalk on the chalkboard.

I think that culture does have a lot to do with Haskell’s naming conventions, and I’m sure that my own culture has a lot to do with my concern over them. Many OO practitioners go out of their way to make clear evocative names. When you write code that way, it reads like a story.

If I say account.deposit(2) in an OO program, or account.getBalance(), I’m stringing together nouns and verbs. Yes, it’s backwards, of course. In English we put verbs before the things that they operate on, so you’d think that in Haskell, things would be better. We could say getTail [1, 2, 3], for instance, to get the tail of a list, but the naming conventions don’t quite work that way. If you want the tail, you say tail [1, 2, 3]. In this case, the function is given a noun name; it’s named after its result.

I first saw this “name the function after its result” style of naming in a textbook about functional programming years ago. I forget which book it was. It’s nice, but it isn’t universal. There’s the case of foldr1 that I mentioned above. The foldr1 function’s name doesn’t tell you anything about the result, really; it tells you what operation is being performed, how it is being performed and what you should expect to give it as arguments. Again, I don’t see any way around this. And, I guess we could see the “fold” portion of foldr1 as a noun – (what do you get? You get the fold), but that feel like a rationalization.

The thing is, programs in Haskell appear to be fundamentally different from programs in traditional OO languages. Haskell seems to pull you into a mode where you are using language mechanisms: lists, pattern matching, and higher-order functions to express your solution, and when you do, you get to use powerful functions that operate on those abstractions. The only mechanism built into an OO language is method dispatch, and the bias is toward making up your own home-grown abstractions with noun-verb syntax. The foldr1 function is all about lists; it has nothing to do with your problem at all. Once could argue that it should really be an operator, something resigned to punctuation-character status, but that just sidesteps the issue. In Haskell, the fundamental parts of your program are lists, data types, and functions that operate on them. It appears that you can move Haskell programs closer to a DSL-like style, and in fact, Paul Hudak does that in a music example in School of Expression, but the code I’ve seen so far isn’t very DSL-ish.

I’ve gotten this feeling that perhaps cryptic naming is an integral part of the Haskell experience. Maybe, given Haskell's semantics, there just aren’t enough verbs to go around. What do I mean by that? Let’s consider foldr1 one more time. If we were trying to do something similar in OO we’d probably place the function on the List class, wouldn’t we? List could have a foldRight function and a foldLeft function. We could distinguish folds with starting values via overloading. There’s no real need to encode a distinction in the method name; no need for a “1”.

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. I wonder if it will ever look normal to me. And, if it does, will I be delighted or scared?