Roads Less Taken

A blend of programming, boats and life.

Benchmarking Spry vs Squeak

| Comments

Spry is evolving quite nicely during my night hours. Focusing on performance is however still premature, but I do want to verify that I am not barking up the wrong tree, like … in the wrong forest even. So I make trivial benchmarks from time to time, just to see and learn.

Some background on the Spry implementation may be interesting. Spry is implemented in Nim as a direct AST interpreter, it’s not a JIT, in only about 2000 lines of code. It has a recursive classic “naive” design and uses a spaghetti stack of activation records, all allocated on the heap relying fully on Nim’s GC to do it’s work. It also relies on Nim’s method dynamic dispatch in the interpreter loop for dispatching on the different AST nodes. Blocks are true closures and control structures like timesRepeat: are implemented as primitives, normally not cheating. Suffice to say, there are LOTS of things we can do to make Spry run faster!

The philosophy of implementation is to keep Spry very small and “shallow” which means we rely as much as possible on the shoulders of others. In this case, primarily Nim and it’s superb features, performance and standard library.

Enough jibbering, let’s do some silly damn lies - ehrm, I mean silly tests!

Is Spry a Smalltalk?

| Comments

I love Smalltalk and I have been in love with it since approximately 1994. I have used VisualWorks, VisualAge (IBM Smalltalk), Dolphin Smalltalk, GemStone, Squeak and Pharo quite a lot, and I was very active in the Squeak community for a long period.

But the last few years, finally, I have started to feel the “burn”… as in “Let’s burn our disk packs!”. And last year I started doing something about it - and the result is Spry. Spry is only at version 0.break-your-hd and several key parts are still missing, but its getting interesting already.

Now… is Spry a Smalltalk? And what would that even mean?

I think the reason I am writing this article is because I am feeling a slight frustration that not more people in the Smalltalk community find Spry interesting. :)

And sure, who am I to think Spry is anything remotely interesting… but I would have loved more interest. It may of course change when Spry starts being useful… or perhaps the lack of interest is because it’s not “a Smalltalk”?

Smalltalk family

The Smalltalk family of languages has a fair bit of variation, for example Self is clearly in this family, although it doesn’t even have classes, but it maintains a similar “feel” and shares several Smalltalk “values”. There have been a lot of Smalltalks over the years, even at PARC they made different variants before releasing Smalltalk-80.

So… if we look at Spry, can it be considered a member of the Smalltalk family?

There is an ANSI standard of Smalltalk - but not many people care about it, except for some vendors perhaps. I should note however that Seaside apparently (I think) has brought around a certain focus on the ANSI standard since every Smalltalk implementation on earth wants to be able to run Seaside and Seaside tries to enforce relying on the ANSI standard (correct me if I am wrong).

Most Smalltalk implementations share a range of characteristics, and a lot of them also follow the ANSI standard, but they can still differ on pretty major points.

My personal take on things in Smalltalk that are pretty darn important and/or unique are:

  1. Everything is an object including meta levels
  2. A solid model for object oriented programming
  3. The image model
  4. 100% live system
  5. The browser based IDE with advanced cross referencing, workspaces and debuggers
  6. The keyword syntax and message cascades
  7. Message based execution model
  8. Dynamic typing and polymorphism
  9. Closures everywhere with lightweight syntax and non local return
  10. Very capable Collections and a good standard library

Not all Smalltalks cover all 10. For example, there are several Smalltalks without the image model and without a browser based IDE. Self and Slate and other prototypical derivatives don’t have classes. Some Smalltalks have much less evolved class libraries for sure, and some are more shallow in the “turtle department”.

In Spry we are deviating on a range of these points, but we are also definitely matching some of them!

Fowltalk - a New Smalltalk

| Comments

In my quest making Spry I also learned about other efforts in the Nim community to construct Smalltalk-like dynamic languages. The most ambitious one may be Fowltalk by “fowl” who typically hangs out in the #nim channel on Freenode. Fowltalk started out written in Nim but since fowl wanted to learn more C++ it’s now written in C++17.

At the moment he is rewriting the parser and code generator parts in the language itself, following a similar bootstrapping style as Ian Piumarta’s idst. For example, here is the method parsing keyword messages.

At the moment Fowltalk is nowhere near usefulness but its fun stuff!

It’s interesting to look at these bootstrap* files - we can immediately notice some syntactic differences to Smalltalk-80:

Block arguments are written like [| :x :y | ... ] and you can mix both locals and params there: [| :aParam aLocalHasNoColon | ... ]. Instinctively I can agree with the combination, but I would probably then make the first | optional.

Some messages have been changed, like ifTrue:ifFalse: is instead ifTrue:else:. I have done similar simplifications in Spry. And just like in Spry ivars are referenced using @myIvar.

There isn’t any documentation on Fowltalk yet, but it’s clearly a rather elaborate implementation. It compiles to bytecodes, uses numbered primitives (I think) and there is an image mechanism.

It was also quite easy to get the REPL up and running, but just as with Spry, it’s hard to know how to use it! On Ubuntu I installed boost sudo apt-get install libboost1.58-dev and then it was easy to get it running following the instructions, as long as you change to

The image constructed by the bootstrap process is 67Mb in size. Then we can do the canonical Smalltalk test in the REPL:

gokr@yoda:~/fowltalk/idk$ ./bin/oop -i oop.img --mmap --repl
> (3 + 4) print

> !quit

Fowl mentioned that the new parser can be loaded using !read bootstrap.1 but… at the moment that causes errors.

It will be interesting to see where this goes! Fowltalk is very early in its evolution, and it’s not a JIT, but it’s a real bytecode VM with an image and we can never have enough Smalltalk-like languages! :)

Spry Performance

| Comments

When writing Spry I am so far mainly ignoring performance. The general execution of Spry code will be a regular interpreter (although stackless I hope) and not a JIT. But that doesn’t prevent us from playing around and learning something!

In this article I do some silly experiments around interpreter startup time and fooling around with 40 million element arrays. As usual, I am fully aware that the languages (Pharo Smalltalk, NodeJS, Python) I compare with a) have lots of other ways to do things b) may not have been used exactly as someone else would have done it. A truck load of salt required. Now… let’s go!

Spry vs Allen

| Comments

Allen Wirfs-Brock wrote down a bullet list of what he thought actually made it possible for the Alan Kay team to create Smalltalk, and many other ground breaking things, at Xerox PARC in the 70s. Let’s take a look at his bullets one by one and see how it applies to Spry and my puny little effort around it :)