Max Hallinan

Fragments: let expressions, I/O is also boring

I. Let expressions

In Lisps and ML-style languages, it’s often said that everything is an expression.1 I’ve always been curious: how do these languages get away with let expressions? A let expression looks like it modifies the local environment, more like a declaration or a pattern than an expression.

I’ve been meaning to pursue this curiosity, so I was delighted to come upon the answer in the first chapter of Structure and Interpretation of Computer Programs.2 A let expression desugars to an anonymous function application.

For example:

foo :: Int -> Int
foo a =
    b = a + 1
    c = a + 2
    a + b + c

desugars to:

foo' :: Int -> Int
foo' a = (\b c -> a + b + c) (a + 1) (a + 2)

Variables desugar to function parameters. A value bound to a variable is an argument to the function. The local scope created by a let expression is just a function’s local scope. And the expression following in is the function’s body.

II. I/O is also boring

maybe there's a deep & awkward tension in teaching FP, then, between what makes sense pedagogically (build up concepts from simpler concepts!) and what is actually well-motivated (start with I/O because that's what people actually care about)


My first API call was a GET request to Facebook. I was a new programmer, two months into an internship. The request worked and a list of friends appeared on my screen. For the first time, I populated an app with live data.

My heart beat a little harder. I can really do something with this, I thought. It was the same when I handled my first DOM event and wrote my first web server. I could really do something. But there is never anything in particular that I want to do.

I/O isn’t the reason I learned to program. I didn’t have a task to automate or a problem to solve. I learned to program because I wanted a better job. But I immediately discovered that I like to program. And that’s why I kept learning.

Programming satisfies and delights me perhaps more than anything else. I am gratified by programs that don’t have meaningful output just as much as I am by those that do.

Years after that first API request, I read The Little Schemer and thought, this is what I like about programming. The Little Schemer isn’t about I/O. It’s not really even about Scheme. The Little Schemer is about the way little ideas can be used to build bigger ideas. I like to program because I like to spend time with ideas.

Programming gives me a way to understand ideas not just as words on a page or thoughts in my head, but as spaces I’ve inhabited, surfaces I’ve stood on, connections I’ve traversed. The code I write in my free time is a vehicle that carries me into the place where those structures exist. I learn about programming because I want to see more of that place.

  1. As it turns out, “not everything is an expression”
  2. Structure and Interpretation of Computer Programs, section 1.3.2. 
  3. Omar Rizwan on Twitter. I don't doubt that many people are motivated by doing I/O stuff. I do doubt that this is everyone's core motivation. It's not my core motivation and it's improbable that I'm unique.