From: Ari.Huttunen@hut.fi (Ari Huttunen)
Newsgroups: comp.lang.misc,comp.lang.eiffel,comp.object
Subject: Request for feedback on the Sather 1.0 Specification
Date: 23 Dec 92 23:51:50 GMT
Followup-To: comp.lang.misc
Distribution: inet
Organization: Helsinki University of Technology, Finland
NNTP-Posting-Host: cardhu.cs.hut.fi

Here is a short list of changes between
Sather versions 0.2 and 1.0 that was
mailed on the Sather mailing-list. At the
end are instructions how you can obtain
the precise specification by FTP. 

And Merry Christmas to you all!

		A.H.

-----clip-------clip--------clip-------clip-------

From: om@ICSI.Berkeley.EDU (Stephen M. Omohundro)
To: sather@ICSI.Berkeley.EDU
Subject: Request for feedback on the Sather 1.0 Specification

Sather version 0.2 has been available for a while now and we have
gotten lots of feedback both from outside users and from internal
projects. Based on this feedback, we have an initial specification for
Sather 1.0, the first "official" version of Sather. It incorporates a
number of new features which are briefly described below. As with
earlier versions, our goal remains to support extremely efficient
computation in the context of powerful abstraction mechanisms. We
would be very interested in feedback on the 1.0 specification document
which is available by anonymous ftp (retrieval instructions are given
at the end of this note). While the implementation is currently
underway, the design is still somewhat flexible. Comments received
before the end of January 1993 are much more likely to have an impact
than later comments. Comments on the design should be sent to
"isather@icsi.berkeley.edu".

The document "The Sather 1.0 Specification" is a precise description
of the 1.0 proposal. The following paragraphs informally describe some
of the features which version 1.0 adds to version 0.2. The features
are listed roughly in the order they might be noticed in examining
ordinary code.

1. Declaration during assignment. Variables can now be automatically
declared to have the return type of an expression which is assigned to
them by using the symbol "::=". For example, "a::=5" could be used to
simultaneously declare "a" as an integer and assign the value 5 to it.

2. Extended routine argument syntax. A routine may now specify default
values for its arguments. Routine calls can either specify the
argument values positionally or by name. Any unspecified arguments
take the default value. Routines may have one unnamed argument which
is automatically named "arg" (somewhat analogous to "res" for the
return value).

3. Iters. The feature which will perhaps affect the most code is a new
iteration construct called an "iter". These are a powerful
generalization of a similar construct in CLU. Typical loops (such as
Sather "until" loops) initialize some iteration variables, execute the
body of the loop, increment the variables in some way, and test for
the end of the loop.  A typical example is code to step through the
elements of an array. The code for initializing, incrementing, and
testing the iteration variables is often complex and subject to
"fencepost" errors. It also often relies on the internal details of a
data structure. The same code for doing this is often repeated in many
places. These aspects suggest that this kind of code should be
encapsulated in some way. The Sather 0.2 libraries introduced a number
of "cursor" classes to help with this situation. The iter construct is
a cleaner and easier to use form of encapsulation.  Iters allow the
iteration generation code to be separated from the body of the loop
which uses it and to be placed in the class which has access to the
neccessary information. Iters look much like routines, except that in
addition to returning values, they can also "yield" them.  For
example, the INT class has the iter:

   iter up_to(last:INT):INT is
      -- Yield successive integers from `self' up to and including `last'.
   res:=self; until res>last loop yield; res:=res+1 end end;

Iters are called from with in "for" loops. For example, to print out
the integers from 10 to 20, one might say:

   for j::=10.up_to(20) loop OUT::i(j).nl end

The body of the loop is executed each time the iter "yields".  Iters
are particularly useful in conjunction with more complex data
structures. For example the ARRAY{T} class has the iter "elts:T" which
yields the elements in order. For example, here is a routine to sum
the elements in an array:

   sum(ARRAY{INT}):INT is 
      for e::=arg.elts loop res:=res+e end end

Iters can also indicate that some of their arguments are to be
re-evaluated on each iteration by declaring them to be "hot". ARRAY{T}
defines "set_elts(hot T):T" which first yields an element of the array
and then sets it to the current value of the argument. To set each
element of "a:ARRAY{INT}" to "7" one could say:

   for a.set_elts(7) end

To double each element of the array one can say:

   for e::=a.set_elts(2*e) end

"For" loops can step through multiple iters at the same time. For 
example, to copy the elements of "a:ARRAY{INT}" to "b:ARRAY{INT}" you
can say:

   for e::=a.elts, b.set_elts(e) end

Many other data structures now use iters where they used to use
cursors. For example, trees have iters to yield their nodes in pre,
post, and in order sequence. Much of the matrix and vector library
code now uses iters. This improves the readability and correctness of
the code. It also improves the execution performance because the
compiler can convert iter loops into inlined code using pointer
arithmetic.

4. More flexible basic types. In 1.0 user programs can now define
basic types with a specified number of bits and specified alignment
requirement. This allows one to design classes for special-purpose
machines with new fundamental types. Basic classes can now also have
attributes. This allows, for example, complex numbers to be
represented by basic objects. It also allows arrays whose elements
have structure to be represented by a single chunk of memory. This
makes certain data structures, such as hash tables, more efficient.

5. Statically type safe. Sather 1.0 is statically typesafe in the
sense that it is now impossible for a program which compiles to assign
an object of the wrong type to a variable. This was made possible by
introducing stronger typing rules and by the introduction of the
"typecase" construct which generalizes and replaces reverse
assignment.

6. Bound and unbound routines and iters. Unbound routines are a new
construct which generalizes the "function pointer" construct of
languages like C. Bound routines generalize the "closure" construct of
languages like lisp. A bound routine combines a reference to a routine
in some class with an object of that class using the symbol "&". The
object explicitly holds the state which is only implicit in a closure.
Some applications of this construct include associating functionality
with operations in a window system, associating actions with rules in
a parser, and constructing higher order routines. For example, here is
how bound routines can be used to write a routine which forms the
composition of two argument routines:

class COMPOSE{R,S,T} is
   r1:ROUT{R}:S; -- The inner routine.
   r2:ROUT{S}:T; -- The outer routine.

   comp_helper(R):T is
      -- Output the effect of `r1' followed by `r2'.
      res:=r2(r1(arg)) end;

   comp(r1:ROUT{R}:S, r2:ROUT{S}:T):ROUT{R}:T is
      -- Return the composition of `r1' and `r2'.
      ob::=new; ob.r1:=r1; ob.r2:=r2;
      res:=ob.&comp_helper end
end;

The class INT defines "abs:SAME" to compute the absolute value and
"sqrt:SAME" to compute the square root. The routine "sqrt" requires
that its argument be positive, so we might want to compose these
routines. The statement:

r::=COMPOSE{INT,INT,INT}::comp(INT::&abs,INT::&sqrt)

makes "r" a bound routine of type ROUT{INT}:INT which first forms the
absolute value of its argument and then takes the square root. For
example, "r(-9)" would return 3.

Another use appears in the ARRAY{T} class. The routine
"map(ROUT{T}:T)" takes a routine as an argument, and applies it to
each element of the array.  For example, if "a:ARRAY{FLT}" then
"a.map(FLT::&squared)" squares each element, while "a.map(FLT::&sin)"
takes the sine of each element.

7. Abstract classes. Classes which specify abstract interfaces are now
defined separately from other classes (their names still begin with
"$"). The syntax has the form:

abstract class $FOO is ... end

They may contain "abstract routines" which specify an interface but do
not provide an implementation.

8. No debug keys. Assert statments no longer have an associated
keyword. Boolean constants are typically used to obtain the same
effect when wanted. 

9. Switch -> case. The name "switch" has been changed to "case". 

10. Typecase. Reverse assignments are no longer allowed. Instead, the
"typecase" construct is used to conditionally execute code based on
the type of a variable. This also introduces powerful new ways to use
the type system.

11. Require and Ensure. Routine and iter pre and postconditions are
now made explicit with "require" and "ensure" clauses. 

12. Default type parameters. Parameterized classes may specify default
types for their parameters. This is convenient when there is a common
case which is only rarely changed.

13. Type bounds. Explicit bounds may now be placed on type parameters. 

14. External classes. Instead of the "C" class, the interface to other
languages is now richer. External classes allow a separate Sather
class to be dedicated to each external object file and for the
interface between Sather and other languages to be smoother. 

15. Literal forms. All data structures are now specifiable in a
literal form. This allows the specification of the initial values of
the elements in arrays, for example. It also allows arbitrary data
structures with circular pointers, etc. to be specified. For example,
a simple linked list class might be:

class LINK is val:INT; next:LINK end

We may describe a circular list with 3 elements by the literal
expression:

#1(LINK,1,#(LINK,2,#(LINK,val:3,next:#1)))

The inner "#1" is a reference to the outer literal expression which is
labelled "#1". Literals may be used to initialize arrays and other
data structures. 

16. Syntactic sugar. The special symbols such as "+", "-", "*", "<",
"[,]" etc.  are now just syntactic sugar for corresponding routine
calls. Classes may define these routines and so allow the use of the
special syntax on their objects. The sematics of equality test and
object assignment are not changable (though assignment to attributes
is). 

17. Exception handling. Exception handling now uses the type system to
switch on exceptions.

18. While statement. The simple loop construct now may utilize both
"while" and "until". 

19. Integer class parameters. In addition to type parameters,
parameterized classes may now have integer parameters as well. This is
useful for specifying the size of fixed-sized arrays (a new basic
class) and the number of bits in an object. 

20. Define and undefine. The old "alias" and "UNDEFINE" constructs
have been replaced by more uniform "define" and "undefine" clauses. 

21. No routines in constant and shared initialization. Arbitrary
routine calls have been eliminated from constant and shared
initializers. This is possible because of the powerful new literal
forms. This simplifies dependencies between classes and allows the
compiler to leave out more unused code. 

22. Default attribute values. Attributes may now specify default
values. The defaults are used if "new" is not passed explicit values
for the attributes. 

23. Enumerated constants. The syntax for defining constants has been
slightly extended to automatically define ranges of integer constants.
For example,

constant a::=5,b,c,d,e,f;

is a shorthand for:

constant a::=5; constant b::=5+1; constant c::=5+2; 
constant d::=5+3; constant e::=5+4; constant f::=5+5; 

24. SAME. "SELF_TYPE" has been changed to "SAME" for better
readability and easier typing.

25. Builtin types. A number of classes are now part of the language
definition.  This makes for greater portability of programs and allows
for better compiler optimization on the fundamental types. The builtin
types include: ARRAY, BITS, BOOL, CHAR, CLASS_TYPE, FIXED_ARRAY, FLT,
FLTD, FLTE, INT, INTH, INTD, STR, SYS. The new numerical classes are
better integrated with IEEE floating point and ANSI C.

26. Interpreter. The new compiler will support interpreted execution
and dynamic linking of compiled routines. This should speed up the
class design cycle and significantly improve the development
environment. 

You may obtain the proposed Sather 1.0 specification by anonymous ftp
as follows:

% ftp ftp.icsi.berkeley.edu
Connected to icsic.Berkeley.EDU.
220 icsi-ftp (icsic.berkeley.edu) FTP server (Version 5.60.l) ready.
Name (icsi-ftp:username): anonymous
331 Guest login ok, send ident as password.
Password:
230 Guest login Ok, access restrictions apply.
ftp> binary
200 Type set to I.
ftp> cd pub/sather
250 CWD command successful.
ftp> get manual-1.0.ps.Z
200 PORT command successful.
150 Opening BINARY mode data connection for manual-1.0.ps.Z (102073 bytes).226 Transfer complete.
local: manual-1.0.ps.Z remote: manual-1.0.ps.Z
102073 bytes received in 1 seconds (1.6e+02 Kbytes/s)
ftp> quit
221 Goodbye.
% uncompress manual-1.0.ps.Z
% lpr manual-1.0.ps

A compressed version of the TeX "dvi" file is also available for
retrieval (manual-1.0.dvi.Z) for printers with different sized fonts
(eg. 600dpi).

Stephen M. Omohundro                               
International Computer Science Institute           Telephone: 510-643-9153
1947 Center Street, Suite 600                            Fax: 510-643-7684
Berkeley, CA 94704                             Email: om@icsi.berkeley.edu
 
--------clip------clip-------clip--------clip-----

...............................................................................
Ari Huttunen