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