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 :)
In the last article I outlined a simple model of modules and that is kinda implemented but needs a few fixes. The next step is how to find and combine modules and this is an area where I want to push the envelope a bit. Most popular package/module systems today are quite trivial in nature. Often it’s a command line tool that queries central catalog(s) and then proceeds by downloading code in the form of source files onto disk. Then the compiler or runtime environment finds and loads the code by simply looking for files on disk. There are several parts of this that are very primitive.
When I built SqueakMap waaay back I was already then tainted with the idea of shared object models and one of the primary ideas in SqueakMap was to make sure each local Smalltalk environment got a full live object model of the catalog which then could be queried, viewed and reasoned about inside the Smalltalk environment. Much more powerful than a bunch of JSON files on disk. This led to the approach of downloading the full catalog in a serialized form - and then loading it into Squeak.
With Spry I want us to create a simpler meta model - at least for starters - but with an even smarter infrastructure backing it…
As discussed in the previous article I want Spry to have a trivially accessible persistence mechanism enabling something similar to the Smalltalk image model, but based on a database. The memory organisation in Spry is basically nested Maps. After dwelling a bit on the inevitable hard question about modules and namespaces I have decided on a design that I hope will turn out simple and reasonably powerful!
Smalltalk has a Dictionary holding all the globals forming “the roots” of the object memory. In Smalltalk this Dictionary is also itself a global variable accessible as Smalltalk, in other words Smalltalk == (Smalltalk at: #Smalltalk). The primary use of Smalltalk is to hold all classes by name, so they are all reachable as globals. Obviously Smalltalk can also hold any kind of object (not just classes) as a global.
Spry also has such a top level Dictionary, but in Spry we call a Dictionary a Map to be a little bit more aligned in terminology with other languages (and it’s shorter). This top level Map is the root Map and it is accessible via the word root. In Spry the root word is actually bound to a primitive function returning this Map, so in Spry we also have root == (root at: 'root).
Ok, so Spry has a Map of globals and one way of using Spry is simply by populating root with words bound to functions making these functions globally accessible, it’s how I have done it so far. Yeah, yeah, I know, but for smaller systems it probably works just fine!
In developing Spry - renamed from Ni - I am getting closer to the Really Fun Stuff.
As a Smalltalker I dream “bigger” than just managing source code as text in files…
Smalltalk uses the “image model” in which the system is alive and running all the time, the full development environment is also live together with your application, and we are in fact modifying object structures when we develop Smalltalk programs. We can also snapshot that object memory onto disk and fire it up somewhere else. Several Lisp implementations have used a similar approach I think.
The image model has tons of really cool benefits, I don’t have time repeating all of them, but a modern implementation of the idea should take a few things into account that was not considered in the 1970s:
The “image” in Spry will be buildable from source
You should be able to use Spry without the image mechanism (you can already)
Spry code will have a readable text format and file structure
The image model does not have to be all or nothing, it can be partial
The image mechanism will be a module for the Spry VM, so you can skip it entirely
Some argue that the image model has downsides - like being an “ivory tower” incapable of interacting with the outside world. The Smalltalk environments have indeed historically suffered a bit in varying degree, but we can easily find ways around those issues while still reaping the awesomeness of a fully live programming environment, especially if we give the above items proper thought from the start.
With Spry I think I have a beginning to a novel approach… as well as taking the above into account.
When I started out implementing my own language in Nim I named it “Ni” without that much thought actually. It was a pun on “smaller than Nim” (obviously one letter shorter!) and of course with a reference to Monty Python.
But… really, the name “Ni” sucks. It’s hard to say in general and since it’s often mentioned together with Nim the confusion is obvious. And it also turned out to be less than optimal to google for.
So from now on the language is called Spry and there are two domains registered for it pointing to the same place - sprylang.org
and spry-lang.net. The main site is sprylang.org, I first registered the .net domain but later realized that sprylang is just as reasonable as spry-lang, and there the .org was not taken.
Well, to be honest I was just surfing for synonyms to various “nice words” and I stumbled over it. I was leaning towards “fleck” but a native english speaking friend talked me out of it. :) Spry jumped up from some thesarus site and… it just feels nice. And the meaning of spry is also very fitting IMHO:
Spry: full of life and energy
One of the primary goals of Spry is to be a fully 100% live programming language and environment.
Spry: Moving or performing quickly, lightly, and easily
…and yeah, the agility and nimbleness is also a big part. Given the influence from “older” languages like Smalltalk, Rebol, Lisp and Forth - I can also see some sense in the typical use of the adjective spry - namely as pertaining to someone elderly! That’s fine with me.