There are a handful of programming languages that were so influential that all of the hundreds of programming languages that exist today are based to some degree on these half a dozen or so “root” languages that have been around for many decades.
One of these and a personal favorite of mine is Smalltalk-80. It didn’t just greatly influence programming through its pure Object Orientation paradigm, it also greatly influenced computing itself. The mouse you are using with your PC? The shiny icons on your Smartphone? The idea of moving windows around on a screen instead of just seeing a wall of text? That all goes back to a company called Xerox (you might know them from their copying machines), whose research division PARC (Palo Alto Research Center) made Smalltalk, a weird mix between a graphical user interface and a programming language created in the ‘70s that completely revolutionized computing, which until then was purely text based.
It was the first mouse driven graphical user interface and after Steve Jobs saw it, Apple went on to create Mac OS, Microsoft saw that and created Windows, and the rest is history, now the graphical user interfaces from Smalltalk are everywhere and nobody wants to go back to a text only display.
For quite some time Apple played around with their own Smalltalk implementation (it’s still developed outside of Apple as Open Source to this day, you can get it here), but later on decided to go with Objective-C instead which is heavily influenced by Smalltalk-80, even when it comes to the syntax the two language use. And even Apple’s new Swift language still shares a great deal in common with Smalltalk. Although a real Smalltalker would probably just huff about that imperfect adoption of Smalltalk’s principles. Ruby is also a language heavily influenced by it. And of course Dart, Google’s programming language which I’ve written about here before.
So for historical reasons alone it’s fun to see where this all came from, but more than that it could make you a better programmer, because Smalltalk (just like Lisp) still has many things to offer that a lot of the mainstream languages today don’t. You probably have heard the term “pure functional programming”, Smalltalk is “pure object oriented programming” and can teach you much more about OOP than the majority of mainstream languages today can because their OOP implementation is imperfect in comparison, Smalltalk is where OOP actually comes from (Smalltalk didn’t invent it I believe, but put the theory into practice).
Also interesting is that in Smalltalk, you don’t write your code into text files that then get interpreted as a whole and executed when you run the finished application you’re writing. In Smalltalk, you use something called a system browser (sometimes called class browser, code browser or just browser). Everything in Smalltalk is live objects. You write a single method, compile it, and the code is live in the system and you can inspect it and change it, there is no concept of a runtime in Smalltalk because everything happens at runtime. The programming community has very recently started to do live programming, where you see the changes live while you make them, and people are amazed by the concept, but Smalltalk had this for over 40 years.
There are quite a few implementations of the Smalltalk-80 language, you can find some of the most popular implementations here.
I’d recommend Pharo and Cuis. Cuis is interesting because it is a very stripped down version of Smalltalk-80 that makes it easier to understand the whole system, and Pharo is what you should use for actual production apps and what you should use to getting started with Smalltalk. It’s arguably the best of the free Smalltalks out there right now (there are also very expensive commercial Smalltalks available that are also very good). It’s based on Squeak, which is the continuation of Apple’s Smalltalk-80 implementation as an Open Source project, but modernizes it and removes a lot of the stuff that was more intended for teaching kids programming.
Smalltalk is very easy to learn. Like Lisp it has very few syntactic constructs, in fact, the whole Smalltalk syntax fits on a single postcard:
It was intended to sound natural like English sentences. If you know what named function arguments are which a lot of languages nowadays support but people rarely use, that comes from Smalltalk where it is the only method to send arguments to a function. It’s very descriptive, it makes your code very readable and easy to understand.
Object methodArg1: myArg methodArg2: myArg2.
That is how it looks. Let’s put this into a more concrete example so that you see why it makes code so readable:
canvas drawRectangleWithX: 10 y: 10 width: 100 height: 100.
Even though you have never seen this function before, thanks to the named arguments of the function, you know what all of these arguments do. So you instantly know that this function draws a rectangle at point [email protected] with a width and height of 100 to a canvas. Compare that to most programming languages:
canvas.drawRectangle(10, 10, 100, 100);
Not that readable unless you know how the function works. With Smalltalk you have to write a bit more code, but there is of course autocompletion so you don’t type it out completely by hand and at any rate, code is read much more often than it is written.
Smalltalk isn’t just a language, it’s a whole system. People often compare it to an operating system running on top of your operating system, because it does window management and has apps that run inside of its window. Back in the day when Smalltalk was invented, Smalltalk actually was the operating system of the Xerox Alto computer, so the people who think that aren’t wrong.
It’s a contended issue because some people really like that and some people don’t. There are Smalltalk implementations like GNU Smalltalk which work more like traditional programming languages, but you lose a lot of what makes Smalltalk so great.
When you first start up Pharo, this is what you get:
Looks like a Linux running inside a virtual machine window like VMWare or VirtualBox. But this is actually the programming language. And everything you see there is written in Smalltalk and you can look at the code for everything to learn from it, and more importantly, you can change everything to fit your every need. You have full control over everything. It’s very common to develop your own development tools when working on big projects. For example, you can add a special visualization to the debugger that then helps you debug your project.
When you click on the background somewhere, a context menu opens under your mouse cursor and you get a list of actions and also applications that you can open. These are all the development tools you will use. Test runners, code editors, version control, it’s all there, you don’t need anything besides Pharo Smalltalk, it comes with batteries included.
Here is the code browser which is where you can browse all of the source code in the system for every app and everything else you see on the screen, including of course the code browser itself. And, which is what is probably the most peculiar about Smalltalk, its also where you write your code. Now lets look at another really neat feature of Smalltalk. Let’s close Pharo and open it again, saving the image when we’re asked to.
What? The code browser again? Where is the Welcome screen we got before? That is right, saving the image means the next time you open Pharo, you continue right where you left off, with all the windows where you left them. In fact, every object in the system gets saved in its current state, so it is really as if you had frozen time. You are exactly where you left off. In the middle of debugging an issue but your kid wants your attention? Save the image, and continue just where you left off when you come back to it.
You can also save images under a different name if you want multiple images, your customer when running into a problem could save the image, send it to you and you can debug the problem live without having to first reproduce it. Or if you’re developing a web app, you can put the image on a remote server and run it exactly like it does on your computer at home. No need for something like Docker, and again, Smalltalk had this for decades and now it becomes popular suddenly ;) There are lots of these features in Smalltalk that other languages today adopt and think it’s the coolest thing. So why not just adopt Smalltalk and get all of the next 50 years or so of programming innovation, today :)
But lets use this code browser now to develop a very simple class Counter which lets you increment, decrement and reset an instance variable count, so that you get to see how you write code in Pharo. We will also make use of test driven development, which is baked into the system, so Pharo is also really great if you want to learn more about TDD. This counter example is used in many areas of Smalltalk, you will for example stumble upon it again when you learn web programming with Pharo and Seaside, so it’s a good place to start.
All code in Pharo is categorized in packages so that everything is neat and tidy, so we create a new package by right clicking on any of the packages in the first list and choosing “Add package” from the context menu.
Now we’re asked for the name of the package, enter “MyCounter”. Now it looks like this:
Look at the text area below the lists at the top. It shows a template that we can fill in to create a new class in our new package. Every class in Smalltalk is a subclass of Object or one of its descendants. Our Counter class is going to be a subclass of Object directly, so we replace
#NameOfSubclass with `#Counter’.
Strings in Smalltalk are always betweem single quotes, double quotes mean the text in between is a comment. We need an instance variable “count” for our Counter, so in between the single quotes behind
Now we need to save, you can do that by right clicking anywhere in the text area and choosing “Accept” or just press Ctrl+S (Cmd+S on a Mac). Unless you made an error, your new class is now in the second list from the left.
When selected, the third list shows a single list item “no messages”. Click on that and the text area now shows a template for creating a new method in our Counter class.
In white at the top is the name of the method. Below that in double quotes is a comment describing what the method does. Below that in light blue and in between pipes is a list of temporary variable names (temporary variables have to be declared in between pipes before you use them in Smalltalk). And below that, in red, are the statements, so the things that make your method actually do something.
We want to be able to view the current count of the Counter, in Smalltalk all access to instance variables is done through accessors, setters and getters. So we write a getter called plainly count.
We save (accept) the code and surprise, a window will pop up asking you to enter your name. This only happens one time and all changes you make will be tagged with this name from then on. It’s customary to enter your full name there in CamelCase, so for example “JohnSmith”, but use whatever you like, I entered CrypticWyrm.
Our new method is now listed in the fourth and last list in the code browser and you might have noticed, in the third list it now says accessing.
The third list lists what is called protocols in Smalltalk. It’s just a way to neatly categorize methods so that it is easier to browse through classes to find out what they do. You can name the protocol of your methods however you like, it’s just meant to help but doesn’t change anything in the code itself, but Pharo will automatically try to figure out what name fits best, so for our count getter, it used the accessing protocol.
We’ll now add a setter for our count instance variable to set the current count of the counter. We’ll use that mainly for testing our function. Click on any of the protocols in the third list, and the text area is again prefilled with the template to create new methods. Fill it out for the
Accept the changes and your new method shows up in the fourth list again. This is now enough for us to try out our class, and in Pharo you do that in a Playground. Left click anywhere on the background of Pharo to open the context menu, and select Playground. Now enter this code:
In Smalltalk, we don’t use the equals sign for variable assignment, we use
:= instead and the equals sign for equality, so it’s closer to how math does it. So you won’t see weird
=== syntax. Press the play button in the top right corner and the result of the code on the left is shown on the right. The result is “an UndefinedObject (nil)”. In Smalltalk, all instance variables are intialized with nil by default, which is called null in some other languages. Let’s try setting and getting the count value next.
Now the result is “a SmallInteger (5)”. As you can see, it doesn’t just stupidly print the number 5. You get a live view on the object with lots of information about it. And yes, the number 5 is an object, in Smalltalk, everything is an Object. Even classes. Even integers. Everything. Pure Object Orientation. Fun side note, if/else is not a language construct in Smalltalk, if and else are implemented as methods on boolean objects. Again, pure object orientation.
Our class works, so let’s add more methods. We still need increment, decrement and reset. But what to reset it to? Nil? 0 seems a better choice here, so we’ll probably also want to overwrite the instance method
initialize of our superclass Object (remember, all objects are descendents from Object in Smalltalk) to initialize the newly created counter to 0 instead of nil.
Let’s start with the increment method. In the protocol list (third list from the left) click on “all” since this is going to go into a new protocol and fill out the template, then accept the changes.
Instead of trying out our method in the playground, this time we’re going to write a test for it so that Smalltalk does it for us. To bundle our tests together we create a new class for them, called CounterTest.
In the second list, click on your “Counter” class to deselect it and fill out the class template for our new class:
Note that we are now subclassing TestCase, not Object. Accept the changes and below our Counter class in the second list is now a CounterTest class. Click on it, then in the third list click on “no messages” to see the method template in the text area and replace the template with this new method testIncrement:
Accept the changes and you see the new method in the fourth list. You should notice a circle in front of the method name in the list. Since the method name starts with “test”, Pharo knows that it’s supposed to be a test, so it has integrated the test into the UI. Click on the circle and the test will be run and it should pass unless you’ve made an error. The circle will now be green. Otherwise it would be red. The CounterTest class in the second list also has a circle in front of it. If you click that, all tests for the class are going to be run and the circle turns green if all tests pass.
Now click on the Counter class again and look at the increment method. It too has a circle in front of it now. Since we named our test “testIncrement” in the CounterTest class, Pharo knows that the test is testing the “increment” method in the Counter class. So we can click the circle here to execute the test, without having to go over to our CounterTest class first. Pretty neat!
Let’s do some TDD now, which means before we implement the decrement method, we’re going to write the test and let it fail since the decrement method doesn’t exist yet. So click on the CounterTest class in the second list, then on “-- all --” in the third list and create the method testDecrement:
Accept the changes and click on the circle in front of our new method. The test fails, the circle turns red and a debugger window opens telling us something went wrong. Click on the X in the top left of this debugger window to close it, debugging is outside of the scope of this article but I’ll give you links to tons of tutorials and books at the end of this article if you want to learn more.
Now go over to the Counter class and implement the decrement method. By now you should know how to do that, so I won’t repeat the steps here.
Again, we see the circle in front of our method because we named our test “testDecrement”. So without having to go to the CounterTest class first, we can click on the circle to run the test and now the circle should be green, because our test passes.
Now we’re going to make our Counter initialize with 0 instead of nil. To do that, we need to override the instance method
initialize. So click on the protocol
all to get back to the method template and replace it with this:
After accepting the change, you will see the method in the methods list and there is a small triangle in front of it. That shows you that it overrides a method.
You should also write a test for the new method, you know how to do it now so I won’t repeat the steps here. Also go ahead and write the reset method to reset the counter to zero and the test for it.
That should have given you a nice overview of what Smalltalk is and how you work with it. If you got interested in learning more, there is one thing I want to mention before I send you off into the world of Smalltalk on your own, a bit of terminology which will help you understand other texts about Smalltalk and Pharo.
objectInstance argument1: aVariable argument2: anotherVariable.
This expression is a message. You send a message to the object “objectInstance”. The part
argument1:argument2: (without the arguments themselves) is called the method selector. In Smalltalk you don’t directly call a method on an object, instead you send a message with a selector and possibly a few arguments and Smalltalk then figures out which method to call on the object. When you get deeper into Smalltalk, you’ll find out why and how powerful that is, but for now just be aware of this terminology.
You now know the basics of working with Smalltalk but there is of course much more to learn, thankfully there are tons of screencasts and even free books that teach you everything you’d want to know. And you can of course always just look at Pharo’s source code itself in the code browser. You can find a lot of books here. Since earlier Pharo versions can be a bit different than the most recent one, you should either start with the most recent book or use the same old Pharo version that is used in the book you want to work through.
I’d recommend starting with the 2017 book “Learning Object-Oriented Programming, Design and TDD with Pharo”, but if you find the book too hard or too easy, try another one, they are all great and since they are free, you won’t waste money by moving on to another book. The book “Enterprise Pharo” concentrates on web development, so if you want to develop websites that might be the most interesting book for you, but lots of the books cover web development to some degree so it is not your only choice.
Here is a collection of useful and interesting links about Smalltalk.
BYTE Magazine Issue about Smalltalk from 1981
Alan Kay talks about Steve Jobs visit to Xerox PARC
The Early History of Smalltalk by Alan Kay
Video interview with Steve Jobs about adapting Smalltalk’s GUI for Mac OS