A Dictionary of Single-Letter Variable Names

http://jackkelly.name/blog/archives/2024/10/12/a_dictionary_of_single-letter_variable_names/

Often, a function is so polymorphic that it’s hard to give the variables useful names. And yet, a convention has arisen around what single-letter names mean. Knowing this convention helps you read library haddocks, as well as make your libraries easier to read for others.

40 Likes

Really good. You might want to add e for error, v for vector and n for natural, integral … s string, state, t time, text.

2 Likes

Thanks, added e, n, s. I haven’t seen enough v so I skipped that.

3 Likes

This is superb, the sort of knowledge that rarely receives a written explanation. Thanks.

Here’s my idea: when traversing tree structures (on both type and term level) I find myself using l and r in binary operators very often! And sometimes as a prefix e.g. lop ln for left-op, left-nat. Though perhaps I’m losing sight of the original blog post at this point :slight_smile:

4 Likes

I’ve seen w fairly consistently for Comonad types, and I think that c for Categorys is at least as common as k (though cat is my preferred convention over either).

3 Likes

Great stuff. You could consider extending to two-letter names – for example, xs is often used for a list, with elements x.

10 Likes

Seriously, we can never have enough cats in our code!

This seems like a great resource for beginners.

I’d add one piece of advice: try to rely on context. If there’s a short name that doesn’t follow a super common convention—and the code isn’t intentionally obfuscated!—chances are you can figure out what it means by zooming out to the broader definition, the module or even the project the code is in. (This advice also applies to folks writing code: only use variable names that are as short as makes sense in context!)

You can actually see this in a bunch of the examples in the article. For type variables, it’s often literally in the type context: you can see that m is a monad or monoid by looking at its constraints. Ditto for most of the other common conventions.

You already demonstrate this principle in a few of the examples that you have, so I figure it’s just worth highlighting this idea in the text too.

6 Likes

Another type-level use of c if for constraints in GADT-happy or Higher Kinded Data-happy code. (1, 2, 3).

3 Likes

Thanks all. I merged the type and value-level sections, because people kept missing some of the value entries (I think because they’d get to the end of the type-level list and think they were finished).

Thanks. This has been there since the beginning, but I think it goes unnoticed because it’s the very last entry in what was a separate “value-level” section. I also have ex for exceptions. Are there others?

Thanks Tikhon, I’ve made this explicit in the opening paragraphs.

1 Like

Big smile, I was going to post “super article, I just think type variables and value variables should have different sections”.

A matter of taste I guess!

I agree with that. I liked the original article because of the clear separation between types and values. I understand the reasoning behind grouping them but it make thinks more confusing.
Maybe using for example :: a for a as a type would make things clearer …

1 Like

Ha, there’s no winning =). I do like that I can now talk about map keys/values, monoids and monads, and errors in a single place. Separate type/value variable sections was my first instinct but people seemed to get lost in the document and not read variables in the “other” section.

2 Likes

A table with separate columns for kind variable meanings, type variable meanings and value variable meanings might work, but would have a lot of empty cells, thus wasting a lot of screen space. :thinking:

Very nice. I found two typos:

A Monad, subclass of Monoid, or (as value) a monadic action.

MonoidMonad

Often used for the (single) numeic induction variable in a recursive function.

numeic → numeric

2 Likes

Fixed, thank you very much.

2 Likes