CSE 505 Lecture Notes:
Smalltalk
October 14, 1994
Background
Smalltalk-72 originally developed as a language for the Dynabook
(1977 article: describes fonts, painting programs, animation, computer
music, simulation, mouse, ...)
developed by Learning Research Group at Xerox Palo Alto Research Center in
the 70's and early 80's
some principal players: Alan Kay, Dan Ingalls, Adele Goldberg
metaphor for programming the Dynabook: simulation
(other metaphor that was considered: information retrieval)
Characteristics of Smalltalk-72:
- interpreted
- extensible syntax:
fred move up x inches
- more object-oriented than Simula -- even integers are objects
- 'class' is an object (but a rather special one). No subclassing
Characteristics of Smalltalk-80:
- everything is an object, even classes, blocks (closures), activation
records, etc.
- classes can have subclasses
- not statically typed
- rich programming environment
- definitely no longer a programming language for kids!
Smalltalk-80 is now a commercial product (ParcPlace Systems, Digitalk,
Object Technology International), and a hot item on Wall Street and the MIS
world
If you have time, read an account of the the social and
political history of Simula and Smalltalk, by clicking
here.
Smalltalk influenced the development of other object-oriented languages, such
as C++, Objective C, CLOS, Beta, Trellis/Owl, Emerald,
Self
Running Smalltalk
To run Smalltalk on a SPARCstation in CSE:
Set up your display variable correctly. For example, if you are on host
mollusc, and running Smalltalk on the machine norge, on mollusc type
xhost +norge
and on norge type
setenv DISPLAY mollusc:0
After getting the display set up correctly, execute this:
/var/mnt/visual/bin/st80 /var/mnt/visual/image/visual.im
After Smalltalk starts up, inside the "installation workspace" change the
code that says SourceFileManager default ... to:
SourceFileManager default
file: 1 name: '/var/mnt/visual/image/visual.sources' writable: false;
file: 2 name: 'st80.changes' writable: true.
i.e. change where the source file is found. (This is a file with all the
source code in the system; the system browser uses this.) This will also
put a file st80.changes in your
directory, which keeps track of your modifications and additions to the
system.
When you exit, you can save your work by picking "quit" in the Launcher,
then "save then quit" in the submenu.
If there are problems running on the Suns, we can also get accounts on
the MSCC Macintoshes in the basement of Thompson.
Language Overview
Basic concepts:
- objects
- instances
- classes
- messages and methods
Syntax:
- unary messages
examples: "new", "copy"
Date today Time now hours
Array new someCollection copy
- keyword messages
examples: new:, at:, at: put:
Array new: 10
someArray at: 1 put: 54
anArray at: 1
- binary messages -
examples: + - * /
5 * 9, 3 + 2 * 5
Precedence:
- unary>binary>keyword, left-to-right within same kind,
- parentheses override
- Question: What is the value of 3 + 2 * 5 ?
25, NOT 13
Use parens to get what you want: 3 + (2 * 5)
Example 1: Stack
Object subclass: 'Stack'
instanceVariables: 'store top'
push: item
top := top+1.
store at: top put: item
pop | item |
item := store at: top.
top := top-1.
^ item
setsize: n
store := Array new: n.
top := 0.
Adding error checking and growing:
push: item
| save |
top := top+1.
top > store size ifTrue:
"store is about to overflow. make a new array twice as big, and
copy the old values into it"
[save := store.
store := Array new: 2*save size.
1 to: save size do:
[:k | store at: k put: (save at: k)]].
store at: top put: item
pop | item |
self isEmpty ifTrue: [self error: 'trying to pop an empty stack'].
item := store at: top.
top := top-1.
^ item
isEmpty
^ top=0
This example is stored on /homes/june/borning/smalltalk/Stacks.st
To file it in to your Smalltalk image, copy it to your directory and evaluate:
(Filename named: 'Stacks.st') fileIn.
Smalltalk Environment
- Browsers
- System Browser
- Class Categories, Classes, Method Categories, Methods, text pane
- Menus Launcher
- "yellow": On Macs, option-mouse click or click in caret window
- "blue" : On Macs, command-mouse click (the "clover" button)
- Workspace
- Examples to look at - Point, Rectangle
Message lookup
Object
\
\
Window
\
\
PanedWindow
Object
printOn: stream
...
----------
Window
show
self drawBorder.
self showTitle.
drawBorder
....
showTitle
....
__________
PanedWindow
show
super show.
self showPanes.
showPanes
...
Control structures
All control structures are done with blocks (closures) and message passing
This is characteristic of pure object-oriented languages, but not of hybrid
languages
Object
|
|
Boolean
/ \
/ \
True False
| |
| |
true false
True
printOn: stream
stream nextPutAll: 'true'
& b "evaluating and"
^ b
| b "evaluating or"
^ true
not
^ false
and: block "short-circuit and"
^ block value
or: block "short-circuit or"
^ true
False
printOn: stream
stream nextPutAll: false'
& b "evaluating and"
^ false
| b "evaluating or"
^ b
not
^ true
and: block "short-circuit and"
^ false
or: block "short-circuit or"
^ block value
Examples of Boolean expressions:
(3=4) & (2>1)
(3=4) | (2>1)
(3=2) not
true & false not
(3=4) and: [(1/0) = 8]
Conditionals
True
ifTrue: block
^ block value
ifFalse: block
^ nil
ifTrue: tBlock ifFalse: fBlock
^ tBlock value
False
ifTrue: block
^ nil
ifFalse: block
^ block value
ifTrue: tBlock ifFalse: fBlock
^ fBlock value
Examples of Conditionals:
3=4 ifTrue: [x := 10].
x=y ifTrue: [x := 8] ifFalse [x := 9].
x := x=y ifTrue: [8] ifFalse [9].
Loops
a := 1.
[a < 10] whileTrue: [Transcript show: a. a := a+1].
a := 1.
[a > 10] whileFalse: [Transcript show: a. a := a+1].
1 to: 10 do: [:x | Transcript show: x].
How to define whileTrue (not really done this way, though):
Block
whileTrue: otherBlock
self value ifTrue: [otherBlock value. self whileTrue: otherBlock].
whileFalse: otherBlock
self value ifFalse: [otherBlock value. self whileTrue: otherBlock].
User-defined control structures
Block
repeatUntil: testBlock
self value.
testBlock whileFalse: [self value].
Most common use: iterating over a collection of some sort
Collection
|
_______________|__________________
/ / \ \
Array Set Dictionary SortedCollection
|
|
String
Collection
copy
"evaluate aBlock for each element"
do: aBlock
"like Lisp mapcar -- make a new collection by applying aBlock to each
element and collecting the results"
collect: aBlock
"return a new collection of the elements that pass the test"
select: aBlock
"return a new collection of the elements that fail the test"
reject: aBlock
"like Miranda foldr"
inject: startValue into: binaryBlock
Most of these can be defined in Collection and inherited:
collect: aBlock
| newCollection |
"make a new collection of the same class as me"
newCollection := self class new.
self do: [:x | newCollection add: (aBlock value: x)].
^ newCollection
select: aBlock
| newCollection |
"make a new collection of the same class as me"
newCollection := self class new.
self do: [:x | (aBlock value: x) ifTrue: [newCollection add: x]].
^ newCollection
inject: startValue into: binaryBlock
| result |
result := startValue.
self do: [:x | result := binaryBlock value: result value: x].
^ result
Examples:
a := #(3 4 5 6). "an array literal"
"this is the same as
a := Array new: 5.
a at: 1 put: 3.
a at: 2 put: 4. etc. "
a collect: [:j | j+10] "this returns (13 14 15 16)"
a select: [:j | j>4] "this returns (5 6)"
a inject: 0 into: [:a :b | a+b] "this returns 18"