Why is making something first-class the key to expressivity?

This is an episode of Thoughts on Functional Programming, a podcast by Eric Normand.

Subscribe: RSSApple PodcastsGoogle PlayOvercast

People often say that functional programming is more expressive. But how does FP achieve that? The key is by making things first-class.

Transcript

Eric Normand: Why is making something first class the key to expressivity? Hi, my name is Eric Normand. These are my thoughts on functional programming.

One thing that philosophers will do is they take maybe a phenomenon or an idea, and they give it a name. Then they write a whole book on that one thing that now has a name.

In that book, because it's got a name now, they can talk about it. They can characterize it. They can say, "Well, there's two types of the thing." What they're doing is making this thing that might have been intangible before tangible and real by giving it a name.

Now, it can be part of a bigger idea. You can compose it and describe it. That is very similar to what we do in programming when you make something first class. Making something first class, it's a type of reification.

There's this term, reification, which basically means you are making something real. It comes from the Latin, reify. You're making it real. Before, it wasn't quite as real.

It wasn't something you could pass to a function as an argument. You couldn't save it. You couldn't do all the stuff that you normally do with values in your program.

Now, it's made real. The object-oriented paradigm is all about making stuff first class. You're defining a new class to represent a bunch of objects that represent this thing that used to not have any representation in the program. You're making them real.

Very often, what we want to do is make something in the language that exists already. We can do it in the language, but it's not itself first class. Something in JavaScript, the arithmetic operators are not first class.

You want to turn them into something first class, like a function, so that you can pass them around and do other "functiony" things with them. You can compose the functions. You can do a partial application. You can map it over something.

They can now participate in this whole set of things we do with functions. When they're participating in those things, just like now that this philosopher's idea has a name, it can participate in the sentences. It can participate in the ideas and everything that we do with those ideas, and with books and writing, communication.

We are able to write programs where these things can participate. We can express things that we couldn't express before. When plus is not first class, the only thing you can do is add two things together and assign the result or pass that result to something.

If you never make it first class, you can't pass plus as an argument. I know that sounds very petty. There's this one little thing I can't do, which is pass it as an argument. Except when you say you're able to pass it as an argument, it means you're able to choose the thing that you're passing.

I'm able to say, "Well, today, I want to add these things, and tomorrow I want to multiply, so I'm going to make that a parameter. I can pass whichever function I want at the time into it."

It's a way of expressing this idea that the arithmetic or whatever operation I'm going to do is changeable. This is something that you couldn't express when the plus was embedded, hardcoded in your program. There was no way you could change it.

Now, it becomes an f that you're passing into the function. You could pass anything, which is the beautiful thing. It becomes much more about expressing your intent, expressing your domain.

That's why I say that making something first class is the key to expressivity. It's the key of making it participate as a fully-fledged idea that you can compose and do other things with.

Here's another example. In JavaScript and even in Clojure, there's a way to sequence two things to happen one after the other. The way you do it is you just put them one after the other in the syntax.

You console that log a, then console that log b. It will do the log a first and then it'll do the log b. Usually, we put them on two separate lines, but any whitespace could be between them.

That is a non-first-class thing. This is just syntax. You put some whitespace and you have sequenced these two actions. How would you go about making that into a first-class idea, into a reified idea?

You could make a function that takes two actions and returns a new action that sequences them. You could call the function sequence actions. Then, there you go. Now, you have a first-class thing.

You can start talking about, this is the sequence of these actions. Before, you couldn't say that. You could just say do a, then do b, then do c. Now, you've got a thing where you're talking about sequences of actions that you couldn't talk about before.

I hope I've explained that well. Probably not so well. I hope to work on that more. If you have a better way to express this, let me know. I'm @ericnormand on Twitter. You can also email me at eric@lispcast.com.

I love hearing from you. I love getting emails and starting conversations around these things. Please, just stop listening right now. If it's on your phone and you're in your headphones, just pull up your email and send me an email, eric@lispcast.com. All right, I'll see you later. Bye.