I think of NeXTSTEP as one of the best compromises ever pulled off by the commercial computing industry. Xerox’s PARC laboratory showed people Smalltalk and the Personal Dynabook, giving people in the late 1970s one possible vision of the future of computing. This vision proposed that computing be made (morally) individual and accessible. Though, given the limitations of 1970s hardware, it was far from financially accessible.
It is clear that Steve Jobs and the other folks at NeXT bought into that vision, and asked what commodity pieces they could use to bring that vision towards (and eventually, tortuously, into) the mass market. Here is their shopping list:
- A high-end Motorola-based UNIX workstation.
- The BSD operating system, and CMU Mach kernel.
- Adobe’s Postscript.
- Ethernet networking: another innovation from Xerox PARC.
- Sony’s magneto-optical storage technology: a kind of early Minidisc.
But how to make UNIX work like Smalltalk? Another great compromise — the Objective-C programming language. A tool from Stepstone that turns C functions into the implementations of Smalltalk messages. As we discovered, Objective-C’s great compromise was exactly what NeXT needed in the mid-1980s, but it did not take long before it looked more like yesterday’s technology than the future’s (and I say that with much love).
The late Dr. Brad Cox’s great insight was to integrate C programs with Smalltalk messages. The message replaces the UNIX pipe as the unit of conversation, carrying a richer information package to the destination program. Unfortunately, Objective-C’s implementation of this insight leaves a lot of C-ness — a lot of yesterday’s news — in the message, leading to C programs talking to C programs with little indirection. Programmers still need to concern themselves with allocating and freeing memory on C’s heap — I count five different memory-management systems over the years in Objective-C — and still need to worry about how C programs handle different C types when they arrive in a message.
But great insights stick around, so people looked at this compromise, tweaked some of the parameters, and tried again. Ruby enters our story at this point, but another compromise needs mentioning first.
Java
The Oak team at Sun took Smalltalk, and a heavy dose of learning from Objective-C, and created a system where the UNIX (or other operating system) was irrelevant and the C was accessible. This was a huge success in its own right, but stranded every program inside the great Java galaxy — so much so that if you wanted a program you wrote in another language to speak to your Java code, your easiest path was often to port your other programming language to the Java virtual machine.
Ruby
Ruby came along within a few months of Java, and picked a different place in the compromise spectrum.
All of the UNIX. Ruby is a scripting language designed to be a more ergonomic way to control a computer than the Bourne shell.
In fact, when I first encountered Ruby, that is what the evangelist enthusiast showed me: an alternative to Perl or Python (and I was very happy with Perl, thank you).
All of the Smalltalk. Everything in Ruby is an object and everything responds to messages. And, like Smalltalk, everything is garbage-collected, so no more C memory management.
Almost none of the C. It is there, and you can extend Ruby with C, but it is far from automatic.
You need to do all the work to adapt the Ruby and C galaxies where they meet; though these days, the fiddle and ffi gems make this easier than it used to be.
Maybe people will evaluate other points in this compromise space. Maybe they already have. Maybe — just maybe — a different vision of the future of computing will reveal itself, and we will start making new compromises along the way to that future instead.
Rails
As you saw, I did not encounter Ruby as the default programming language for web backends many people saw it as (though it never actually became more popular than PHP at any point); I was shown a nicer Perl. The comparison with Perl is important, in that it is the first programming language I ever encountered to which people pinned their whole identity.
At the time, I did not understand it, as I had already used BASIC, Pascal, Modula-2, Amiga E, C, Objective-C, Bourne Shell, Java, Perl, Emacs Lisp, JavaScript, Python, various assemblers, and probably some other things. To me, programming languages were tools. Sure, some of them were nice tools, some were less nice, some were easy to apply to a given problem, and some were harder to apply. I always thought that was down to me.
But here were grown-ass adults with way more software engineering experience than me, calling themselves “Just Another Perl Hacker” and explaining how There Is More Than One Way To Do It.
I liked Perl (I still do, and I still use it), but I was never going to call myself a Perl Hacker any more than I would call myself a Bread Eater in a supermarket, or a Screwdriver Twister in the hardware store.
Encountering Ruby, and Ruby users, was the second time I met a community of one-tool artisans. Actually, it turned out to be two communities that slightly overlapped due to Ruby, and that nuance was important. One community was the Ruby community. These were the people who gave interesting talks at Ruby conferences — usually not about Ruby, or even about computers — and enjoyed interesting conversations after. They were the people who believed not in TIMTOWTDI but in MINASWAN (Matz Is Nice And So We Are Nice); both when it meant being nice, and when it meant “please do not judge us by our actions, we already told you we are nice”.
The second community was the Rails community. Rails was a popular web application framework, implemented in Ruby because Ruby is the sort of language that makes it easy to design something that looks like Rails (in the same way that Objective-C makes WebObjects look natural, and Smalltalk makes Seaside look natural).
The web became popular at around the time OOP became popular, so most web frameworks are made out of objects even though a web server interaction is typically a function that maps its request to its response with maybe one side effect.
The Common Gateway Interface (CGI) made it easy to turn a web request into a UNIX command, and the command’s output into a response, so we got a second generation of web frameworks that were made out of UNIX: the LAMP (Linux, Apache, MySQL, Programming language) stack. Personally, I used Maypole via Perl.
Rails was, in the spirit of the Great Xerox Compromise, one of each of the above. It was a UNIX tool made out of a scripting language (Ruby), and it was object-oriented because it was made out of Ruby. That made it familiar to refugees from WebObjects or Java Servlets. It also ran on Linux, which in the few years following the dot-com crash came with a huge benefit: it did not cost money.
Despite this, Rails programmers did spend money, They spent it on their laptops: Rails was the second community to push Apple PowerBooks into becoming the default programmer laptop, after the Java galaxy. Not even Reese Witherspoon’s iBook in “Legally Blonde” pushed Apple’s stock price up so much.
They spent money on their text editors, with most opting for the then-proprietary (and Apple Design Award-winning) TextMate.
These days, if you see someone in a café with a MacBook, there is a good chance that they are using Final Cut Pro to edit their next TikTok video. In the late 2000s and early 2010s they were more likely to be trying to emulate the success of Flickr, Basecamp, Shopify, or GitHub, launching a startup backed by a quirky domain name and a Rails application.
Rails was is powerful, easy to use, and cheap, and therefore its fate is inevitable.
It must be less “current” than the latest fad in web application technology, and therefore the “wrong” choice even though it is an entirely adequate choice.
It must become the legacy code that pays the bills while the vanguard attempt yet another rewrite in Phoenix, Node, Deno, Vapor, or whatever got released between drafting this article.
As such, the Rails community has largely dissipated — moving on to newer things, or finding themselves embarrassed at failing to notice the political angle to people who make web applications to control and atomize the workforce. This is probably a good thing for the distantly-related Ruby community, who can get back to discussing Ruby and things entirely unrelated to Ruby.
Maybe they will be the people who create the next big compromise.
Cover photo by Ian Talmacs on Unsplash.