Hacker News new | ask | show | jobs
by thedufer 2506 days ago
Unfortunately, a lot of work there is done by the Haskell community having utterly absurd standards for those things. I work in a different functional programming language, and you would not believe the amount of time I spend convincing new hires with Haskell backgrounds to spend the extra few characters to expand out the unreadable point-free/single-character-names style that Haskell folks prefer.
2 comments

Has it ever occurred to you that Haskell programmers prefer single-letter variable names in some contexts because it makes the code better? Perhaps it is not the children who are wrong.
Right, I find pointfree style to be much more readable than pointful, I expect the GP would too if they became used to it
The problem is you can’t bring that change about in a corporate setting by just doing things your own way and hoping your coworkers catch up. I think that’s more what GGP was having issue with.
IME, this isn't consistent. If you can write it as `f . g . h` then point-free will probably be clearest. If you need to use each argument in a few places, I find going all the way to point-free is usually much less clear than some intermediate points or even the fully pointful version.
I have spent quite a bit of time in both styles, and there's a pretty clear winner in my experience. I don't work in Haskell, but in another statically-typed FP language - maybe type classes are the feature that flip everything we know about readability from other languages?
No, the problem is giving names that are too specific to things. Like if you're implementing a merge sort for some reason, and go to write merge:

    merge :: Ord a => [a] -> [a] -> [a]
    merge (x:xs) (y:ys) | x <= y = x : merge xs (y:ys)
                        | otherwise = y : merge (x:xs) ys
    merge [] xs = xs
    merge xs [] = xs
Those are the ideal variable names. Clarity is only hurt by making the names "descriptive" by naming the type variable elementOfListsToMerge or the parameters things like theHeadOfTheFirstList and so on. It's useless precision, like using 100 digits of pi to calculate volume of a... pie. You pay the cost every time you use it, while it adds no additional knowledge.

This is what I mean - there are a lot of cases when writing Haskell code that you write generic polymorphic combinators. Using long variable names is negative utility. Haskell programmers know this, and so they don't use long names when short ones convey identical information in a more readable manner.

This is where most other languages fall down, and why most programmers don't understand the concept. It's common in Haskell to write code that applies to so many different situations that any "descriptive" name you give to a local variable is just plain incorrect in many use cases.

In the other direction though, Haskell programmers also appreciate the value of a well-chosen name when one applies. Note that the function being discussed elsewhere in this thread isn't polymorphic. It has descriptive local variable names. No one suggested renaming them x or a.

In other words, choose names well, not according to dogma that says short is bad.

I think this is kinda my point. Haskell folks like to show unrealistically small code samples that don't even do the small thing they claim, where one-letter names are kinda defensible, and then you realize that that's how they name everything.

Since you like sorts, have you seen a Haskell implementation of quicksort that spells out the word "pivot"? This seems like a small ask. Surely someone has done it. Before typing this, I assumed it couldn't possibly be as bad as I remembered and that I was falling prey to confirmation bias, but in fact 9 out of the top 9 results (one is a dead link, which is why there aren't 10) for "haskell quicksort" on Google use a single-character variable name for it (n, p, or x). As a side note, 7 out of 9 of them exhibit neither the time nor space complexity promised by quicksort. (I admit that two of them appeared to be the same code - call it 8/8 and 6/8, respectively, if that seems unfair.)

Finally, one of the two that does attempt to perform it in place (which is far more complicated) contains variables named lb, ub, mub, ma, and, my favorite, iLTj. Good luck figuring out how that code works. This is the thing I'm talking about, and it is not an isolated example.

I like Haskell as a language! It has a lot of cool ideas. But people who learn it are often made into much worse programmers for having been exposed to it, and it is because of stuff like this. It's some weird community standards problem.

> and, my favorite, iLTj

"i less than j". Not hard to guess if you know about "LT" in the standard library.

By the comment, the GP is not a Haskell developer and those people are not programming in Haskell.

So, even though it is well known that short named variables and point free syntax often improve the readability of Haskell code, it probably does not improve the readability of his code.

I work in a statically-typed FP language. Unless type classes are the magic feature that make point-free viable, it's hard to see how that could be the difference.
Oh believe me, I’d believe.

My Haskell background comes from building upon academic proofs of concept during a stint at CSAIL. Never again.

That world has very little to do with commerical Haskell though, now does it? Why, we even discourage the use of Singletons and if you import a unification library everyone will immediately demand to know why.