We succeeded in running the Smalltalk-76 language on our vintage Xerox Alto; this blog post gives a quick overview of the Smalltalk environment. One unusual feature of Smalltalk is you can view and modify the system’s code while the system is running. I demonstrate this by modifying the scrollbar code on a running system.
Smalltalk is a highly-influential programming language and environment that introduced the term “object-oriented programming” and was the ancestor of modern object-oriented languages. The Alto’s Smalltalk environment is also notable for its creation of the graphical user interface with the desktop metaphor, icons, scrollbars, overlapping windows, popup menus and so forth. When Steve Jobs famously visited Xerox PARC, the Smalltalk GUI inspired him on how the Lisa and Macintosh should work.
Be sure to read the comments after the article itself, since it includes comments and clarifications from none other than Alan Kay himself.
A few years ago I was exploring new (to me) programming languages and looked into Smalltalk. I found a modern implementation called Squeak, and the ability to modify code during execution was one of the most interesting aspects of the system.
In 1985, I saw essentially this exact same demo, give by an Apple Guy at a campus event. He was showing off Smalltalk on a Mac Plus. The demo was instead of changing the background to black, he changed the width of the scrollbar.
It’s hard to appreciate it with screenshots in contrast to seeing it live.
If you want to see it, go and download the latest All In On Squeak Image from squeak.org
At the top, there’s a Projects menu, create a new MVCProject. An MVC project brings back the original UI of Smalltalk 80.
Right click, open a browser. Click and such around to get a feel for it. The main panes all have a scrollbar.
Right click again, open a workspace. Type “ScrollController class browse”, then right click and select “do it”.
A browser will show up. In the second column of the top row of lists, make sure “instance” is selected. Then click on “basic control sequence” in the 3rd column, and finally “controlInitialize” in the 4th. Below is the source code for a scrollbar.
Locate the “24”, and change it to something like “36”. Then right click, and select “accept” (it’s way at the bottom).
Shazam, fat scrollbars.
This is a great demo because it is, in fact, instantaneous and immediately visible. You can change the scrollbars for the new Morphic UI, then they don’t instantly update like the MVC one does. Since the MVC panels are constantly recreating the scrollbars as the mouse moves, vs Morphic where they create them once.
But here’s the important detail about what happened here.
Squeak came out in, oh, what, 1996?
The Smalltalk I saw in 1985 is the same ST80 that came out of Xerox in the early 80’s. Apple was one of the early partners to work with Smalltalk. Smalltalk is an image based system. So, the image is the source code. You just need a runtime to make the image work. The image I saw running in 1985 is the same image that the Squeak guys used to bootstrap their new runtime. A direct lineage from the Xerox team (the detail that the folks working on Squeak WERE the same folks from the Xerox team is a nice happenstance).
So, it’s exciting seeing the lineage of the original system, way back to the 1980s. This sort of secret project that was buried behind the locked doors of research labs, but allowed to sneak out. And that even today, you can reach back and kind of see what they were working on back in the day.
If you like, you can contrast the original Squeak v1 machine, and it’s image and sources from over 20 years ago. They’re available on the web site, the EXE works fine with Wine. See how the image has exploded from 2mb up to over 35, similarly with the sources.
The other interesting thing is that here is a source base that has been constantly maintained since the late 70’s. It probably has similarities with Emacs in that regard. I imagine there is nothing left of the original, as in “This is my favorite axe — I’ve replaced the head twice and the handle 3 times.” While the details have changed, the whole is maintained.
But the line is there. The work is there. Not only is it, perhaps, a 40 year old project, but it’s actually an ACTIVE 40 year old project.
It’s almost romantic to think that there are lines of code in this thing that have, while perhaps moved around, remained unchanged for 40 years — yet still work, and still do their job.
Interesting, if you look at the ScrollController from the latest 5.x release, and compare it to the Squeak v1 release, save for a local variable being removed (which is actually in the code, but commented out), the code is identical. How long has this code been around.
Well almost any programming language will be new compared to Fortran…
Does anybody knows how to trigger the class browser? Was it an application to edit global properties such as the scroll bar? or can you edit the code for each individual application?
What happens when you messed up the code? e.g. set the size of buttons to zero. Was there a way to reset the custom code?
There were two main ways to trigger the class browser.
1. Opening it up from a menu (exact location depends on Smalltalk image).
2. Middle-clicking an object in the UI allowed opening a menu and choosing the Browser for it.
Your last point is the issue though. To my mind Smalltalk failed for two real reasons:
1. At the time it was expensive, really expensive, and the hardware was expensive too.
2. It had an image problem – Smalltalk stores the state of the system in images, which can be loaded. On the one side this enables live editing of absolutely everything (including the language and environment). On the other side, if you messed up you could really mess up – having to revert to an earlier image. Sometimes this is a real pain, as trying to track which of a number of image files introduces a subtle issue may not be simple.
There is a reason Test-Driven Development originally came from the Smalltalk camp.
I really recommend people download a copy of Squeak (http://squeak.org/) though – it bears enough similarities to the original to be worth a look, and it can really change your perspective on what is possible.
Edited 2017-10-23 20:59 UTC
You “Don’t save”.
The image is just that — a memory image. You need to “save the image” to “save your changes”.
If you hork up the image with bad code, don’t save it. Reload from your existing image and start over.
The novel thing, especially at the time, was that every time you enter a command in to the system, Smalltalk will save that command to the Changes file. Like Bash History.
This was specifically for this issue. If you crashed your image, you would reload from the most recent saved image, and then, one by one, re-apply the changes from the change log until you got to “just before” you messed everything up.
It’s essentially like “point in time” recovery in a database.
Imagine if your source code was committed locally every time you changed it. With normal system, you save your file, and that’s it. Unless you have a back up, the new overwrites the old.
In this case, each change is saved out, then you work with a Change Browser to manifest changes going forward.
Today, it’s even a mechanism for collaboration in the Smalltalk community.
It was quite novel and exciting for the time. It’s still novel today.
Changing code at runtime seems quite a feat at first glance. But then I wonder what practical use it has. If it was vital it would probably be possilbe to implement it also with other languages. But what for other than an educational exercise? And those things usually come at a penalty in terms of complexity or resource use.
Is is implemented in other languages, Lisp language family, Mesa/Cedar, Erlang, Eiffel, Dylan, Julia, Ruby, Python and to smaller extent Oberon, Java and .NET.
Edited 2017-10-24 17:13 UTC
The downside with the on the fly modification system in Smalltalk is that over time the memory gets badly fragmented. Often, it took almost as long to run garbage collection as it took to reboot the system rather limiting its utility in production.
Maybe if you’re running a ca 1980 Garbage Collector, but not today, not hardly.
Pharo has put a lot of work in to their GC recently, and are working on making it better for 7.0. They’re closing in on Java’s performance for GC.
Hm, IIRC Sugar UI (of One Laptop Per Child XO-1) was also kinda live or near-live modyfying, in Python, with a keyboard key for “show/edit source”. I wonder what will be the result off all those millions(?) kids “graduating”…
Well, a modern example of this in production, today, in a gazillion places, is the Java Application Server environment — i.e. Tomcat et al.
You have a running server, to which you can deploy (and redeploy) applications. This is a live, running server who can and does change on the fly, as all of the code shares a monolithic heap.
But also, similarly, consider a normal Java program. Java runs an interpreted byte code for a mythical VM. But over time, the runtime will look at statistics, and then use a Just In Time (JIT) compiler to covert the byte code in to machine code. When the code invokes a method, one second it’s calling the raw byte code and being interpreted, the next the runtime has transparently swapped it out and replaced it with machine code. So this is another example where updating a running system is very practical and done all the time, day in and day out. Even better, the JIT can later learn stuff to do a better job, recompile the method, dump the original machine code and replace it with better machine code.
So, you as a developer get all of the advantages of a byte code (compact code, portable runtime) but the benefits of compiled machine code as well.
Of course, your web browser is another (notorious) example of this, Javascript is very “friendly” to being stomped on by code and having stuff redefined.
Yes this all has a cost, but we are “CPU Abundant” today in most use cases for most applications, so the computer has plenty of idle time to dream this stuff up and make changes.
The real reason you don’t see live-updateable systems like that in common use is that it removes two things: the ability to run code derived from arbitrary languages (notably assembly and C/C++), and the ability for the OS or hardware vendor to exert control over the platform.
But that’s not true.
I mean, really, what is an OS if not a system that can do “live updates” of “arbitrary languages”. Minix can (I believe) almost do this at the kernel level.
Recall that the Smalltalk at the time WAS the Operating System. The machines booted in to Smalltalk. The “kernel” was the Smalltalk VM, that then executed the byte code in the image. Early systems without hardware support were no different than a modern program running threaded code. The Java VM is exemplar of that.
And the Java VM CAN run “arbitrary code” (but only because the host OS will let them). You can dynamically load and unload .DLL/.SO files in Java.
Even the creaky, ancient UCSD P-System could run “arbitrary code”. It could intermix P-Code with machine language segments. At some level, all systems have to be able to do something like that.
It just has to be code compiled in a format recognizable by the OS.
Not really. You can still run compiled code in these types of dynamic systems.
Even some compiled languages supported these type of environments, the objective-c runtime springs to mind.