Squid language (was: Looking for tools for support of theoretical informatics research)

Anthony Hannan ajh18 at cornell.edu
Fri Jul 11 17:50:04 UTC 2003


Hannes Hirzel <hannes.hirzel.squeaklist at bluewin.ch> wrote:
> In this context it might be noted that Anthony began a little subproject 
> called Squid which could be very
> interesting from a theoretical point of view as well; just search the
> mail archive for 'Squid' (and perhaps ask him for a status report).

Thanks for remembering.  You can check out the Squid web page at
http://minnow.cc.gatech.edu/squeak/Squid.  However it is not up to date.
 I am still experimenting.

Right now I'm designing the language and am leaning towards lambda-based
objects a la E (erights.org).  That is, every object is a block. When a
message is sent to an object its block is invoked with the message
object as is sole argument.  Dispatching on the message selector is done
by calling #dispatch:.  For example:

 false _ [
	here dispatch: {
		#and: -> [false].
		#or: -> [here arg value].
		#not -> [true].
	}
 ].

'here' is synomynous with 'thisContext'.  The sole message argument is
not explicitly specified since it is the same everywhere.  It can be
accessed via 'here message' or its components can be accessed via 'here
selector', 'here args', 'here receiver'.

A "class" would look like:

 Message _ [
	receiver _ nil.
	selector _ nil.
	args _ nil.
	instance _ [
		here dispatch: {
			"instance methods"
			#receiver -> [receiver].
			#selector -> [selector].
			#args -> [args].
		}
	].
	here dispatch: {
		"class methods"
		#receiver:selector:args: -> [
			receiver := here args first.
			selector := here args second.
			args := here args third.
			instance
		].
	}
 ].

'Message receiver: 1 selector: #+ args: {2}' would return the
instance block with free vars (receiver, selectors, args) bound
appropriately.  It will understand #receiver, #selector, or #args.

If a message is sent to an object that it does not understand directly,
it will delegate to the selector's default block if one exists.  For
example,

 #arg _ [here receiver args first].

When 'arg' is sent to an object and the object does not specify an
implementation for #arg, then the #dispatch: method will invoke the
block assigned to #arg with the original message as its message.  So the
above block will be invoked with 'here receiver' referring to the
original message instance.  This #arg message will work on any object
that understands #args, which in our case includes both Messages and
Contexts.

These "default" blocks replace inheritance.  Although inheritance can
be implemented by the user by implementing his own dispatch method.

Finally, a nice side-effect of block-objects is that the same block is
invoked for every message sent to an object, allowing us to implement
"method wrappers" easily.  For example,

 nil _ [
	Transcript show: here message printString.
	here dispatch: {
		#isNil -> [true].
		#ifNil: -> [here arg value].
		...
	}
 ].

'Transcript show:...' will be called on every message sent to 'nil' even
if it does not understand it.

Comments?

Cheers,
Anthony



More information about the Squeak-dev mailing list