Stefan Matthias Aust sma at
Mon Jun 29 19:36:58 UTC 1998

Trevis wrote:

>I don't have access to this paper, but I would be very interested
>in seeing these two differences. Can you summarize, or give me a 
>pointer as to where I might get this info?

I'll try a summary of differences in no special order of importance. Some
information is even guessed from reading between the lines.

The purpose of the Smalltalk project is introduced as "to support children
of all ages in the world of information." The paper then describes the idea
behind objects and details the difference between "3+4" where "+" in an
operation of two integer values and "3+4" where "+4" is a message send to
object 3. This is exactly the same as we already know from ST-80. It seems
that there're already unary, binary and keyword messages. A forth kind of
(I'd call it) pseudo messages isn't described but seems to exist. More on
this later.

>From the screen shots, the ST-76 looks like Squeak. Windows are simple
rectangular frames, window title are left centered tabs and scrollbars are
popping out on the left side. It seems that popup menus always popup on the
right side of windows and not at the current cursor position. The mouse
cursor, btw, is called stylus in this paper.  Otherwise look and feel seems
be the same as in ST-80.  I think, there's no system or class browser yet,
but classes are shown as plain files.

A class is defined by

Class new title: 'Window';
  fields: 'frame';

If your class shall subclass an existing class, you can add

  subclassof: Window;

in front of the "fields:" message. Please notice the "!" which seems to
start some kind of special mode for method definition.  The "!" is followed
by a comment. It seems that italic font style is enough to denote a
comment. Categories are defined by a bold and larger font style, again
there's no other sign.  Method definitions are enclosed in [ ], as are
blocks in ST-80 nowadays. For example

  [frame contains: stylus loc =>
    [self enter.
      [frame contains: stylus loc =>
        [keyboard active => [self keyboard]
        stylus down => [self pendown]]
      self outside => []
      stylus down => [^self leave]]]

Here're a lot of interesting things to notice. First of all, ST-76 seems to
have a lot of more binary messages than ST-80 which are special glyphs not
included in the ASCII char set. I tried to represent them here using "=>",
"::" or "^". The arrow is the "ifTrue:" message of ST-76. "::" which is
actually shown as open-colon like a small 8 seems to introduce the already
mentioned forth kind of message send. I think, it works like an ordinary
statement; it doesn't need a receiver. 

Please also note that the "." only separates simple statements, but isn't
needed after blocks or before "^", the usual return operator, always shown
as an arrow in ST-76.

>From another code example

Class new title: 'Rectangle'; fields: 'origin corner'.

origin [^origin] "^ means return"
corner [^corner]
origin: origin corner: corner
  "no code; just store into the instance"

we can learn that comments in double quotes already existed in ST-76 and,
more important, that simple acessing methods didn't needed something like

origin: newOrigin corner: newCorner
  origin <- newOrigin
  corner <- newCorner

(the "<-" btw is the assignment arrow)

Because ST-76 has no real meta classes, a new rectangle has to be
constructed as follows

Rectangle new origin: 0 at 0 corner: 42 at 21

(the "@" is really a little square with a black dot (ugly, IMHO) in ST-76)

Now something more important, which resembles the way, LISP treats boolean
values. In ST-76, everything but the special object "false" was counted as
true! There's the following definition in Object, the paper tells us:

and: x [self=false => [^false] ^x]

Interestingly, it uses "=" instead of "==" (the identity test message)
which isn't mentioned in the whole paper. Also please note, that "and:"
seems to work not with blocks.

The paper then highlights the advantages of subclasses and of
encapsulation. It shows how you could change the implementation of
Rectangle without affecting other classes. Message sends to "super" are
also mentioned.  

Then the implementation of the system is described, IMHO the most
interesting part. Interestingly, ST-76 very much resembles Timothy Budd's
Little Smalltalk system. Now I know from where he took his byte codes. The
paper describes the idea of compact byte code and even lists the complete
instruction set.  It then displays a figure of Classes, Methods,
MessageDictionaries (note, not MethodDictionaries), Contexts and a simple
Rectangle object. Nothing new here and every similar to Little Smalltalk

Each byte code instruction is separated into two four bit nibbles. The
upper nibble decodes the instruction. The lower descibes the argument (an
index or an offset for the instruction pointer). Instruction no 11 is
special. The next byte describes the actual instruction and its argument.
Instruction no 12 isn't detailed in the paper.

1  Load relative to receiver
2  Load relative to temp frame
3  Load relative to literals
4  Load indirect literals
5  Load relative to context
6  Load constant

7  Send literal message
8  Send special message

9  short jumps
10 long jumps

11/0  pop stacktop
  /1  store stacktop into ...
  /2  pop and store stacktop into ...
  /3  return stacktop

  ...= receiver (1), temp frame (2), indirect literal (4), context (5)

12 escapes

ST-76 also features a virtual memory system, which enables the 16 bit
system to store up to 65535 objects, or about 1 MB of memory, assuming
normal object sizes. Some more details are mentioned.

Last but not least, a ST-76 code example of the VM is appended to the
paper. This bunch of code also gives a number of interesting examples of
how to write ST-76. Some highlights...

Array access is done using the subscript message "~" (actually a small dot
like the upper dot of a colon, difficult to show in ASCII). Obviously, it's
a binary message and it can be extended using the assignment arrow as shown

array~i        corresponds to  array at: i
array~i <- 42  corresponds to  array at: i put: 42

The author is proud of the feature to use cascading "=>" conditional
messages to create case-like statements :-) Don't get my wrong, IMHO a case
statement can be very useful in certain circumstances. And describing a VM
meets these circumstances.

byte/16 =1 => [...];
        =2 => [...];
        =3 => [...]

Local variables are separated by a "|" and written in front of the opening
[ of the method definition.

send: message | class meth callee t i
  [class <- self top class.

a for/next-loop looks like...

for:: i to: meth nargs do:: [t~i <- self pop]

I guess that this has the meaning of

(i to: meth nargs) do: [:i | t at: i put: self pop]

but details are missing here. There's another pseudo message

until:: (meth <- class lookup: message) do:: [..]

shown in the source code, but this is strange, too. It seems that this
corresponds to

[(meth <- class lookup: message) == false] whileTrue: [...]

but why isn't the first expression enclosed in [ ]. I'd have expect this
because it has to be evaluated more than once.  Some questions remain.

Nevertheless, I hope this summary is somewhat useful.
Stefan Matthias Aust  //  Are you ready to discover the twilight zone?

More information about the Squeak-dev mailing list