GNU Smalltalk Reference Card
===============================================================================

==>History and Background

   Smalltalk was developed by Alan Kay and others in the 1970s and 1980s to be
   a simple, easy to use programming language.  Originally designed with the
   Dynabook in mind, an early "notebook" computer concept, Smalltalk usually
   comes with a complete development system and user interface that uses pull-
   down menus, graphics and icons.  GNU Smalltalk, written by Andrew Valencia
   and made available for free, is unusual in being line oriented and lacking
   the graphical support.  However, it is easy to use with UNIX and ordinary
   terminals and files.

   Smalltalk was first standardized in 1980 with Smalltalk-80.  Several imple-
   mentations grew out of this, including Smalltalk V and GNU Smalltalk.  Later
   implementations add concurrency and other elements.

   Smalltalk is a pure object oriented language.  Everything is an object, even
   a class!  Objects communicate by passing messages to each other.  The 
   language uses weak typing, as does LISP, so that a variable can change types
   when new values are reassigned to it.  It is usually interpreted, rather than
   compiled.

   Objects can contain instance variables and instance methods (procedures).
   No instance variables are accessible outside an object, and all interaction
   with an object is done through the instance methods.

==>Running GNU Smalltalk on niktow

   * How to start and stop a session:

        % mst -q
        >

   The prompt is >.  To quit, press CONTROL-D.  The first time you use GNU 
   Smalltalk, it builds an image file, called mst.im, which takes a while 
   (30 seconds).  Afterwards, it uses this mst.im file so loading and starting 
   is much faster (< 5 seconds).

   * To load a file into mst while it is running:
     
        FileStream fileIn: 'nameoffile' !
     
   * User initialization file:
     
        a file called ".stinit" in your home directory
    
   * Unix System commands:
     
        Smalltalk system: 'ls' !
     
   * To inspect the value of a variable:
     
        x printNl !
     
   * To create a new variable, you must first define the variable name by
     inserting it into the Smalltalk dictionary with any value:
     
        Smalltalk at: #x put: 5 !
     
     Note that the # is needed before the x.

==>Where to get more info

    There is a tutorial on GNU Smalltalk written by its creator, Andrew
    Valencia.  It is in the file:

          /usr/local/doc/HELP/PROGLANGS/SMALLTALK/tutorial

    The standard book is "Smalltalk-80: the language and its implementation"
    by Adele Goldberg David Robson, Addison-Wesley, 1983.  Bouwhuis Call 
    No. QA76.8.S635 G64 1983


==>Smalltalk Language Elements

literals (literal expressions)

   1.  numbers

          3     30.45   -5    8r377 (octal)
          16rFF  (hexadecimal)
          1.586e5   (scientific notation)

   2.  individual characters

          $a    $5    $<   $)   $$

   3.  strings of characters

          'hi there'   'use single quotes only'
          'can''t'    (this puts one single quote inside the string)

   4.  symbols

          #bill     #M63

   5.  arrays of other literal constants

          #(1 2 3)      #(('mark' 37 'buffalo') ('kathy' 28 'greeley'))


Variable names

      sequence of letters or digits beginning with a letter

      if begins with lower case letter, then it is a private variable

      if begins with upper case letter, then it is shared (may be global)


Assignment -- binds an object to a name

      x := 5

      stuff :=   #(('mark' 37 'buffalo') ('kathy' 28 'greeley'))


      x := 2 := 7


Pseudo-variable names -- special names of constant objects

      nil

      true
 
      false


Messages  (3 types)

      1.  Unary -- a single word, does NOT end in a colon, has highest preced.

              5 printNl
              Time now

      2.  Binary -- either a single character or a double character, infix
                    notation, only done left to right with no precedence of
                    * over + or any of that, only done after unary

              5 + 6 * 4
              6 <= i

      3.  Keyword -- one or more keywords, each ending in a colon, followed
                     by parameter values.  No precedence among keywords, 
                     without parentheses it is conceptually one keyword

              Array new: 5
              x at: 6 put: 'mark'

Precedence

      unary messages,
      binary messages,
      keyword messages,
      assignments or return from method (^)

Cascaded messages

      the same object can receive multiple messages if each is separated by a
      semicolon, such as

          Array new: 5; at: 1 put: 10; at: 2 put: 0


Code blocks

      A sequence of Smalltalk statements surrounded by square brackets.
      Statements are separated by period.  The last statement should NOT end
      in a period.  Execution is deferred until requested:

          x := [ index := index + 1. y := 4 ]

      X's value is the code block.  To get it execute its code block, use
      value message.

          x value

Control Structures

      Code blocks implement control structures.  Send messages to various
      objects (like a boolean object) and use an argument that is a code block:

          (x < 2) ifTrue: [ x := x + 1 ] 

      You can even send a timesRepeat message to an integer:

          5 timesRepeat: [ 'hi there' printNl ]

      There is also whileTrue: and whileFalse: messages but they are sent to
      other code blocks (because they must be executed more than once, hence
      their execution is deferred.)

          [x ~= y] whileTrue: [ x := x - 1 ]


      You can use parameters to code blocks:

          #(2 3 5 7 11) do: [:prime | sum := sum + (prime * prime) ]


                     Example of Account Classes
                     ==========================

Object subclass: #Account
     instanceVariableNames: 'balance'
     classVariableNames: ''                            
     poolDictionaries: ''                             
     category: nil !

Account comment: 'I represent a place to deposit and withdraw money' !


!Account class methodsFor: 'instance creation'!

new
   | r |
       
   r := super new.
   r init.
   ^r 
!!

!Account methodsFor: 'instance initialization'!

init
   balance := 0
!!

!Account methodsFor: 'printing'!

printOn: stream
   super printOn: stream.
   ' with balance: ' printOn: stream.
   balance printOn: stream
!!

!Account methodsFor: 'moving money'!

spend: amount
   balance := balance - amount
!

deposit: amount
   balance := balance + amount
!!


Account subclass: #Savings
    instanceVariableNames: 'interest'
    classVariableNames: ''
    poolDictionaries: ''
    category: nil !

!Savings methodsFor: 'initialization'!

init
     interest := 0.
     ^ super init
!!

!Savings methodsFor: 'interest'!
interest: amount
     interest := interest + amount.
     self deposit: amount
!
clearInterest
     | oldinterest |

     oldinterest := interest.
     interest := 0.
     ^oldinterest
!!


Account subclass: #Checking
     instanceVariableNames: 'checknum checksleft'
     classVariableNames: ''
     poolDictionaries: ''
     category: nil !

!Checking methodsFor: 'Initialization'!
init
     checksleft := 0.
     ^super init
!!

!Checking methodsFor: 'spending'!
newChecks: number count: checkcount
     checknum := number.
     checksleft := checkcount
!

writeCheck: amount
     | num |

     (checksleft < 1)
          ifTrue: [ ^self error: 'Out of checks' ].
     num := checknum.
     checknum := checknum + 1.
     checksleft := checksleft - 1.
     self spend: amount.
     ^ num
!!

                      Sample Session using Accounts above
                      ===================================

Script started on Thu Oct 20 12:08:48 1994
% mst -q
Smalltalk 1.1.1 Ready

st> FileStream fileIn: 'account.st' !
st> Smalltalk at: #a put: (Account new) !
st> Account comment !
st> a printNl !
an Account with balance: 0
st> a deposit: 125 !
st> a spend: 10 !
st> a printNl !
an Account with balance: 115
st> a deposit: 47; spend: 42; deposit: 100; printNl !
an Account with balance: 220
st> Smalltalk at: #b put: 0 !
st> b := Checking new !
st> b printNl !
a Checking with balance: 0
st> b deposit: 4000 !
st> b newChecks: 1000 count: 200 !
st> b printNl !
a Checking with balance: 4000
st> b writeCheck: 500 !
st> b printNl !
a Checking with balance: 3500
st> %
script done on Thu Oct 20 12:13:16 1994