01Jul

The Sterling Bullet

Posted by Elf Sternberg as Uncategorized

One of the best books on software development ever written is the 1986 No Silver Bullet. Brooks’s central argument is that software development in a team requires the constant, daily transfer of active knowledge of progress, and the cost overhead of this transfer exceeds the value of additional developers fairly quickly; adding more people to a failing software project will actually slow the project down.

The classic joke around this book is that, if your manager proposes hiring more people to get the job done, you should buy him two copies of the book so he can read it twice as fast.

Alex Mills recently wrote an essay that got my attention (and that of a lot of other developers), in which he crystallized an emotion that a lot of programming language enthusiasts feel: The World Might Be Missing A Programming Language. Mills’s impression is one I used to share. To some degree I still share it, and I still love hacking on programming languages, but Mills’s laundry list of features he wants in his perfect programming language is the wrong list.

Let’s talk about four programming languages that are awesome, first.

Racket (i.e. Lisp)

Lisp is the great granddaddy of all great programming languages. Functional-first, mutation-capable, and possessing the ur-construct of all special cases (exceptions, parallel programming, concurrent programming), call-with-current-continuation, Lisp isn’t really so much a programming language as a language for writing other languages. It’s so malleable and powerful it can do almost anything.

Lisp’s malleability comes at a price: every developer writes it differently. Every lisp quickly becomes a hard-to-read pile of abstractions because every developer’s brain works differently, and Lisp has absolutely no guard rails.

Lisp also has exactly one semantic construct: the parenthetical. Every Lisp function looks exactly like every other function. Only the names changed. It can be hard, in a deeply nested Lisp function, to discover what is doing what to what.

Haskell

Haskell is the functional programming opposite of Lisp: it has Magical Guardrails. Haskell programs are strongly typed, but they use types not just as validation or as a description of memory, but as actual guidance to the compiler as to how the program should be assembled and run. Haskell is famous for the maxim "If it built, it will run," because types guarantee that the program will do something. It may not always be correct (it’s possible you wrote a plus where you meant minus somewhere, after all), but a huge set of possible errors simply don’t exist in Haskell.

Haskell’s syntax is clear and concise. Almost too concise; it can sometimes not be obvious where functionality is coming from, because the developer’s type-based request can lead to the compiler just going out into the library and, if there’s only one type match, automatically adding it. This is great if you know the library, not so great for beginners.

Haskell also uses some concepts from advanced topics in mathematics. Phrases like "structure-preserving transforms" and "monoids in the category of endofunctors" get thrown around, giving beginners a sense of terror at all the learning that’s about to happen.

Python

Python isn’t either of those language; Python is a dynamically typed language with a strict syntax and a huge standard library. Python is a hit because of that library: it was the first interpreted language to bring massive, available functionality for many of the things programmers did on a daily basis with its initial install. Python’s whitespace-oriented syntax annoyed people when it came out; now it’s considered something of a stroke of genius, as you ought to be indenting your scopes anyway.

Python is easy to learn, easy to teach, and at first glance "does what you mean." Its lack of types can lead to lots of debugging pain and unit testing, but for small programs it’s a wonder of fast productivity.

C

C gets a deservedly bad rap. It’s a language which pretends to have guardrails, but they’re mostly made of spaghetti. On the other hand, C creates predictable assembly language, and it’s possible to extract every last erg of power out of your CPU using it. But it’s "types" are mostly there to describe the layout of memory rather than securely associate functions with objects, and the semantics of C let you change types on the fly. This can be useful for systems programming, where a blob of memory can be a database structure, and the exact same blob just a stream of bytes to be passed over a network, without having to copy or transform the data, but the human overhead of debugging and the notorious security headaches has the world searching for an alternative.

Mills’ language already exists, sort-of

Every time I read a bullet point in Mills list, I had the reaction, Oh, you want Python, or Oh, you mean Haskell.

When he says "I want a language that makes writing asynchronous code easy," my reaction is: Haskell. Haskell goes the full math and says "If you squint just right, everything looks like everything else." A list is a container for a number of things; an exception is just a container for a thing that might fail; an asynchronous operation is just a container for a thing that will happen eventually. By leveraging this insight, Haskell can glue everything together into "an operation that might deliver a list eventually." But Haskell requires exceptional levels of cleverness to know how to put together its n-dimensional Lego pieces. It’s a great language to learn, and it is general purpose, but it’s hard to master.

He wants a Haskell that doesn’t require all that thinking.

A lot of his requests made me think: Lisp. The closest thing we have is Clojure, a Lisp that runs on the Java VM. It resists the classic Lisp explosion by leveraging the Java Standard Library, thus requiring that every deviation from the stock language converges on "tools that still run on the JVM." It’s a nifty restriction and Rich Hickey’s secret weapon. But it’s still a Lisp.

He wants a Lisp that can’t blow up, but isn’t restricted to a VM-only platform.

Like a lot of developers, I gripe a lot about the languages I know best. I complain about Python, Javascript, and Go because I know those languages, and am good at them. I love Haskell and Lisp and Rust, but I also know where those warts are and, unlike the first three, I’ve never been asked to work in them professionally; I suppose if I were using them for something other than recreational purposes I’d get tired of their faults just as quickly.

What Mills (and I, and a lot of other developers) really want is smarter programmers. Self-aware developers who care more abou the code than the usual hired guns we run across in this industry, the fly-by-night, $15/hour code-camp kids who just know how to search Stack Overflow.

Comment Form

Subscribe to Feed

Categories

Calendar

July 2019
M T W T F S S
« Jun    
1234567
891011121314
15161718192021
22232425262728
293031