Expressive Code in Ruby

Marc Ferraro
5 min readMar 26, 2021

One of the most gratifying moments in my coding journey so far was when I learned about expressive code, the practice of writing code that could convey more than just function. My background is in dance, and naturally my ears perked up — I’d only just started my course and until then had imagined computers as powerful but inflexible interpreters of ideas, and that to write a program was to converse in that rigid mindset. As it turns out, the opposite is often the case, and much like my understanding of movement, any given programmer may have their own way of conveying an idea. This was immensely helpful not only for my ability to code, but also my understanding of what it meant to be a programmer.

When we talk about expressive code, we are referring to code that is able to tell a programmer what (and in the best cases, why) a task is performed in addition to performing that task. Coding this way is essential all throughout a project’s timeline as even a newcomer to code will quickly understand that just a few days without putting eyes on code, even code that you’ve written, will require significant time to mentally reabsorb. Programmers read code as much if not more than they write it and spending the extra time while composing to make sure it is legible later on is well worth it.

I mentioned earlier that I have a background in dance, and while I’ve found that philosophies in dance composition have been remarkably helpful in my visualization of the pathways of code, I never expected that this particular aspect of that experience would be why I reference it.

Without further ado, Labanotation:

Segment of Pina Bausch’s Wind Von West Notated by Mira Kim
Segment of Pina Bausch’s Wind Von West, notated by Mira Kim, source

This is the closest literal practice to coding that dance has to offer, and the fastest way to explain it is that Labanotation is to movement what music notation is to sound. Each symbol represents an action taken by the body based on the distance it is placed from the center of the staff. It is an intricate, precise method to record and preserve dances (in fact, the scope actually goes beyond just dance; in theory, any movement of the human body could be recorded this way). However, if you’ve ever taken any kind of dance lesson, you’ll know that this is not something being read from in a studio, even for projects where a dance is being restored from notation. And why is that?

Labanotation is incredibly specific, but lacks the expression of an actual person performing it. If it were to be followed literally, movements that were meant to flow might be performed robotically (or vice versa!). Thus, the choreographer will interpret it for their dancers, who now will never have to directly come into contact with it.

A Simple labanotation phrase
A walk into a jump, with outstretched arms returning to the side, source

This is where we can return to the world of code: as programmers, when we write we are doing the job of that interpreter for future eyes on our work. In the same way labanotation isn’t used strictly to teach and create new dance, code needs to be more than just functional. We, however, have the unique job of writing our instructions into the movement itself, so to speak.

Consider these three ways of solving this simple code puzzle (puzzle and solutions from code_report):

We want to find which of the arrays in this array has the highest sum (framed as money in a bank account):

[[1,2,3],[4,5,6],[7,8,9]]

First, in C++11:

int maximumWealth(vector<vector<int>>& accounts) {    
auto max = 0;
for (auto const& row : accounts) {
auto sum = 0;
for (auto const& account : row)
sum += account;
max = std::max(max, sum);
}
return max;
}

then APL:

maximumWealth ← ⌈/+/

finally Haskell:

maximumWealth :: [[Int]] -> Int
maximumWealth = maximum . map sum

These languages all able express the same idea in different ways. C++11 feels the most cumbersome, and in this particular scenario we don’t gain a lot from being this verbose. APL sits on the opposite end of the spectrum with only four characters defining the expression. This one is nice to look at, but is almost so slim as to shroud what is actually happening, in addition to using symbols unused by other languages. I’m not very familiar with C++, but even I can kind of piece together what is going on. APL doesn’t have that same cross language benefit.

The Haskell solution feels just right — it reads like a sentence(in reverse) and is able to convey the specific processes that are occurring without rambling on for too long. It feels similar to my own solution in Ruby:

maximum_wealth_array.map {|account| account.sum}.max

It is possible that someone who has no coding experience whatsoever could stumble through the Ruby and Haskell solutions and have a decent understanding of what is going on. They read like plain english, showing no more or less information than necessary. However, the first two are not inferior solutions — expressiveness has context. For the same reason that Labanotation is primarily used to record not teach dance, different approaches are going to better suit different goals. Not only can we express our intent through our syntax, we can express it through our choice of language.

Source

Dance is about conveying ideas through movement, but without expression it is just that: empty movement. We program not for it’s own sake, but to make things. Our code needs to be loud and stand out.

Learning about expressive code was a watershed moment as someone new to this field. There was a lot more creativity in programming that I had previously thought. Writing with this philosophy in mind has made the process much more exciting and enjoyable me, and I hope this has inspired you to think about your code a in a new light. Remember, we’re writing code for every person that ever takes a look at it and someday we may be playing to a very big audience. May you code loudly and move loudly!

Source

--

--

Marc Ferraro

Software Engineer // Graduate from Flatiron School // Dance Teacher and Choreographer