[net.lang.st80] New Smalltalk related language

lewis (03/31/83)

(hope this doesn't get in twice)
Now that this group seems to actually have some discussion on it, even
one article bemoaning the lack of an implementation, I'm going to jump in.
I've recently designed a language, which I call Spadina, that is heavily
based upon Smalltalk - primarily 76, since that's what I'm most familiar with.
It extends it in a few ways that I thought would be interesting, but is
still unstable. In particular, one feature of it is that it uses continuations
rather than simple call-return. That it, when a message is sent, one of the
parameters of the message is an object that should be sent the result.
Normal call-return consists of creating an object that understands a message
containing one parameter, and passing it as the continuation. Any method is
free to ignore a continuation, and to call another one, for example, or to save
a continuation, or anything that you can do with a normal object. The result
of this is that it's really easy to generate control structures in Spadina.
To do things like while statments with an exit you don't have to pass booleans
out of the body; instead you pass the continuation of the loop to the body -
it can then call it directly to exit from the loop if it wants.
Here are a couple of examples - the first one teaches objects to understand
the while message without exits. The ~> token in a message receiver indicates
that the continuation is to be bound to the next name. In a message, it
indicates the value that is to be used as a continuation, rather than creating
one for call return. By explicitly supplying a continuation that is the same
one a you are called with, tail recursion is achieved.
The token :: means passed by name.

object scripts:
`	while :: cond do :: body ~> q
	[	cond ->
		[	body;
			self while :: cond do :: body ~> q;
		];
	]
'

Here's the more complex example. The only different thing about this is that
it uses closures, which in Spadina can understand more than one messages.
Some receivers enclosed in a { } pair create a closure.
A closure can be created to understand messages of the same forms as a class,
and so can be considered to be an instance of a class.
There are no instance variables, however, as a closure
is intended to use the bindings of the environment that it is created in.
This example creates a closure that understands the imperative message "exit",
and just passes control to the continuation of the while. This closure is
passed as a parameter to the body of the loop; see the example below it for
usage.

object scripts:
`	while :: cond doexit : body ~> q
	[	cond ->	body exitis:
			{	exit
				[	q ~^ : nil;
				]
			};
		self while :: cond doexit : body ~> q;
	]
';

i <- 0;
fred while:: i != 10 doexit:
{	exitis: outer
	[	j <- 0;
		fred while:: j != 10 doexit:
		{	exitis: inner
			[	a(i)(j) = -1 -> outer exit;
				a(i)(j) = 0 -> inner exit;
			]
		}
	]
};

This example shows another truth about Spadina - not all the bugs and clumsy
parts have been gotten out yet. In the above example fred is useless - just a
random object that understands while::doexit:.

My favourite examples of how wonderful continuations are the construction
of goto's (as a perveted example of the generality of the language), which
takes about 7 lines of code, and the construction of monitors, conditions,
and fork, without using any parallelism in the implementation, in about
60 lines. The latter example keeps a queue of continuations around for the run
queue, and a couple for each monitor. Fork just places a reference to
the continuation in the run queue and returns.

Some other things that Spadina has are dynamic bindings of variables, multiple
"global" environments, different access to traits, and a different handling of
"arrays".

At any rate, my first implementation is almost done, and I'm willing to send it
out to most people free when it is (April-May). I'm interested in comments/
suggestions, and hope this hasn't been too long or boring.


				author new title: "david lewis"