« Back

Ways to Describe Programming

Recently, in the new batch’s first week at Hacker School Recurse Center (cannot get used to this!), we had a workshop called “Programming Jargon.” While I had initially hoped it would help me answer deep and important questions like “Am I using expressive correctly?”, the workshop instead turned into a discussion of the various axes over which programming languages and approaches can be arrayed — a much more interesting topic as it turns out.

For fun and edification, I reproduce them here, including metaphors and opinions.

Functional, Object Oriented, Imperative, Declarative, Low Level


We started with a questions popular among those recently exposed to programming hipsters: “What is that functional programming sh*t all about anyways? And how does it differ from object oriented?”

Alan began by listing example languages for each group:*

  • Functional
    Haskell, Clojure(script), Scheme, Scala, Erlang
  • Object Oriented
    Java, Smalltalk, Javascript, Python, C++
  • Imperative
    Javascript, Python, C, Ruby
  • Low Level
    Rust, Assembly

Of course languages can appear in multiple groupings, and this points to a dimension that perhaps doesn’t deserve its own section but is worth noting: opinionated — say Haskell — and flexible, like Javascript or Scala.

What I found most interesting is the way I find myself metaphorizing these in my mind:

In a functional-style program, a conveyor belt flows through each machine, Wonka-style, producing my Everlasting Gobstopper at the end. Nothing leaves the system till its ready.


In imperative programs, a fleet of nano-chisels surrounds and sculpts whatever goober of code you have created.


Since I don’t do a ton of classic OO, my metaphor here is limited. Maybe something like a return to the functional factory, but instead of the belt going through each machine it is, instead, carrying code goobers that each machine acts on in turn, with its 10,000 claws.


C-Derived, LISPs, Whatever Arrow and Square Bracket Hell Haskell Is

Next, we moved into differences of syntax. This is where I am again reminded of how awesome Radical Computer Science was at pointing out the best worst programmer trait: doing familiar things because they are familiar.

I too am a syntax partisan, though not of familiarity, exactly. LISPy-ness is possibly more foreign than purportedly mathematical notation, but feel so much friendlier. I suspect it is because in Haskell the arrows are always going the “wrong” way, but maybe I just don’t like pointy characters.

And besides, will we ever truly escape the hegemony of C?

Prefix, Postfix, Infix

General syntactic differentiation flowed logically into operational syntactic differentiation. Along with the initial stylistic paradigms, these might be my favorite axes, the way they seem so fundamental. After all, while I may dislike arrows, they don’t represent a deep type of difference.

But LISPs, stacks, and our familiar infix friends each demand a different conception of expressions themselves and a different mental model of what’s going on inside our processors.

Infix languages seem the most familiar since they match the math we learn in school, but they require great complexity in interpretation and construction. Adding a list requires the operator be repeated each time: 4 + 5 + 2 + 8

In comparison, prefix languages are so simple. This is the lure of LISP: it is a function and a list of arguments. And … that’s it. To add a list: ( + 4 5 2 8)

Postfix languages — essentially though not necessarily synonymous with stack languages — are pretty niche (even though Forth was used to land on an asteroid). The addition example appears as simple as the prefix version: (4 5 2 8 +); the deeper mental model to work easily with a stack is very different from our day-to-day. Does the stack go left-to-right or top-to-bottom? Do you write it like PostScript or would reversing the order of commands make more sense? How do you think of what is on the stack and how does your REPL show you? What would a great postfix IDE look like?

Dynamic, Typed

And though I am partial to the question in the former axis, here it is in the answer that my partisanship reigns. When faced with the contrast between the deliberation and safety of static typing and the looseness of dynamism, I can only say:

F*ck safety! Let’s be dynamic. Let’s get sketching. As a friend of mine one said, “I’d rather code than write a bunch of specifications.”

In my more reasonable mind, I can see the allure of typing, particularly optional typing, like Julia provides. But I want the machine to be working to help me instead of the other way around. I love the feeling it gives of aliveness and teamwork, even if it takes a little longer.

Compiled, Interpreted

Not much to say here. With JIT compilers and other web-driven speed innovation, the gap narrows in a practical sense.

Servers, Embedded, Mobile, the Web

The final category turned to where languages are able to be deployed and thereby the biggest actual consideration in selection.


And thus the workshop ended. I’m not sure I’ve got any deep meaning here, other than I love classification. What about you?

What other axes do you use? Tell me on Twitter — @supersgp. Or, if you’d rather read, this programming paradigm wikihole is quite enjoyable.


Declarative was actually left off the list, but in my mind it belongs in this description space. CSS is probably my go-to example for declarative languages, but I know many people would pick SQL (pronounced squirrel). I’ve noticed language nerds these days are really into the concept, though, and I’m excited for more.

« / »