Alphabet Soup: Haskell’s Single-Letter Naming Quirks

A stylized image of Haskell code from the article

When you used punch cards or tape to write a computer program, brief variable names were the norm. Your compiler or assembler probably only allowed six letters, anyway. But times change, and people who, by habit, give array indices variable names like I, J, or K get a lot of grief. But [Jack Kelly] points out that for highly polymorphic languages like Haskell, you often don’t know what that variable represents anyway. So how are you supposed to name it? He provides a guide to one-letter variable names commonly used by Haskell developers and, sometimes, others.

Haskell’s conventions are particularly interesting, especially with i, j, and k, which are borrowed from mathematical tradition to signify indices or integers and passed on via Fortran. The article also highlights how m often refers to Monads and Monoidal values, while t can represent both traversables and text values. Perhaps more obscurely, p can denote profunctors and predicates, giving a glimpse into Haskell’s complex yet efficient type system. These naming conventions are not formal standards but have evolved into a grass-roots lexicon.

Of course, you can go too far. We see a lot of interesting and strange things written in Haskell, including this OpenSCAD competitor.

14 thoughts on “Alphabet Soup: Haskell’s Single-Letter Naming Quirks

  1. I completely abhor single letter variables. It makes search and replace ambiguous and error prone, but more important, many IDE’s have a built in function to highlight a variable when it gets selected, for example by a double click, but they need at least a 3 letter variable to do that. This highlighting gives you a very quick overview of where a variable is used in a function (or loop, etc). It also helps with spotting typing errors, although those usually get caught by the compiler anyway.

    I can’t fathom that variables won’t have a meaning in Haskell, (or any other language). It feels like the author is attempting to force his point or provoke a reaction here, but it does not entice me to follow the links and read more. I have attempted python a few times (horrible language) and one of the things I bumped into with python is that if you wanted to write some “generic” functions (or a class) and want to use fairly “generic” names for variables, then it’s nearly impossible, because all the generic words seem to be some keyword for one thing or the other.

    1. Is simple text-search-highlighting for variables still a thing?

      I would expect my IDE to do a syntax based highlighting and recognize the scope of a variable.

      VS has the wonderful Ctrl-R-Ctrl-R refactoring method: global change the name of a var. Works like a miracle all over the project. Just mass rename all those shitty brain fart named variables… :-)

    2. Why would you search and replace variable names in haskell?

      Just like in math, variable names are are only valid in the scope of the functions on which they are bound.

      In other words, just because you have two functions f(x)=2x and g(x)=3x, does not mean they are sharing the same x.

      Haskell variables are not variables in the sense of an abstraction for memory addresses, they are just function arguments. Where they are stored in memory is irrelevant.

  2. Is simple text-search-highlighting for variables still a thing?

    I would expect my IDE to do a syntax based highlighting and recognize the scope of a variable.

    VS has the wonderful Ctrl-R-Ctrl-R refactoring method: global change the name of a var. Works like a miracle all over the project. Just mass rename all those shitty brain fart named variables… :-)

    1. Yep. Still a thing. NotePad++ or Geany is your friend :) . Variables like ‘i’ are a pain to search for and sometimes harder to figure out ‘what’ used for. The rule of thumb I had for our software department was variables needed to be at least 3 chars long and ‘mean’ something in the context used. Only exceptions were were like x,y,z used in a coordinate system. You don’t save any ‘time’ in compiling by making your code short and obtuse and feel ‘smart’ about it. Machine doesn’t care if ‘i’ or, more readable, ‘row’. Of course don’t use all 256 chars (or whatever variable max length is for the language) in a variable name either…. I’ve seen that extreme too. Concise, but project meaning. The next guy behind you will thank you.

  3. Thank you for feature my main language!

    I coincide with paulvdh that one-letter variables are unfortunate, and the fact that we have gotten use to it won’t help. I think probably using something like “monad_type” would be clearer and I think this is an opportunity for improving in the friendliness-to-newcomers space.

    I’m glad that you guys have highlìghted ImplicitCAD, I didn’t know about it! Curiously enough, Haskell also offers other interesting tools for makers, like the Clash hardware description language (https://clash-lang.org/) and Copilot for generating C99 code, for Arduino for example (https://copilot-language.github.io/)

  4. I guess it all comes down to context and culture.

    I think I, j, k are fine variable names when used for array indexes and for loops.

    The Linux Kernel coding style document says something similar, and gives some good explanation.

    i is a good variable name because it’s use is very local and limited in scope, and because it gets used a lot in that scope. The thing being indexed should have a good, longer name.

    But it’s also a good name because it’s part of the culture. Every C programmer is going to learn that early on.

    For the article on Haskell, I’m less able to know if this same logic applies or not.

    Certainly he lists a lot more rules, which is a point against it IMO.

    Maybe we need a way to give variables two names. Something like [i]terator and then you call it just i. And the IDE would understand that and provide hover and highlight.

    (I don’t think square brackets would work for C though. But hopefully you get the idea. )

    1. One of the things I like about DotNet is meta comments (the triple forward slash). Hover over a variable and there’s your comnent. I use it for a brief descriptor, and also unit of measure if applicable (meters, amps, feet, etc)

  5. Ah, Haskell. Quite a fascinating language, but utterly mystified. One can do fantastic things with Haskell with some amount of thinking and a couple lines of code that would take far more effort in other modern high-level languages. However, that’s true for all modern high-level languages in some way or another. Some things that are easy in some other languages are really hard in Haskell, so it turns out that Haskell is quite good for a few things, quite bad for some other things, you can write fascinating programs when you’re experienced, which is more or less exactly what you’d get from any other reasonable programming language.

  6. This is kind of off topic, but I don’t see why it’s “going too far” or “strange” to write an OpenSCAD competitor in Haskell.

    OpenSCAD itself can be really annoying to use because (a) it’s fundamentally functional, but doesn’t quite get the affordances right for comfortable functional programming, and (b) it doesn’t have the full power or expressiveness of a general programming language.

    Actually the big built-in limitation of ImplicitCAD, second to the fact that it’s a tiny niche project with limited community or development support, is that it spends energy trying to reimplement the OpenSCAD language. That’s paying a significant cost just to import many of OpenSCAD’s drawbacks. You can also use ImplicitCAD as a library, which gives you “programmatic CAD” in just as natural a way as OpenSCAD, but with the full power, expressiveness, and fine-tuned usability of actual Haskell. It’d be vastly superior to OpenSCAD if it were well debugged and had a good suite of shape libaries.

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.