Translating Idioms

I often advocate to people that I’m helping learn programming that they should learn more programming languages.

One of my early influences on programming was Steve Yegge and from him I internalized the idea that a good programmer should be a polyglot. At the time, I just accepted that as a given, but as I do more teaching, I’ve had the opportunity to think more deeply about why that is.

After all, learning just one programming language is a decidedly non-trivial time investment. Like learning a natural language, there is more to it than just the grammar & syntax. You also need to learn the idioms and tropes, if you want your prose to sound natural. The big part of becoming fluent in a new programming language is learning not just how to do things, but the best/most natural way of doing things (aside: Perl Best Practices was a great book for that & something I wish existed for more languages). This accounts for much of why the prospect of learning a new language can be so daunting.

For example, one of the first programming projects I got involved in was Factor. When I was first starting to learn it, I was coming from Scheme and was trying to write recursive functions to process lists, which seemed very awkward. The community gently told me that the idiomitic way to do that sort of thing in Factor is to use higher-level combinators, like map and reduce. At the time, I just wanted to figure out how to do things in the Scheme way, but I eventually realized that things go much better when one follows along with the natural idioms.

So why should someone go to all the effort?

There are some general reasons – learning anything is a good mental exercise and keeps you from getting stuck in ruts – but I think learning more languages is particularlly useful for someone that wants to be a programmer. The nub of it is that learning more languages greatly increases the number of “tools in your toolbelt” for solving problems.

When thinking about adding to one’s programming repertoire, often data structures and algorithms come to mind as the things to learn. While those are indeed valuable, their value tends to be more at a “macro” scale, when thinking of how to structure the overall approach to a problem. What I’m thinking of here are the little benefits of picking up idioms.

In natural languages, we often adopt loan words to better express something that’s hard to phrase precisely (e.g. schadenfreude). Programming can also benefit by an analogous process of cross-pollination.

For example, while Factor is a stack-based language that’s very different from Clojure, I’ve found some of its idioms of combinators to work very nicely in functional pipelines in Clojure, where we build up a bunch of composed functions that effectively dealing with a data stack in the same manner as Factor. Being aware to all of these different styles, it gives one many more lenses through which to view problems.

Learning idioms from different languages can also help you address little annoyances that you might otherwise not bother addressing. For example, I find myself in Clojure frequently needed to have a vector with the result of two different functions applied to the same value, e.g. [(f1 x) (f2 x)]. That’s not too bad, but the duplication is kind of annoying, especially when you’re doing that in a map or something & you need to make a new anonymous function or what have you.

To me though, that immediately makes me think “oh, this is exactly what bi in Factor is for”, so I went out looking for the Clojure equivalent, and was happy to find juxt.

Very often, one can “ping-pong” between languages to get a more complete understanding of a concept.

When I first read about profunctor optics for Haskell, I was pretty confused, until I eventually realized that lenses are essentially Clojure’s get-in / assoc-in / update-in. That helped develop my understanding of Lenses; then, when I got to Prisms, I could think about what the Clojure equivalent of that would be, which then made me view the Specter library in a new light.

I’m sure not everyone finds learning new programming languages as inherently fun as I do. However, I do think that everyone that works as a programming can be helped by learning a new programming language, particularly one that’s very different from those they already know. Learning new ways of thinking about things gives you new concepts that you’ll start to see popping up everywhere. Maybe those new concepts don’t apply in all cases – trying to bring optics to shell script is maybe a poor idea – but just being aware that this code is doing something that has a name can be invaluable.