[pe.cust.sources] Little Smalltalk Source, *New* Part 4 of 20

earlw@pesnta.UUCP (Earl Wallace) (06/13/85)

#! /bin/sh 
#
# This is an another posting of the Little Smalltalk source, the last posting
# of this source went out in 5 parts and they were too big (>200k) for most
# sites so I redid the whole mess to keep the files around the 50k range.
#
# The complete set is now 20 parts.
#
# P.S. - If you don't receive all 20 parts within 5 days, drop me a line.
#	 Also, I have the Rand sources of May 1984, if someone has a more
#	 updated copy, I'll be happy to post them (or YOU can post them :-))
# 
# -earlw@pesnta
#
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	docs/userman
#	newsletters/Makefile
#	newsletters/letter1
#	newsletters/letter2
#	newsletters/letter2.bak
#	parser/Makefile
# This archive created: Thu Jun 13 11:31:41 1985
# By:	Earl Wallace (Perkin-Elmer Data Systems Group / Customer Service)
export PATH; PATH=/bin:$PATH
if test -f 'docs/userman'
then
	echo shar: will not over-write existing file "'docs/userman'"
else
cat << \SHAR_EOF > 'docs/userman'
.TL
A Little Smalltalk
User Manual
.AU
Timothy A. Budd
.NH 1
Introduction
.PP
This manual is intended as an aid in using the Little Smalltalk system.
It is not intended to be used as an introduction to the Smalltalk
language.
Little Smalltalk is largely (with exceptions listed in a later section)
a subset of the Smalltalk-80\s-2\u*\d\s+2 language described 
.FS
* Smalltalk-80 is a trademark of the Xerox Corporation.
.FE
in [.Smalltalk blue.].
A complete description of the classes included in the Little Smalltalk system
and the messages they accept is given in Appendix 1.
.NH 1
Running the system
.PP
The Little Smalltalk system is invoked by typing the command \fBst\fP.
The system is interactive \- that is, the user types an expression at the
keyboard and the system responds by evaluating the expression and typing
the result.
For example,
typing the expression \fB3 + 4\fP results in the value \fB7\fP being 
displayed on
the output.  Execution is terminated by typing control\-D.  A sample
execution session is shown in Figure 1.
.KF
.sp
.DS B
% st
Little Smalltalk
	3 + 4
7
	^D
%
.DE
.sp
.ce
\fBFigure 1:\fP A Sample Little Smalltalk Session
.sp
.KE
.PP
Instance variables for the command level can be created by
assigning a value to a new variable name.  Thereafter that variable can
be used at the command level, although it is not known within the scope
of any method.  The variable ``last'' always contains the value
returned by the last expression typed.
Figure 2 shows the creation of a variable.
Note that the assignment arrow is formed as a two character sequence.
.KF
.sp
.DS B
.ta 5m
	newvar <\(mi 2 / 3
	newvar
0.666667
	2 raisedTo: newvar + (4 / 3)
4
	last
4
.DE
.sp
.ce
\fBFigure 2:\fP Creating Variables
.sp
.KE
.PP
The default behavior is for the value of expressions,
with the exception of assignments, to be typed
automatically as they are evaluated.
This behavior can be modified either by using the \-d flag
(see Appendix 2), or by passing a message to the pseudo
variable \fBsmalltalk\fP (see Appendix 1).
.PP
Class descriptions must be read in from files, they cannot be entered
interactively.  Class descriptions are entered using a system directive.
For example, to include a class description contained in a file named
\fBnewclass.st\fP, the following system directive should be issued:
.sp
.ce
)i newclass.st
.sp
A list of files containing class descriptions can also be given as
arguments to the st command.  The command
.DS B
%st file\s-2\d1\u\s+2 ... file\s-2\dn\u\s+2
.DE
is equivalent to the sequence
.DS B
.ta 5m
%st
Little Smalltalk
	)i file\s-2\d1\u\s+2
	...
	)i file\s-2\dn\u\s+2
.DE
.PP
A table of system directives is given in Figure 3.
.KF
.sp
.TS
center box;
l lw(3i).

)e filename	T{
Edit the named file.  The Little Smalltalk system will suspend, leaving
the user in an editor for making changes to the named file.  Upon leaving
the editor the named file will automatically be included, as if the )i
directive had been typed.
T}

)i filename	T{
Include the named file.  The file must contain one or more class descriptions.
The class descriptions are parsed, and if syntactically legal new
instances of class \fBClass\fP are added to the Smalltalk system.
T}

)l filename	T{
Load a previously saved environment from the named file.
The current values of all variables are overridden.
The file must have been created using the )s directive (below).
T}

)r filename	T{
Read the named file.  The file must contain Smalltalk statements, as
would be typed at the keyboard.  The effect is just as if the lines
of the file had been typed at the keyboard.  The file cannot contain
class descriptions.
T}

)s filename	T{
Save the current state in the named file.  The values of all variables
are saved, and can later be reloaded using the )l directive (above).
T}

)!string	T{
Execute the remainder of the line following the exclamation point
as a Unix\s-2\u*\d\s+2 command.  Nothing is done with the output of the command,
nor is the returning status of the command recorded.
T}

.TE
.sp
.ce
\fBFigure 3:\fP System Directives
.sp
.KE
.PP
Note that the )e system directive invokes an editor on a file
containing class descriptions, and then automatically includes the file
when the editor is exited.  
Classes also respond to the message \fBedit\fP, which will have the same
effect as the )e directive applied to the file containing the class
description.
Thus the typical debug/edit/debug cycle
involves repeated uses of the )e directive or the \fBedit\fP message
until a desired outcome is achieved.
The editor invoked by the )e directive can be changed by setting
the EDITOR variable in the users environment.
.NH 1
Differences between Little Smalltalk and the Smalltalk-80 system
.PP
This section describes the differences between the language accepted by
the Little Smalltalk system and the language described in
[.Smalltalk blue.].  The principal reasons for these changes are
as follows:
.IP size 6.5m
Classes which are largely unnecessary, or which could be easily
simulated by other classes (e.g. Association, SortedCollection) have
been eliminated in the interest of keeping the size of the standard
library as small as possible.  Similarly, indexed instance variables are
not supported, since to do so would increase the size of every object in
the system, and they can be easily simulated in those classes in which
they are important (see below).
.IP portability
Classes which depend upon particular hardware (e.g. BitBlt) are not included
as part of the Little Smalltalk system.  The basic system assumes nothing
more than ascii terminals.
.IP representation
The need for a textual representation for class descriptions required some
small additions to the syntax for class methods (see Appendix 3).
Similarly, the fact that classes and subclasses can be separately parsed,
in either order, forced some changes in the scoping rules for instance
variables.
.PP
The following sections describe these changes in more detail.
.NH 2
No Browser
.PP
The Smalltalk-80 Programming Environment described in [.Smalltalk orange.]
is not included as part of the Little Smalltalk system.  The Little
Smalltalk system is designed to be little, easily portable, and to
rely on nothing more than basic terminal capabilities.
.NH 2
Internal Representation Different
.PP
The internal representations of objects, including processes, interpreters,
and bytecodes, is entirely different in the Little Smalltalk system from
the Smalltalk-80 system described in [.Smalltalk blue.].  
.FS
* Unix is a trademark of Bell Laboratories.
.FE
.NH 2
Fewer Classes
.PP
Many of the classes described in [.Smalltalk blue.] are not included as
part of the Little Smalltalk basic system.  Some of these are not
necessary because of the decision not to include the editor, browser,
and so on as part of the basic system.  Others are omitted in the interest
of keeping the standard library of classes small.  A complete list
of included classes for the Little Smalltalk system is given in Appendix 1.
.NH 2
No Class Protocol
.PP
Protocol for all classes is defined as part of class \fBClass\fP.
It is not possible to redefine class protocol as part of a class description,
only instance protocol.
.NH 2
Cascades Different
.PP
The semantics of cascades has been simplified and generalized.
The result of a cascaded expression is always the result of the expression
to the left of the first semicolon, which is also the receiver for each
subsequent continuation.  Continuations can include multiple messages.
A rather nonsensical, but illustrative, example is the following:
.DS B
2 + 3 ; \(mi 7 + 3 ; * 4
.DE
.LP
The result of this expression is 5 (the value yielded by 2 + 3).  5 is also
the receiver for the message \(mi 7, and that result (\(mi2) is in turn the
receiver for the message + 3.  This last result is thrown away.  5 is then
again used as the receiver for the message * 4, the result of which is also
thrown away.
.NH 2
Instance Variable Name Scope
.PP
In the language described in [.Smalltalk blue.], an instance variable is
known not only to the class protocol in which it is declared, but is also
valid in methods defined for any subclasses of that class.
In the Little Smalltalk system an instance variable can be referenced only
within the protocol for the class in which it is declared.
.NH 2
Indexed Instance Variables
.PP
Implicitly defined indexed instance variables are not supported.
In any class for which these are desired they can be easily simulated by
including an additional instance variable, containing an Array, and
including the following methods:
.DS B
.ta 4m 8m
Class Whatever
| indexVars |
[
	new: size
		indexVars <\(mi Array new: size

|	at: location
		\(ua indexVars at: location

|	at: location put: value
		indexVars at: location put: value

	...
.sp
.DE
.PP
The message new: can be used with any class, with an effect similar to
new.  That is, if a new instance of the class is created by sending the
message new: to the class variable, the message is immediately passed 
on to the new instance, and the result returned is used as the result of
the creation message.
.NH 2
No Pool Variables
.PP
The concept of pool variables is not supported.  
In their place there is a new pseudo-variable, \fBsmalltalk\fP, which
responds to the messages \fBat:\fP and \fBat:put:\fP.
The keys for this collection can be arbitrary.
Although this facility is available, its use is often a sign of poor
program design, and should be avoided.
.NH 2
No Associations
.PP
The class Dictionary stores keys and values separately, rather than
as instances of Association.  The class Association, and all messages
referring to Associations have been removed.
.NH 2
Generators in place of Streams
.PP
The notion of stream has been replaced by the slightly different notion of
\fIgenerators\fP, in particular the use of the messages \fIfirst\fP 
and \fInext\fP in subclasses of \fBCollection\fP.
External files are supported by an explicit class \fBFile\fP.
.NH 2
Primitives Different
.PP
Both the syntax and the use of primitives has been changed.
Primitives provide an interface between the Smalltalk world and the
underlying system, permitting the execution of operations that cannot be
specified in Smalltalk.  In Little Smalltalk, primitives cannot fail and
must return a value (although they may, in error situations, print an error
message and return \fBnil\fP).
The syntax for primitives has been altered to permit the specification of
primitives with an arbitrary number of arguments.  The format for a
primitive call is as follows:
.DS B
<primitive \fBnumber\fP \fIargumentlist\fP >
.DE
Where \fBnumber\fP is the number of the primitive to be executed
(which must be a value between 1 and 255),
and \fIargumentlist\fP is a list of Smalltalk primary expressions (see
Appendix 2).  Appendix 4 lists the meanings of each of the currently
recognized primitive numbers.
.NH 2
Byte Arrays
.PP
A new syntax has been created for defining an array composed entirely of
unsigned integers in the range 0-255.  These arrays are given a very
tight encoding.  The syntax is a pound sign, followed by a left square
brace, followed by a sequence of numbers in the range 0 to 255, followed by
a right square brace.
.DS B
#[ \fInumbers\fP ]
.DE
.LP
Byte Arrays are used extensively internally.  They have no user protocol.
.NH 2
New Pseudo Variables
.PP
In addition to the pseudo variable \fBsmalltalk\fP already mentioned,
another pseudo variable, \fBselfProcess\fP, has beed added to the Little
Smalltalk system.  \fBselfProcess\fP returns the currently executing process,
which can then be passed as an argument to a semaphore, or
be used as a receiver for a message valid for class \fBProcess\fP.
Like \fBself\fP and \fBsuper\fP, \fBselfProcess\fP cannot be used at 
the command level.
.[]
.ds CH
.bp
.SH
.ce 2
Appendix 1
Class Descriptions
.PP
The messages accepted by the classes included in the Little Smalltalk
standard library are described in the following pages.  
A list of the classes
defined, where indentation is used to imply subclassing, is given below:
.DS I
.ta 3m 6m 9m 12m 15m
Object
	UndefinedObject
	Symbol
	Boolean
		True
		False
	Magnitude	
		Char
		Number
			Integer
			Float
		Radian
		Point
	Random
	Collection
		Bag
		Set
		KeyedCollection
			Dictionary
				Smalltalk
			File
			SequenceableCollection
				Interval
				LinkedList
					Semaphore
				File
				ArrayedCollection
					Array
					String
	Block
	Class
	Process
.DE
.PP
In the descriptions of each message the following notes may occur:
.IP \fId\fP
Indicates the effect of the message differs slightly from that given
in [.Smalltalk blue.].
.IP \fIn\fP
Indicates the message is not included as part of the language defined
in [.Smalltalk blue.].
.IP \fIr\fP
Indicates the protocol for the message overrides a protocol given in
some superclass.  Only where the logical effect of this overriding is
important is the message given a second time; some messages, such as
copy, are overridden in many classes but are not described in the documentation 
because the logical effect remains the same.
.bp
.SH
.ce 2
Appendix 2
Man Page
.PP
A Unix man page for the st command is given on the following page.
.bp
.SH
.ce 2
Appendix 3
Syntax Charts
.PP
Syntax charts for the language accepted by the Little Smalltalk system
are described on the following pages.
The following is an example class description:
.DS B
Class Set :Collection
| dict |
[
        new
                dict <\(mi Dictionary new

|       add: newElement
                dict at: newElement 
                     ifAbsent: [dict at: newElement put: 1]

|       remove: oldElement ifAbsent: exceptionBlock
		dict removeKey: oldElement ifAbsent: exceptionBlock

|       size
                \(ua dict size

|       occurrencesOf: anElement
                \(ua dict at: anElement ifAbsent: [0]

|       first
                dict first.
		\(ua dict currentKey

|       next
                dict next.
		\(ua dict currentKey

]
.DE
.bp
.SH
.ce 2
Appendix 4
Primitive Numbers
.PP
The following chart gives the function performed by each primitive in the
Little Smalltalk system.
.SH
Information about objects
.IP 0
(not used )
.IP 1
class of an object
.IP 2
superobject of an object
.IP 3
test if class responds to new
.IP 4
size of object
.IP 5
hash value 
.IP 6
test if two built-in objects are of the same type
.IP 7
object equality testing ( == )
.IP 8
various switch toggles
.IP 9
numerical generality testing
.SH
Integer manipulation
.IP 10
integer addition (both args must be integer)
.IP 11
integer subtraction
.IP 12
integer < test
.IP 13
integer > test
.IP 14
integer \(<= test
.IP 15
integer \(>= test
.IP 16
integer = test
.IP 17
integer ~= test
.IP 18
integer multiplication
.IP 19
not used
.SH
Bit manipulation and other integer valued functions
.IP 20
gcd:
.IP 21
bitAt:
.IP 22
bitOr:
.IP 23
bitAnd:
.IP 24
bitXor:
.IP 25
bitShift:
.IP 26
radix:
.IP 27
not used
.IP 28
integer quo:
.IP 29
integer rem:
.SH
Other integer functions
.IP 30
doPrimitive:withArguments: 
.IP 31
not used
.IP 32
convert random integer to random float
.IP 33
bitInvert
.IP 34
highBit
.IP 35
randomNumber (argument is seed )
.IP 36
asCharacter
.IP 37
asString
.IP 38
factorial
.IP 39
asFloat
.SH
Character manipulation
.IP 40
not used
.IP 41.
not used
.IP 42
character < test
.IP 43
character > test
.IP 44
character \(<= test
.IP 45
character \(>= test
.IP 46
character = test
.IP 47
character ~= test
.IP 48
not used
.IP 49
not used
.SH
Character unary functions
.IP 50
digitValue
.IP 51
isVowel
.IP 52
isLetter
.IP 53
isLowerCase
.IP 54
isUpperCase
.IP 55
isSeparator
.IP 56
isAlphaNumeric
.IP 57
caseShift
.IP 58
asString
.IP 59
asciiValue
.SH
Floating point manipulation
.IP 60
floating point addition (both args must be float)
.IP 61
floating point subtraction
.IP 62
floating point < test
.IP 63
floating point > test
.IP 64
floating point \(<= test
.IP 65
floating point \(>= test
.IP 66
floating point = test
.IP 67
floating point ~= test
.IP 68
floating point multiplication
.IP 69
floating point division
.SH
Other floating point operations
.IP 70
ln
.IP 71
sqrt
.IP 72
floor
.IP 73
ceiling
.IP 74
not used
.IP 75
integerPart
.IP 76
fractionalPart
.IP 77
gamma
.IP 78
asString
.IP 79
exp
.SH
Other numerical functions
.IP 80
normalize number to be within 0 and 2\(*p.
.IP 81
sin 
.IP 82
cos
.IP 83
not used
.IP 84
arcSin
.IP 85
arcCos
.IP 86
arcTan
.IP 87
not used
.IP 88
raisedTo:
.IP 89
radix:
.SH
Symbol Commands
.IP 90.
not used
.IP 91
symbol comparison, returns true or false.
.IP 92
printString
.IP 93
asString
.IP 94
print (used internally)
.IP 95
not used
.IP 96
not used
.IP 97
build a new class, arguments are class name, superclass name, instance
variables, messages, methods, context size.
.IP 98
insert an object into class dictionary, first argument is symbol,
second argument is class definition
.IP 99
find an object in class dictionary.  argument is symbol.
.SH
String operations
.IP 100
string length
.IP 101
string compare, case important \- return \(mi1, 0 or 1.
.IP 102
string compare, case not important
.IP 103
string catenation
.IP 104
string at:
.IP 105
string at:put:
.IP 106
copyFrom:length: 
.IP 107
copy (new string with same chars)
.IP 108
asSymbol
.IP 109
string printString
.SH
Array manipulation
.IP 110
build an untyped object of given size, argument is integer size. 
.IP 111
index variable get (first argument is object, second is index)
.IP 112
index variable put (first argument is object, second is index, 
third argument is expression)
.IP 113
object grow (returns a new object with same instance variable values
as first argument, but with second argument tacked on end as new instance variable)
.IP 114
build an instance of \fBArray\fP of the given size. 
.IP 115
new string of given size 
.IP 116
not used
.IP 117
not used
.IP 118
not used
.IP 119
not used
.SH
Output and error messages
.IP 120
print string with no return
.IP 121
print string with return
.IP 122
general error - first argument is receiver, second is error string
.IP 123
print string on error output (with return)
.IP 124
not used
.IP 125
unix system call 
.IP 126
not used
.IP 127
block return without surrounding context
.IP 128
reference count less than zero, first argument is guilty object 
.IP 129
does not respond error, first argument is receiver, second is message. 
.SH
File operations
.IP 130
file open, first argument is name, second argument is mode
.IP 131
file read
.IP 132
file write
.IP 133
set file mode, first argument is file, second is mode indicator (anInteger)
.IP 134
compute file size in bytes
.IP 135
file set location (at:) second argument is location (anInteger)
.IP 136
return current file offset in bytes
.IP 137
not used
.IP 138
not used
.IP 139
not used
.SH
Process management
.IP 140
block execute (trapped by interpreter)
.IP 141
new process (withArguments:) 
.IP 142
terminate a process
.IP 143
perform:withArguments: (trapped by interpreter)
.IP 144.
not used
.IP 145
set state
.IP 146
return state
.IP 148
start atomic action
.IP 149
end atomic action
.SH
Operations on classes
.IP 150
class edit
.IP 151
superclass of a class
.IP 152
class name (a Symbol)
.IP 153
new instance of a class
.IP 154
list all commands class responds to
.IP 155
respondsTo: , second argument is a symbol
.IP 156
class view (drop into editor, but no include)
.IP 157
class list
.IP 158
variables (returns an array of symbols)
.IP 159
not used
.SH
Date and Time
.IP 160
current date and time as string
.IP 161
seconds time counter
SHAR_EOF
if test 19526 -ne "`wc -c < 'docs/userman'`"
then
	echo shar: error transmitting "'docs/userman'" '(should have been 19526 characters)'
fi
fi # end of overwriting check
if test -f 'newsletters/Makefile'
then
	echo shar: will not over-write existing file "'newsletters/Makefile'"
else
cat << \SHAR_EOF > 'newsletters/Makefile'
l1: letter1
	itroff -ms letter1

l2: letter2
	pic letter2 | tbl | eqn | ditroff -ms

SHAR_EOF
if test 85 -ne "`wc -c < 'newsletters/Makefile'`"
then
	echo shar: error transmitting "'newsletters/Makefile'" '(should have been 85 characters)'
fi
fi # end of overwriting check
if test -f 'newsletters/letter1'
then
	echo shar: will not over-write existing file "'newsletters/letter1'"
else
cat << \SHAR_EOF > 'newsletters/letter1'
.SH
\s20Little Smalltalk Update\s0
.PP
In the first month of distribution copies of the Little Smalltalk system
have been sent out to over 50 sites.  Currently it is reported that
attempts are being made to port the system to the following machines.
Numbers in parenthesis indicate the number of sites using the machine,
while asterisk indicates at least one successful port has been reported.
.DS L
.ta 2i 4i
* AT&T 3B2 (2)	* Ahmdal (1)	Altos 8600 (1)
Arete 1100 (1)	CRD 68/35 (1)	DecPro 350 - P/Os (1)
* DecPro 350 - Venix (1)	Fortune 32:16 - SYS III (2)	HP 3000 (1)
* HP 9000 (1)	IBM PC - DOS 3.0 (1)	Macintosh (1)
Masscomp MC 500 (1)	Metheus Lambda 4.2 (1)	* PDP 11/70 - Berkeley 2.9 (3)
PDP 11/70 - Sys V (1)	Perkin Elmer 8/32 (1)	Pyramid 90x (2)
* Ridge (2)	VAX 750 - 8th Edition (1)	* VAX 750 - Berkeley 4.2 (7)
* VAX 780 - Berkeley 4.2 (21)	VAX 780 - SYS V (3)	VAX 780 ULTRIX (1)
.DE
.PP
If you have the Little Smalltalk system, and have been able to successfully
port it to a system I have not indicated here, please send me an electronic
note indicating what difficulties (if any) you may have encountered.
.SH
BUGS
.PP
Unfortunately, there were also in this first month a number of BUGS
reported, and some enhancements made to the system.  There were three major
bugs: command lines containing pseudo variables did not work correctly, the
arbitrary radix form of numbers was not recognized correctly, and the
system could get into an infinite loop if an error was encountered during a
fastsave.  There were also a fair number of less critical bugs reported and
fixed.  (The class SmallTalk should have been Smalltalk, various error
messages were wrong, the parser would sometimes core dump on incorrect
programs, and linked lists could sometimes get into an infinite loop).
Finally there were several enhancements made to improve the functionality
of the system.
.PP
The attached sheet shows the date each one of these changes was made in the
distribution version of the software.  You can compare this date to the
date shown on your distribution tape - all changes with earlier dates will
be reflected in your copy of the software.
.PP
As a policy, those individuals who have obtained a copy of Little Smalltalk
by earlier sending a check for $15 can obtain the lastest distribution 
\fIfree\fP by merely returning a magnetic tape on which to copy the software.
.SH
Installation Notes
.PP
The installation notes distributed along with the Little Smalltalk system
were greatly expanded during this first month in reponse to questions and
difficulties encountered in installating the system on various machines.
Sections were added on fast loading, protections, trouble shooting and
further distribution.  Since many of you received your distribution before
these sections were written, they are reprinted here below.
.SH
Fast Loading
.PP
The Little Smalltalk system has the ability to save and restore a user
environment by basically moving a copy of all of the users data space into
a file.  Although this produces rather large files, the savings in time
permitted by not having to recreate a specific environment can be
substantial.  Because this is such an unusual thing to do, it is probably
wise, if installing the system on a new machine/operating system, to first
comment out the define for FASTDEFAULT in parser/env.h, 
which will install a system which will not default to doing a fast load.
.PP
Once such a system has been created and passed all self tests, you can
experiment with fast loading by executing the st command with the argument
\-f.  For test cases you can use the programs in /tests.  If it appears to
be successful, then (by defining the variable FASTDEFAULT) you should
regenerate the system so that the default behavior is to do a fast loading.
(When regenerating the system, sources/main.c should be the only file
needing to be recompiled).
.PP
Fastloading does not currently work on the HP-9000, or the DEC-pro 350.
It may not work on other machines as well.
.SH
Protections
.PP
The directories /sources and /parser need not be readable by casual users.
The directory /prelude contains files, however, which must be loaded by
the Little Smalltalk system prior to every execution.  The protection of this
directory, and on the files in it, should therefore be such that all users
have READ access.
Although the /tests directory is only used during system installation,
users may want to refer to it for examples of class descriptions and to see
how various problems (8 queens, dinning philosophers) have been solved in
Smalltalk.
Allowing all users access to the /docs directory will permit a kind of
on-line access, however users should not be allowed to modify any files in
any directory.
.SH
Troubleshooting
.PP
Here are a few of the problems you might run into, and possible solutions:
.PP
The first thing to suspect if you observe strange behavior is the
fastloading feature.  Try running the system with the \-m flag, which will
turn off fastloading.  For example, on the 11/70 fastloading will inhibit
the )i command from working correctly, but no error messages will be
generated.  The appearance of a message such as ``\fIxxx\fP: is not 
an identifier'', or of can't happen message number 23
is also a clue that fastloading does not work and should be disabled.
Similarly, the appearance of the message ``no such context as:
\fIxxx\fP/stdsave'' during startup is an indication that the file
containing the saved binary form of the standard prelude either does not
exist or is unreadable, or that the path given in parser/env.h is wrong.
.PP
Solutions to problems with fastloading are to try to 
to recreate the stdsave file in /prelude, or as a last resort to remove the
definition for FASTDEFAULT from /parser/env.h and recompile everything.
This latter step will configure a system that will not attempt fastloading
unless explicitly called for.
.PP
If the function _gamma is undefined following load for st.  Solution: remove
the definition for the symbol GAMMA and recompile.
.PP
No output appears when you start the program, and if you type control-D all
the output appears.  Solution: define the symbol FLUSHREQ and recompile.
.PP
Can't happen number 22 - either TEMPFILE is unreadable, or
/prelude/standard does not exist.
.PP
Systems that have trouble with long lines may have difficulty with the file
syms.c in /sources (there is one line in that file over 300 characters long).
If necessary, this file can (and will be) automatically reconstructed from
other files in the directory.
.PP
Receiving error number 129 whenever any non-primitive class method is
called may be a symptom of a clash of variable names.  On older systems the
variables runningProcess and runningInterpreter would clash on systems that
did not support long variable names.  The variable runningInterpreter (in
process.c) has since been changed to presentInterpreter, so this problem
should not occur in software taken from more recent distribution tapes.
.SH
Further Distribution
.PP
The Little Smalltalk system is public domain, and may be distributed
further as long as proper attribution is given in all published references.
.PP
In the interests of keeping the distribution up to date and as error free
as possible, we wish to keep track of known sites using the
system.  People interested in being placed on the mailing list for future
bug announcements and new version announcements should contact Professor
Budd.  Changes, modifications, or improvements
to the code or the standard library can be submitted also, and will be
considered for inclusion in future distributions.
SHAR_EOF
if test 7613 -ne "`wc -c < 'newsletters/letter1'`"
then
	echo shar: error transmitting "'newsletters/letter1'" '(should have been 7613 characters)'
fi
fi # end of overwriting check
if test -f 'newsletters/letter2'
then
	echo shar: will not over-write existing file "'newsletters/letter2'"
else
cat << \SHAR_EOF > 'newsletters/letter2'
.ds CM
.SH
\s+9Little Smalltalk Update, Number 2\s0
.PP
The good news is that Little Smalltalk has now been distributed to over 100 
sites; and that it appears to port rather easily to anything calling itself
Unix.  The bad news is that with so many sites running the software there
were bound to be a few bugs reported.  There were.  Special thanks go to
Charlie Allen of Purdue for not only locating a large number of bugs but also,
in most cases, providing fixes.  Other bugs (and, in some cases, fixes) were
reported by Jan Gray of Waterloo and Charles Hayden of AT&T.
.PP
The major bugs fixed since the last update include the following:
.RS
.IP
The bug that was causing the fast save routines to fail
on the PDP 11/70 and other
16 bit machines was located and fixed (the environment variable was being
trashed).
.IP
Bases were not being checked properly on the ``radix:'' message in classes
Integer and Float.  A base of zero or one would cause an infinite loop or
core dump.  A message is now produced in these cases.
.IP
The confusion over whether instances of Dictionary should return a value or
a point in response to first and next was resolved in favor of a value.
Various locations using instances of Dictionary were affected by this.
.IP
The pseudo variable smalltalk was being improperly initialized, and would
not respond to at: or at:put:.  This has been changed.
.IP
Empty arrays have been fixed to print correctly.
.IP
The message at:put: in class String has been fixed to work properly.
.IP
Bags and Sets have been fixed to print properly.
.IP 
An error in computing the hash value of a Symbol was found and fixed.
.IP
An error in computing relations between Points was fixed.
.IP
In various places in Collection and subclasses the message == was used
where = should have been used.
.RE
.PP
In addition, the following changes/enhancements were made:
.RS
.IP
An exit was added at the end of main.
.IP
The message ``perform:withArguments:'', which permits messages to be
constructed at run time, was implemented in class Smalltalk.
.IP
A backtrace routine was added so now when a message is not understood by a
receiver not only is an error message printed but a list of messages 
that were executed leading up to the point of error is printed.
.IP
The process manager was revised and cleaned up.
.IP
Hashing was changed so that the modular division is now done in Smalltalk
rather than in the primitive.
.IP
The message ``variables'' was added to class Class.  This message returns
an array of symbols representing the names of instance variables defined in
the class.
.IP
The mode setting messages for class File were changed from ``asInteger''
(for example) to ``integerMode''.
.IP
Several messages were added to class Random, including ``randomize'' (by
default instances of class Random return the same pseudo-random sequence),
\&``randInteger:'' (return a random integer in a given range), and
\&``between:and:'' (return a random floating value in a given range).
.IP
The message ``asDictionary'' (which converts a collection into a Dictionary)
was added to class KeyedCollection.
.IP
The message ``doPrimitive:withArguments:'' was moved from class Object to
class Smalltalk.
.IP
The unary looping messages ``whileTrue'' and ``whileFalse'' were added to
class Block.  (A program illustrating the use of whileFalse is given in the
``programming corner'' at the end of this newsletter).
.IP
The message ``date'', returning the current date and time,
was added to class Smalltalk.
.IP
A primitive was added to gain access to the low order bits of the Unix
clock, which is accurate to one second.  With this, the message ``time:''
was added to class Smalltalk.  This message executes a block and returns
the elapsed time, to within one second.
.IP
Instances of class ByteArray were given protocol and made accessible to the
user, in addition to being used extensively internally in the Little
Smalltalk system.
.RE
.PP
The source for these changes is too large to report here.  However, as
we announced in the last newsletter, as long as changes and bug fixes
continue to be relatively common,
anybody who has paid for the distribution tape can obtain
the latest sources by merely sending a blank tape back to
the University of Arizona at the address given below.
.SH
Machines
.PP
To date, successful ports of the Little Smalltalk system have been reported
on the following machines:
.DS I
Amdahl
AT&T 3B2
DecPro 350 (running Venix)
HP 9000
IBM PC/IX (running Unix)
Perkin Elmer (type not known)
PDP 11/70 and 11/44
Pyramid 90x
Ridge
Sequent
Vax 780 and 750, both 4.2 and Sys V
.DE
.PP
If you have the Little Smalltalk system running on some machine not listed
here, we would be interested in hearing about it.
.SH
Programs Wanted
.PP
A textbook is currently under development describing the 
Little Smalltalk language and its implementation.
The book will be divided into two parts, the first of which will describe
the language, and could be used in, say, a comparative programming course.
The second part will describe in detail the implementation, and could be
used in an upper division undergraduate or graduate level seminar on very
high level language implementation.
.PP
As part of the effort of writing this book, we would be most interested in
acquiring any unique or interesting applications developed using 
the Little Smalltalk system.
These would be considered for use as examples (with appropriate
acknowledgments, of course) or as suggested projects for students to
develop.
Also programs are solicited for the Programming Corner (below).
.SH
Rising Costs
.PP
Due to the increased cost of magnetic tapes and postage,
it is unfortunately the case that we
must raise the price for the Little Smalltalk system from $15 to $20.
Distribution tapes for the Little Smalltalk system can be obtained by
sending a check for $20, made out to ``The University of Arizona'' to:
.DS I
Professor Tim Budd
Smalltalk Distribution
The Department of Computer Science
The University of Arizona
Tucson, Arizona
85721

CSNET: budd@arizona
UUCP {ucbvax, noao, ihnp4} ! arizona ! budd
.DE
.SH
Programming Corner
.PP
It is hoped that in the future these newsletters will contain fewer bug
reports and more useful information.  As an attempt to move in the latter
direction, we would eagerly like to solicit short example programs that
illustrate the power or utility of Smalltalk. 
Please send any programs you would like us to consider, along with a short
written description, to the address given above.
.PP
This time we will illustrate the use of \fIgenerators\fP in Smalltalk.
We define a generator to be any object that produces a sequence of values
in response to the messages \fIfirst\fP and \fInext\fP.  
In response to either of these message
the value \fInil\fP is used to indicate the end of
sequence.
Generators are an
extremely powerful programming tool, and will be discussed in detail in the
forthcoming book on Little Smalltalk (discussed above).  In the Little Smalltalk
standard prelude (the set of classes included at the start of execution)
there are many instances of generators.
All the various subclasses of Collection, for example, will respond to
first and next.  Notice, however, that there are basically two approaches
used in the subclasses of Collection.  Some objects, such as instances of
Dictionary or Array, maintain all their values in memory and merely
interate over them in response to these messages.  Instances of Interval
or Random,
on the other hand, never maintain the entire list, and produce new elements
only on demand.  It is the latter approach we will consider here.
.PP
The problem is to generate the set of prime numbers up to some fixed limit.
The algorithm used in the first program
is a variation on the sieve of Eratosthenes (see Knuth
Vol.2 pages 373-376 for a discussion of this technique).
In this program the
prime producer proceeds by first constructing a generator for the
numbers from 2 to the desired limit, using an Interval.
This generator is used to produce the first prime, the number 2.
When asked to produce the next prime, a new generator is produced by adding
a \fIfilter\fP to the previous generator.  
The filter (in this case an instance of class Factor) is given two objects;
the original generator, and a specific non-negative number.
The filter will pass inquiries back to the original
generator, but in the process filter out values that have the number
as a factor.  
.PP
Pictorially, the underlying generator can be viewed as follows:
.DS B
.PS
line <-
box "2 filter"
line <-
box "2 to: n" "generator"
.PE
.DE
.PP
Again, when asked for the next prime, the generator is once more modified by
adding a second filter, this time for the last value, the number 3.
.DS B
.PS
line <-
box "3 filter"
line <-
box "2 filter"
line <-
box "2 to: n" "generator"
.PE
.DE
.PP
The program continues, each time a new prime is requested a filter is
constructed to remove all factors of the previous prime.  In this fashion,
all the primes are eventually generated.
.PP
The code is as follows:
.DS I
Class Primes
| primeGenerator lastFactor |
[
	first
		primeGenerator \(<- 2 to: 100.
		lastFactor \(<- primeGenerator first.
		\(ua lastFactor
|
	next
		primeGenerator \(<- (Factor new ;
					remove: lastFactor
					from:   primeGenerator ).
		\(ua lastFactor \(<- primeGenerator next
]

Class Factor
| myFactor generator |
[
	remove: factorValue from: generatorValue
		myFactor \(<- factorValue.
		generator \(<- generatorValue
|
	next		| possible |
		[ (possible \(<- generator next) notNil ]
			whileTrue:
				[ (possible \e\e myFactor ~= 0)
					ifTrue: [ \(ua possible ] ].
		\(ua nil
]


.DE
.PP
By way of contrast, a second program will be presented that also generates
the list of prime numbers.  Unlike the first program, this program always
generates the \fIinfinite\fP list of primes.
(This difference is largely superficial; the first program could easily be
modified to also generate the infinite sequence by merely initializing the
internal generator with one that produces the infinite list of natural
numbers.  Similarly, we could add a specific test to halt the second
program after a given point.)
.PP
Instead of using a filter, this second program builds a recursive chain of
generators for each new number considered.
Each time a new value is requested, the value of the last prime produced is
incremented by one, and a new instance of the primes generator constructed.
If any value less than the square root of the putative prime is a factor,
the number is rejected.  Otherwise, the number is accepted and returned.
.DS I
Class Primes
| lastPrime |
[
	first
		\(ua lastPrime \(<- 2
|
	next
		[ lastPrime \(<- lastPrime + 1.
		  self testNumber: lastPrime ] whileFalse.
		\(ua lastPrime
|
	testNumber: n
		(Primes new) do: [:x | 
			(x squared > n) ifTrue: [ \(ua true ].
			(n \e\e x = 0) ifTrue: [ \(ua false ] ]
]
.DE
.PP
The method for the message \fIdo:\fP, inherited from class Object, is implemented
in terms of the messages \fIfirst\fP and \fInext\fP, and illustrates the
pervasive nature of generators in Little Smalltalk.
.PP
While the second solution is shorter and requires only one class, it tends
to be much less efficient.
A possible source for this inefficiency is the need to regenerate the list
of primes each time a number is to be tested.  To determine the effect of
this regeneration a third program was produced that kept an explicit list of the
previous primes.
.DS I
Class Primes
| prevPrimes lastPrime |
[
	first
		prevPrimes \(<- LinkedList new.
		prevPrimes add: (lastPrime \(<- 2).
		\(ua lastPrime
|
	next
		[ lastPrime \(<- lastPrime + 1.
		  self testNumber: lastPrime ] whileFalse.
		prevPrimes addLast: lastPrime.
		\(ua lastPrime
|
	testNumber: n
		prevPrimes do: [:x | 
			(x squared > n) ifTrue: [ \(ua true ].
			(n \\ x = 0) ifTrue: [ \(ua false ] ]
]
.DE
.PP
The third version was about twice as fast as the second, however it
requires significantly more space for the list of previous primes.
It was still not as efficient as the first program.
.PP
A final lesson that can be observed concerns the appropriate choce of data
structures.  I originally wrote the third program using a Set instead of a
LinkedList.  The LinkedList has the advantage of keeping the values
ordered, which is important since small values (such as 2 or 3) tend to be
factors of non-primes much more frequently than do larger values.  Since
the testNumber: loop halts when the first factor is found, the ordering can
be significant.
.PP
The following chart gives the execution time in seconds and
the number of memory reference increments and
decrements performed by the four algorithms in computing the first 300
primes.  
While the Unix clock is only accurate to within one second,
the increment/decrement count is a fairly reliable measure of
computation, since almost every operation requires at least one increment
or decrement.
.TS
center box;
l c c
l | c | r.
Program	Time (in seconds)	Reference Counts
_

1. Generator and Filters	12	199,987

2. Generators and regeneration	65	690,817

3. Generator and LinkedList	21	331,565

4. Generator and Set	168	2,032,211

.TE
SHAR_EOF
if test 13177 -ne "`wc -c < 'newsletters/letter2'`"
then
	echo shar: error transmitting "'newsletters/letter2'" '(should have been 13177 characters)'
fi
fi # end of overwriting check
if test -f 'newsletters/letter2.bak'
then
	echo shar: will not over-write existing file "'newsletters/letter2.bak'"
else
cat << \SHAR_EOF > 'newsletters/letter2.bak'
.SH
\s+9Little Smalltalk Update, Number 2\s0
.PP
The good news is that Little Smalltalk has now been distributed to over 100 
sites; and that it appears to port rather easily to anything calling itself
Unix.  The bad news is that with so many sites running the software there
were bound to be a few bugs reported.  There were.  Special thanks go to
Charlie Allen of Purdue for not only locating a large number of bugs but also,
in most cases, providing fixes.  Other bugs (and, in some cases, fixes) were
reported by Jan Gray of Waterloo and Charles Hayden of AT&T.
.PP
The major bugs fixed since the last update include the following:
.RS
.IP
The bug that was causing the fast save routines to fail
on the PDP 11/70 and other
16 bit machines was located and fixed (the environment variable was being
trashed).
.IP
The message ``perform:withArguments:'', which permits messages to be
constructed at run time, was implemented in class Smalltalk.
.IP
Bases were not being checked properly on the ``radix:'' message in classes
Integer and Float.  A base of zero or one would cause an infinite loop or
core dump.  A message is now produced in these cases.
.IP
The confusion over whether instances of Dictionary should return a value or
a point in response to first and next was resolved in favor of a value.
Various locations using Dictionarys were affected by this.
.IP
The pseudo variable smalltalk was being improperly initialized, and would
not respond to at: or at:put:.  This has been changed.
.IP
Empty arrays have been fixed to print correctly.
.IP
The message at:put: in class String has been fixed to work properly.
.IP
Bags and Sets have been fixed to print properly.
.IP
In various places in Collection and subclasses the message == was used
where = should have been used.
.RE
.PP
In addition, the following changes/enhancements were made:
.RS
.IP
An exit was added at the end of main.
.IP
The process manager was revised and cleaned up.
.IP
Hashing was changed so that the modular division is now done in Smalltalk
rather than in the primitive.
.IP 
An error in computing the hash value of a Symbol was found and fixed.
.IP
The message ``variables'' was added to class Class.  This message returns
an array of symbols representing the names of instance variables defined in
the class.
.IP
The mode setting messages for class File where changed from ``asInteger''
(for example) to ``integerMode''.
.IP
Several messages were added to class Random, include ``randomize'' (by
default instances of class Random return the same pseudo-random sequence),
\&``randInteger:'' (return a random integer in a given range), and
\&``between:and:''.
.IP
The message ``asDictionary'' was added to KeyedCollection.
.IP
The message ``doPrimitive:withArguments:'' was moved from class Object to
class Smalltalk.
.IP
The message ``date'' was added to class Smalltalk.
.IP
A primitive was added to gain access to the low order bits of the Unix
clock, which is accurate to one second.  With this, the message ``time:''
was added to class Smalltalk.  This message executes a block and returns
the elapsed time, to within one second.
.RE
.PP
The source for these changes is too large to report here.  However, as
always, anybody who has paid for the distribution tape can obtain
the latest sources by merely sending a blank tape back to us
here at the University of Arizona.
.bp
.SH
Machines
.PP
To date, successful ports of the Little Smalltalk system have been reported
on the following machines:
.DS I
Amdahl
AT&T 3B2
DecPro 350
HP 9000
IBM PC/IX
Perkin Elmer
PDP 11/70 and 11/44
Pyramid 90x
Ridge
Vax 780 and 750, both 4.2 and Sys V
.DE
.SH
Programs Wanted
.PP
A book is currently under development describing the Little Smalltalk language
and implementation.  As part of this effort, we would be most interested in
acquiring any unique or interesting applications developed using Little 
Smalltalk.  These would be considered for use as examples (with appropriate
acknowledgments, of course) or as projects in the book.
Also programs are solicited for the Programming Corner (below).
.SH
Rising Costs
.PP
Due to the increased cost of magnetic tapes and postage,
it is unfortunately the case that we
must raise the price for the Little Smalltalk system from $15 to $20.
Distribution tapes for the Little Smalltalk system can be obtained by
sending a check for $20, made out to ``The University of Arizona'' to:
.DS I
Professor Tim Budd
Smalltalk Distribution
The Department of Computer Science
The University of Arizona
Tucson, Arizona
85721
.DE
.SH
Programming Corner
.PP
The following program was contributed by Jan Gray, an undergraduate with
the Waterloo Smalltalk Project at the University of Waterloo.
The program simulates a simple Turing Machine with a one-way tape.
An example TM program is provided which merely changes a run of uppercase
I's into lowercase i's.
.nf
Class Main
[
	main			| tm |
		tm \(<- TuringMachine new initialize.
		tm delta state: 0 input: $# nextState: 1 output: $L.
		tm delta state: 1 input: $I nextState: 1 output: $i.
		tm delta state: 1 input: $i nextState: 1 output: $L.
		tm delta state: 1 input: $# nextState: 2 output: $R.
		tm delta state: 2 input: $i nextState: 2 output: $R.
		tm delta state: 2 input: $# nextState: 'halt' output: $#.
		tm tape: 'IIIIII'.
		tm delta print.
		tm run
]
Class TuringMachine
|       tape            "Infinite tape"
        state           "Current state, TM continues if state is a number"
        delta           "A TransitionTable, which for each (state, input)
                         gives (next state, output)"
        tapeMoves       "A Dictionary which maps L and R into [tape left]
                         and [tape right]"
|
[
        initialize
                tapeMoves \(<- Dictionary new.
                tapeMoves at: $L put: [tape left].
                tapeMoves at: $R put: [tape right].
                delta \(<- TransitionTable new.
                self tape: ''.
                self state: 0
|
        tape: aString
                tape \(<- Tape new with: aString
|
        state: aState
                state \(<- aState
|
        delta
                \(ua delta
|
        step
                | next |
                next \(<- delta atState: state input: tape read.
                state \(<- next state.
                (state isKindOf: Number)
                        ifTrue: [(tapeMoves includesKey: next symbol)
                                        ifTrue:  [(tapeMoves at: next symbol) value]
                                        ifFalse: [tape write: next symbol]]
|
        run
                state \(<- 0.
                self print.
                [state isKindOf: Number] whileTrue: [self step print]
|
        printString
                \(ua 'State ', state printString, ', Tape ', tape printString
]
Class Pair	:Magnitude
| state symbol |
[
        state: aState symbol: aSymbol
                state \(<- aState.
                symbol \(<- aSymbol
|
        state
                \(ua state
|
        symbol
                \(ua symbol
|
	< aPair
		\(ua state < aPair state or:
			[state = aPair state and: [symbol < aPair symbol]]
|
        printString
                \(ua state printString, '	', symbol printString
]
Class TransitionTable :Dictionary
[
        state: aState input: in nextState: nextState output: out
                self at: (Pair new state: aState symbol: in)
                     put: (Pair new state: nextState symbol: out).
		\(ua nil
|
        atState: aState input: in
                \(ua self at: (Pair new state: aState symbol: in)
                       ifAbsent: [\(ua Pair new state: 'hung' symbol: nil].
|
        print
                'State	Read	Next	Write' print.
		self binaryDo: [:x :y |
			(x printString , '	', y printString) print]
]
Class Tape :Object
| tape position |
[
        with: aString
                tape \(<- '#', aString, '#'.
                position \(<- tape size
|
        read
                \(ua tape at: position
|
        write: aChar
                tape at: position put: aChar.
|
        left
                (position > 1)
                        ifTrue: [position \(<- position - 1]
|
        right
                (position = tape size)
                        ifTrue: [tape \(<- tape, '#'].
                position \(<- position + 1
|
        printString
                \(ua (tape copyFrom: 1 to: position - 1), '{',
                  ((tape at: position) asString), '}',
                  (tape copyFrom: position + 1 to: tape size)
]
SHAR_EOF
if test 8524 -ne "`wc -c < 'newsletters/letter2.bak'`"
then
	echo shar: error transmitting "'newsletters/letter2.bak'" '(should have been 8524 characters)'
fi
fi # end of overwriting check
if test -f 'parser/Makefile'
then
	echo shar: will not over-write existing file "'parser/Makefile'"
else
cat << \SHAR_EOF > 'parser/Makefile'
CFLAGS =-O
LFLAGS =-n

BINDIR = ../bin

SOURCES = parser.y parser.lex parse1.c parse2.c
MISC = disclaim Makefile *.h y.tab.c lex.yy.c uchar.c

install: parse
	mv parse $(BINDIR)

parse: y.tab.o parse1.o parse2.o
	cc $(LFLAGS) -o parse y.tab.o parse1.o parse2.o -lm

bundle: y.tab.c lex.yy.c
	bundle $(SOURCES) $(MISC) >../parser.bundle

y.tab.o: y.tab.c lex.yy.c

y.tab.c: parser.y
	yacc -d parser.y

lex.yy.c: parser.lex
	lex parser.lex

parse2.o: parse2.c drive.h

lint.out: y.tab.c
	lint y.tab.c parse1.c parse2.c -lm

clean:
	-rm -f *.o
SHAR_EOF
if test 541 -ne "`wc -c < 'parser/Makefile'`"
then
	echo shar: error transmitting "'parser/Makefile'" '(should have been 541 characters)'
fi
fi # end of overwriting check
#	End of shell archive
exit 0