Basic Smalltalk

Message types.

Unary Messages 1 negated This says receiver 1 gets the message negated
Binary Messages 2 + 3 The receiver is 2, + is the selector and 3 is the argument
Keyword 2 between: 4 and: 5 Selectors between: and: arguments 4 and 5

This is how a Smalltalk workspace is used to evaluate expressions.

Examples of Messages

The is no operator precedence so 2 + 3 * 4 is 20 not 14
Messages have the following precedence

  1. unary
  2. binary
  3. keyword

so in:

 2 between: 4 and: 3 + 5 negated
5 negated is executed first, then 3 + (-5) finally the between: and: message is processed.

Work is done in the transcript or a workspace. Things that can be done are Doit, Showit, or InspectIt. These choices are in the Smalltalk menu, but only Doit and Showit popup directly on a right button. They are still available under the submenu Smalltalk. The inspect function can be applied directly to an object such as 1/3. In Smalltalk, 1/3 belongs to the class Fraction and has two member parts denominator and numerator.

Classes express the operations common to a group of objects. Class names are capitalized: Integer.

Instances are objects that are members of classes: 1 2 10 are instances of Integer

The class person may be characterized by instance variables name and address. If me is an instance name is Bruce address Mielkeb@uwgb.edu.

variables can be local or global.

Instance methods. Methods contain a sequence of Smalltalk expressions.

There are 4 types of Smalltalk expressions

  1. Literals:
    #aSymbol  #(1 2 3 4)  'magic'
    Literals define an object of class Number, String, Character, Symbol or Array. #aSymbol is a symbol , #(1 2 3 4) is an array, 'magic' is a string. a symbol is a sequence of objects from the Character class which can be indexed. Symbols differ from strings in that their characters may not be changed. A symbol constant identifies the associated symbol constant. Form of a symbol constant # followed by the characters in the symbol. Each literal is unique #red is the same item everywhere.
  2. Variable Names: Smalltalk x replacementCollection By convention, variables beginning with a capital letter are global and those beginning with lower case are local variables.
  3. Message expressions:
    bag add: stream next
    100 factorial
    array at: index + 10 put: Bag new
  4. Blocks of code:
    [ :x :y | x name <  y name]

Types of equivalence

== means identical (similar to eq and eql in lisp) and = means equal (just like equal in lisp)

'red' = 'red' but not 'red' == 'red'
#red == #red as well as #red = #red
true and false are global constants but true ~= 'true' ~= #true

Messages

The class object (thus all classes) responds to the following messages

Messages for the class Number: +, -, *, /, //, \\, negated, between: and:

Boolean has the subclasses True and False that respond to &, | and other keyword messages such as and: or:, xor:, ifTrue:, ifFalse:, not and many other messages.

3 = 4 returns an instance of the class False which has single instance false. True is also a class with a single instance true.

Example of an array message,

|anArray|
anArray := #(10 15 20).
^anArray at: 1 returns 10

Cascading

3 factorial factorial factorial 
=> a large number ((3!)!)! Try it you won't believe it.
3 factorial; factorial; factorial
returns 3!

This is an example of cascaded messages, where each message is performed on the receiver (3) in sequence.

|st|
 st := 'Nice String'.
 Transcript
    nextPutAll: 'Hello World';
    cr;
    nextPutAll: st;
    space;
    nextPutAll: 3 printString
Sends:
Hello World
Nice String 3
to the transcript window. Notice that if you perform showIt on this code you get
a MDITranscript
as the value of the expression. The side effect is the output to the transcript.

Asking the system to execute Elmo is a request to create global variable Elmo and the system responds with a request "Do you want to create global variable Elmo?"

If you do create Elmo, then it appears in the dictionary Smalltalk (type Smalltalk into the workspace and InspectIt).

Compare class variables with instance variables. Airplane all airplanes have a cockPitCrew of 3 so can have a class variable cockPitCrew := 3. On the other hand while all airplanes have a capacity, this varies from plane to plane therefore capacity is an instance variable.

Dictionary

|aDictionary|

	aDictionary := Dictionary new.
	aDictionary at: 'Bruce' put: 'Mielke'.
	aDictionary at: 'George' put: 'Ruth'.

	^aDictionary at: 'George'
Evaluates as 'Ruth'.

Creating a New Class

When creating a new Subclass you are prompted with the dialog box to the right. Normally you will choose the default settings which allow you to have named instance variables. If you choose Indexed, this requires that the class contains Bytes, and that it be an array type.

The instance method printOn: aStream (or Transcript)

printOn: aStream
	aStream nextPutAll: 'Airplane flight ';
		space;
		nextPut: $#;
		nextPutAt: flightNumber printString;"change number to a string for output"

printString automatically defined when printOn is defined.

Pool Dictionary

Pool Dictionary are variable containers. All variables maintained by pool dictionaries can be accessed by the instances and the class that has the pool dictionary in its definition. They are not accessible by subclasses or their instances.

|myDictionary|

myDictionary := Dictionary new.
myDictionary 	at: 'Bruce' put: 2315;
		at: 'Bill' put: 2316.

The return value for this is 2316. If you showIt you will get 2316. If you want the whole dictionary add yourself to the end of the cascade.

myDictionary := Dictionary new 	
		at: 'Bruce' put: 2315;
		at: 'Bill' put: 2316;
		yourself.

The Rest of the Story

For a look at advanced Smalltalk topics click here.