Academics are infamous for their project names and abbreviations, so,
let’s call this #bikexit17…
As some people already know, I am starting a new position in October.
I will be a lecturer at the University of Kent as part of the
Programming Languages and Systems group. While I am pretty excite about
the opportunity to work with a very interesting group, it reminded me of all
the little annoying things I went through when moving from Lille to Linz.
One of them was shipping my bicycle. Last time, I was already thinking, well,
why not ride it instead of shipping it?
And that’s where we are this time around.
I got a few holidays I have to take anyway.
And, I could use a real offline holiday for a change.
Especially, since I suspect the start in Canterbury to be a bit stressful.
It should be possible to do the whole trip with about 11 days of cycling. Currently, my plan is as follows:
Day 1: Linz -> Passau, a brief 90km to warm up (Sept. 9)
Day 2: Passau -> Regensburg, ca. 140km (Sept. 10)
Day 3: Regensburg -> Ansbach, ca. 140km (Sept. 11)
Day 4: Ansbach -> Mosbach, ca. 130km (Sept. 12)
Day 5: Mosbach -> Heidelberg -> Mannheim -> Worms, somesightseeing and ca. 90km (Sept. 13)
probably a day of rest
Day 6: Worms -> Koblenz, ca. 150km (Sept. 15)
Day 7: Koblenz -> Bonn or Cologne, ca. 70-100km (Sept. 16)
Day 8: Bonn/Cologne Maastricht, ca. 140km (Sept. 18)
Day 9: Maastricht -> Brussels, ca. 100km (Sept. 19)
spending a couple of days in Brussels and around
Day 10: Brussels -> Lille, ca. 130km (Sept. 21)
perhaps another day in Lille
Day 11: Lille -> Canterbury, ca. 130km (Sept. 23)
If I am passing by your region, I’d be happy to have some company along the way.
Will probably start out with a friend to go to Passau, and might have company around Bonn.
Flanders should also be a very nice area for cycling 😉
Since this is my first trip of this magnitude, I am also happy for any tips,
recommendations, does/dont’s, you might be willing to share. Got already some,
but wouldn’t mind more.
And, just to be clear: such adventures are drastically simplified by being able to travel without passport, or roaming charges.
So, thank you EU. Thank you very much!
SOM, the Simple Object Machine, has been a steady companion for much of my
research. As mentioned earlier, all this work on virtual machines
started for me with CSOM, a C-based implementation of a simple Smalltalk
language. From the beginning, SOM was meant as a vehicle for teaching language
implementation techniques as well as doing research on related topics.
As such, it is keep simple. The interpreter implementations do not aim to be fast.
Instead, concepts are supposed to be expressed explicitly and consistent, so that
the code base is accessible for students. Similarly, the language is kept simple
and includes dynamic typing, objects, classes, closures, and non-local returns. With these features
the core of typical object-oriented languages is easily covered.
One might wonder about exceptions, but their dynamic semantics very
similar to non-local returns and thus covered, too.
Originally, SOM was implemented in Java. Later, CSOM, SOM++ (a C++-based implementation),
AweSOM (a Smalltalk-based implementation) joined the family. Some of this history
is documented on the old project pages at the HPI, where much of this work was done.
When I picked up maintaining the SOM family for my own purposes, I added
As part of the work on building a fast language implementation, I also
added TruffleSOM, a SOM implementation using the Truffle framework on top of the JVM.
As well as RPySOM, an RPython-based bytecode interpreter for SOM, and RTruffleSOM,
a Truffle-like AST interpreter implemented in RPython.
A Fast SOM
For TruffleSOM and RTruffleSOM, the focus was on performance. This means,
the clarity and simplicity got somewhat compromised. In the code base, that’s
usually visible in form of concepts being implemented multiple times to cover
different use cases or special cases. Otherwise, the language features
haven’t really changed. The only thing that got extended is the set of basic
operations implemented for SOM, which we call primitives, i.e., builtin
operations such as basic mathematical operations, bit operations, and similar things
that either cannot be expressed in the language, or are hard to express efficiently.
The main reason to extend SOM’s set of primitives was to support a wide set of
benchmarks. With the Are We Fast Yet project, I started a project to
compare the performance of a common set of object-oriented languages features
across different programming languages. One of the main goals was for me to be
able to understand how fast TruffleSOM and RTruffleSOM are, for instance compared
Well, let’s have a look at the results:
The figure shows the performance of various SOM implementations relative to
Java 1.8, i.e., the HotSpot C2 compiler. To be specific, it shows the peak
performance discounting warmup and compilation cost. As another reference point
As the numbers show, TruffleSOM and RTruffleSOM reach about the same performance
on the used benchmarks. Compared to Java, they all are about 2-4x slower.
Looking at the results for Node.js, I would argue that I managed to reach the performance of state-of-the-art dynamic language VMs with my little interpreters.
The simple SOM implementations are much slower however. SOM and SOM++ are
about 500x slower. That is quite a bit slower than the
performance reached by the Java interpreter, which is only about
10-50x slower than just-in-time compiled and highly optimized
Java. The slowness of SOM and SOM++ are very much expected
because of their focus on teaching. Beside many of the little design choices that are not optimal for performance, there is also the used bytecode set, which is designed to be fairly minimal and thus causes a high overhead compared to the optimized bytecode sets used by Java, Ruby, or Smalltalk 80.
Making SOM++ Fast with Eclipse OMR
As shown with TruffleSOM and RTruffleSOM, meta-compilation
approaches are one possible way to gain state-of-the-art
performance. Another promising approach is the reuse of existing
VM technology in the form of components to improve existing
systems. One of the most interesting systems in that field is
currently Eclipse OMR. The goal of this
project, which is currently driven by IBM, is to enable languages
such as Ruby or Python to use the technology behind IBM’s J9 Java
Virtual Machine. At some point, they decided to pick up SOM++ as
a show case for their technology. They first
integrated their garbage collector, and later added some basic
support for their JIT compiler. My understanding is that it
currently compiles each bytecode of a SOM method into the J9 IR
using the JitBuilder project, allowing a little bit of inlining,
but not doing much optimizations. And the result is a 4-5x
speedup over the basic SOM++ interpreter. For someone
implementing languages, such a speedup is great, and not to snub
at, even if we start from a super slow system. But as a result,
you reach the performance of optimized interpreters, while still
maintaining a minimal bytecode set and the general simplicity of
the system. Of course, minus the complexity of the JIT compiler
To reach the same performance as TruffleSOM and RTruffleSOM, there is quite a
bit more work to be done. I’d guess, SOM++ OMR would need more profiling
information to guide the JIT compiler. And, it probably will also need a few
other tricks like an efficient object model and stack representation to really
achieve the same speed. But anyway, to me it is super cool to see someone else
picking up SOM for their purposes and built something new with it 🙂.
Other Uses of SOM
And while we are at it, over the years, some other projects spawned off from SOM.
There was NXTalk for
the Lego Mindstorm system. My own ActorSOM++,
which implemented a simple Actor language as part of SOM. And more recently,
SOMns, a Newspeak implementation
derived from TruffleSOM. You might have noticed, it’s actually a bit faster than
TruffleSOM itself :) And, it supports all kind of concurrency models, from actors over CSP,
STM, fork/join, to classic threads and locks.
Similar to SOM++ OMR, the Mu Micro VM project picked up
a SOM implementation to showcase their own technology. Specifically, they used
RPySOM, an RPython-based bytecode interpreter
for their experiments.
Guido Chari forked TruffleSOM to built TruffleMate
and experiment with making really all parts of a language runtime reflectively
accessible, while maintaining excellent performance.
And last, but not least, Richard Roberts is currently
working on a Grace implementation on top SOMns.
So there are quite a few things happening around SOM and the various offspring.
I hope, the next 10 years are going to be as much fun as the last.
This post, the fourth in the series, is about my current work on
concurrency and tooling. As mentioned before, I believe that there is not a
single concurrency model that is suitable for all problems we might want to solve.
Actually, I think, this can be stated even stronger:
Not a single concurrency model is appropriate for a majority of the problems we
want to solve.
In practice, this means that the programming languages, which we have today, all get it wrong.
They all pick a winner. Be it shared memory, a very common choice (e.g. C/C++,
Java, C#, Python, …), or be it message-passing models with strong isolation
suboptimal, and restricting. It will either lead to code riddled with data races or deadlocks, or it becomes
increasingly difficult to ensure data consistency or performance.
So, what’s the solution? I have been advocating for a while that we should
investigate the combination of concurrency models. As part of this
research, we started Project MetaConc. The goal of the project is
not necessarily to design languages that combine models, but instead, provide
more immediate solutions in the form of tools that allow us to reason about the
complex programs we already got.
We outlined the vision in a short position paper last year. The general
idea is to devise some form of meta-level interface for tools to abstract from
the concrete concurrency models present in a language or library. With meta-level
interface, I mean either some form of reflective API in a language, or an
interface to the language implementation, which could either be an API or something
like a debugger protocol. This would allow us to construct tools that can handle
many different concurrency models, and ideally, their combinations, too.
We started the project with looking into debugging.
Specifically, we focused on the actor model and identified the kind of
bugs that might occur and what kind of support we would want from a debugger to
handle actor problems. Carmen, one of our PhD students,
reported on it at the AGERE’16 workshop.
I myself had good fun adding debugging support to SOMns. With Truffle’s debugger
support that’s pretty straightforward. You just need to add a few tags to your AST nodes
as described in my blog post.
Since I was already busy with the debugger, I also invested some time into the
language server protocol (LSP), a project pushed by RedHat and Microsoft.
I think, with a platform like Truffle, and a generic way of talking to an IDE like the LSP,
it should be possible to get basic IDE support for a language by just
implementing a Truffle interpreter. But since that’s getting a little off topic,
I’ll just point at the Can we get the IDE for free, too? blog post.
In practical terms, the LSP allowed me to provide a very basic support for code completion,
jump to definition, and debugging support for Visual Studio Code.
More recently, I demoed our own Kómpos debugger for various concurrency models at the
<Programming>‘17 conference. It is a live debugger that abstracts from specific
concurrency models, and instead allows us to use custom stepping operations and
breakpoints as provided by the SOMns interpreter. In the demo, I wasn’t actually
able to show that yet. That’s more recent work, which we wrote up and submitted
for review to DLS’17. And at least for debuggers, I think we come very close
to the goal set out for the project. We devised a protocol that uses metadata
to communicate from the interpreter to the debugger which breakpoints and stepping operations are supported.
This makes the debugger completely independent from the concurrency models.
We also showed that one can use such concurrency-agnostic protocol to provide
visualizations. And I hope that’s a good indication for being able to build
other advanced debugging tools, too.
That’s it for today. There are so many other things, I probably don’t get to mention.
But, in the next and likely last post in the series, I am going to look
at the SOM family of language implementations.