What's so special about Smalltalk anyway?

Maybe you've seen someone mention Smalltalk, perhaps not knowing what it is, or if you do, wondering why there would be a reason to even bring up such an old, most probably dead programming language at all.

You might know that Smalltalk was invented in the 70s at Xerox PARC, that it was arguably the first implementation of modern OO as we know it, that Unit testing and modern JIT compilation was first implemented in Smalltalk and perhaps a number of other historical tidbits.

And the language itself has inspired many other programming languages, Ruby, Python, Objective-C, CLOS, and even Java. So if you're already developing in one of those languages, you're already benefiting from all that knowledge, so no need to spend any of you attention on computer history, right?

But what is missing from that narrative is how Smalltalk programming is actually done, rather than the language specification as compared to any other programming language. The secret sauce, as it were.

Most programming languages today are source-code based. It is so obvious so you might now be thinking what the alternative could be. I mean obviously, you're writing source code in a file, right? That is how things are done.

It turns out programming can be done in another, mostly quite weird way, with huge but non-obvious immediate benefits. I will now try to describe how this other strange way of programming is done in practice.

With few exceptions, Smalltalk implementations are combinations of programming language, IDE, debugger and run-time, all wrapped up into one (although it can run head-less when it needs to).

Smalltalks are image-based systems, meaning that everything that happens is in-memory, which can be serialized to a changes file, which is reloaded when the VM is restarted.

That means that all classes and methods created and all changes made are made only within that image. When you make changes to a method, it is compiled and linked immediately into the image.

All changes are live.

This means that your program is running inside the image, and any changes you make to the classes and methods that makes up your code, will immediately affect the program as it runs.

Here is an example; I'm making a small rogue-like isometric game in a Smalltalk called 'Pharo'. The game is running as I'm editing it and adding features.

If an error occurs, which happens when you are halfway into implementing something, the debugger shows what is missing and have the same kind of code editor there. When you fix the problem and save the method, you can continue running your code with the new changes. There might be new errors, handled in the same way, until finally everything works again.

What do you need to do to make those changes permanent? Nothing, you just did it. This is sometimes referred to as 'debugger-based development' :) .

This is a big thing, even if it might just seems quirky right now. This mode of developing means that there is a very tight loop between coding, running, discovering problems and fixing them. There is no focus on anything else except the code.

Consider also for a moment what was not present in the example above;
  • Saving to a file
  • Compiling the file to an intermediate format
  • Running the code and switching to another window to see it run
  • Reading a long text-based error message
  • Switching back-and-forth between your source-code editor (doing some simulations of the target environment but not quite there) and the error message
In conversations I've had with engineering directors of companies such as LabView, I've heard estimates that they save at least 5% development time (a conservative figure, which I personally estimate to be higher) just by using Smalltalk. And that the reason for this is just this tight loop.

This does seem nice, I guess,  but seriously, how do you even develop like this? How do team members share code? How do you even deploy anything? Can it run int the cloud, on mobile, what?
OKOK, easy. Right. As it turns out, Smalltalk has evolved quite a bit in the last decade to have the following features;

Full git integration (github/lab/whatnot), persisting code changes as files, but pulling just means some new classes pop up and some methods have changed. Yes, there full git support for diffing, merging, branching, et.c. It's just done from a package and class perspective instead of having to play file management.

Works with Docker, with a number of ready-to-go images to derive from, or to use. Image sizes range from 71MB to 200MB.

This means, incidentally, that you can now easily run a Smalltalk app both inside a Kubernetes cluster, scaling it like nobody's business, or as an AWS Lambda or Google/Azure Cloud Function. There are even a a couple of packages for integrating more fully with AWS services.
As for deploying desktop apps, it is possible to ship a platform-specific Smalltalk VM, a trimmed image and have a script run it with editing/editor disabled. Not perfect but works well, apparently.

Mobile is lagging a bit, but with three interesting projects coming up strong the last years; One is PharoJS, which is a Smalltalk-to-JS compiler which leverages Cordova (running JS in a webview) and Scarlett Smalltalk which is on the first steps of becoming a kind of Smalltalk Flutter, with native bindings for both iOS and Android.

Finally Amber Smalltalk is a Smalltalk implementation in JavaScript, running in the browser, letting you live code your web app, and which also can make mobile apps, suing the same trick (but posibly earlier) that PharoJS did.

I hope I didn't steal too much of your time and also that I conveyed a bit of why Smalltalk can help and perhaps even make something possible that have previously seemed too hard to do. There are other interesting features that the editor and debugger has which I hope to give  detailed post about soon.