Today, we’re going back to the future and do some Smalltalk with the GraalVM.
The Java HotSpot Performance Engine is one of the most sophisticated process virtual machines (VMs) available and used by millions of Java developers every day. If we go back in the early history of HotSpot, not many people may know that HotSpot was initially built by the same team that worked on Strongtalk, a strongly-typed Smalltalk environment as its name suggests. In case you’ve never heard of Smalltalk: it’s both a programming language and a programming system created by a research group led by Alan Kay at Xerox PARC. Although the community today is quite small compared with those of more mainstream programming languages, Smalltalk systems such as Squeak/Smalltalk, VisualWorks, Pharo, or GemStone/S are still widely used in research and industry to this day.
One of the most interesting developments in current virtual machine research, on the other hand, is the GraalVM project. GraalVM is a high-performance virtual machine based on HotSpot and comes with support for multiple programming languages. At this point, I’m sure you’ve already figured out what this blog post is about: running Smalltalk on the GraalVM!
You may be wondering why Smalltalk and GraalVM? For one, it’s, of course, an interesting challenge to bring Smalltalk with all its language features and its programming system to the GraalVM (more on that later).
More importantly, we as a research group are interested in exploring the domain of polyglot programming. Polyglot programming is the practice of writing code in multiple programming languages in the same software project. This gives developers a much broader choice in terms of libraries and frameworks they can re-use.
However, we were looking for the right platform that would allow us to experiment with language interoperability and the GraalVM. Instead of having to go through an external API such as the JVM Tool Interface (JVMTI), a Smalltalk programming system would just be yet another programming language on the GraalVM with direct access to all its runtime capabilities.
Moreover, Smalltalk comes with a comprehensive set of programming tools with support for exploratory programming and live object inspection that we could adapt to other programming languages.
That’s why we have implemented GraalSqueak, a Squeak/Smalltalk implementation for the GraalVM.
Let’s talk a bit about the implementation of GraalSqueak. If you’d like to see some demos first, feel free to skip this section and come back later if you like.
How GraalSqueak Fits into the GraalVM Ecosystem
GraalSqueak’s Bytecode Interpreter
To support Smalltalk on GraalVM, we therefore needed to implement a Smalltalk VM in Truffle. The first challenge, however, was the fact that Truffle is designed for AST interpreters while the Smalltalk-80 specification, as described in the Blue Book, includes a well-defined bytecode set similar to Java.
Although not well-documented officially, Truffle supports the implementation of bytecode interpreters through a special form of AST representation. This approach is used in GraalVM’s LLVM bitcode interpreter and in GraalSqueak, and explained in detail in this paper (preprint). If you’re looking for some code, you can find GraalSqueak’s bytecode loop here.
Supporting the Smalltalk Programming System
The Smalltalk programming system, however, needs a lot more than just a bytecode interpreter to work correctly. Smalltalk is mostly written in itself. The compiler, for instance, is written in Smalltalk and so are many language features such as exception handling or reflection. The language also supports some rather uncommon but powerful mechanisms:
allInstances returns a list of all instances for a given class, while
become: can be used to swap identities of two objects. Moreover, everything is an object in Smalltalk, including source code. So instead of using files, Smalltalk VMs save snapshots of the entire object memory in a file, so-called images, which can then be loaded again later, even on a different platform.
Truffle, on the other hand, does not support most of these features out-of-the-box. Hence, we had to come up with implementation strategies to support all these features on top of Truffle. In the case of
allInstances, for example, GraalSqueak walks all objects just like a garbage collector. And to load an image file, a Java object is allocated for each Smalltalk objects. To be able to communicate with them from other languages, these objects implement Truffle’s interoperability API. On top of all of this, we also needed to port various VM plugins such as BitBlt and Balloon, which are used by the drawing machinery of Squeak/Smalltalk.
Unfortunately, there isn’t enough time to go into more detail. But if you’d like to learn more about GraalSqueak, its implementation, and limitations, have a look at the GraalSqueak paper (preprint) we presented at MPLR’19.
So now, it’s time for some demos! In the following screencasts, we run GraalSqueak 1.0.0-rc6 on GraalVM 19.3.0 and demonstrate various Smalltalk tools that allow us to interact with different languages.
Workspace, Inspector, and Explorer
The first tool is the Workspace, which can be used to interactively evaluate code, similar to an interactive shell. For this, it provides so-called print-Its (
ctrl/cmd + p), inspect-Its (
ctrl/cmd + i), explore-Its (
ctrl/cmd + e), and do-Its (
Math module and invoke its
min function with arguments from Smalltalk and Python. Additionally, the base language of our PolyglotWorkspace can be changed via its context menu. This means the tool can also be used in the same way for all other languages supported by the underlying GraalVM. This demonstrates another advantage of polyglot programming: Language-agnostic tools can provide a much more consistent programming experience and consequently, developers don’t have to learn how to use new tools whenever they learn a new language. Just think about all these different language-specific debuggers for example. Instead, they can keep their preferred debugger and use it for all languages. If you find this idea interesting, have a look at our paper (preprint) on LSP support in Truffle.
The next tool shown in the screencast is our PolyglotInspector. In this case, it’s opened on a Python list and displays both the interface and the contents of the list. The traditional Smalltalk inspector updates frequently to provide more or less live feedback, and so does its polyglot variant. By invoking
append with a Smalltalk object as the argument, we put the object into the Python list, which is displayed in the inspector shortly after. Lastly, the Inspector can easily be turned into an Explorer, which displays interface and contents in a tree view instead of a list.
In our PolyJuS paper (preprint), we have combined multiple workspaces and explorers to build a polyglot, Jupyter-like notebook system. In the video above, we first play around with a Python array and show, how objects can be shared via a special polyglot
bindings object. Then, we analyze the numbers of contributions for two different programming language conferences per country, always using the best library for the job: Ruby’s
nokogiri for extracting data from an HTML table, a Python library called
pycountry to clean the data set, R’s
ggplot2 to render a plot, and the tool itself written in Smalltalk. The PolyglotNotebook comes with GraalSqueak. If you’re looking for GraalVM-powered Jupyter kernel with similar capabilities, check out our IPolyglot kernel.
Java and Smalltalk
Finally, let’s have some fun with Java and Smalltalk! You may have noticed that Java is not listed as one of the supported languages. That’s because there isn’t a Truffle interpreter for Java yet (the GraalVM team is working on it though). But since Java is the host for all languages running on GraalVM, it is possible to interact with the host Java through a dedicated interface. This, in turn, means we can technically access and interact with all kinds of Java objects including parts of GraalSqueak’s own infrastructure. This allows us to change the title of the
JFrame, for example, that GraalSqueak uses for rendering the programming environment. And just because we can, we can call
System.gc() to request a garbage collect before quitting GraalSqueak via
We hope you enjoyed this dive into Smalltalk, GraalVM, and polyglot programming! If you’d like to give GraalSqueak a try, head over to this GitHub repository. The README.md should cover everything you need to get started! Please keep in mind, though, that this is an experimental research VM with various limitations at this point. Nonetheless, please open issues if you run into any problems or if you have any questions.
This summer term, we ran our first polyglot programming seminar at Hasso Plattner Institute. So if you’re interested to see what our students have built with GraalSqueak, check out our post on the GraalVM blog. We look forward to using GraalSqueak for both teaching and research on polyglot programming in the next year!
Last but not least, we wish you a wonderful festive season and a happy new year! 🎄🎅🎉
Discussion on Hacker News: https://news.ycombinator.com/item?id=21735782
Smalltalk and GraalSqueak
- GraalSqueak: Toward a Smalltalk-based Tooling Platform for Polyglot Programming (preprint).
- GraalSqueak: A Fast Smalltalk Bytecode Interpreter Written in an AST Interpreter Framework (preprint).
- Efficient Implementation of Smalltalk Activation Records in Language Implementation Frameworks (preprint).
- PolyJuS: A Squeak/Smalltalk-based Polyglot Notebook System for the GraalVM (preprint).
- Live Multi-language Development and Runtime Environments.
- Smalltalk-80: The Language and Its Implementation (free version).
- Back to the future: the story of Squeak, a practical Smalltalk written in itself.
- Squeak/Smalltalk: Documentation, Terse Guide to Squeak, Research Papers.
GraalVM and Truffle
- Implement Your Language.
- Truffle Language Implementations.
- One VM to Rule Them All (original GraalVM paper).
- Language-independent Development Environment Support for Dynamic Runtimes (preprint).