Overview of Smalltalk Programming
Overview of Smalltalk Programming
Smalltalk
History and significance of Smalltalk
Object-oriented programming
Smalltalk was developed at the Xerox Palo “…and I can tell you I did not have C++ in mind.”
Alto Research Center (PARC) in the early
1970’s 2004 Turing Award Winner
Alan Kay, Dan Engalls, Adele Goldberg,
Dave Robson
Delivered the Turing Lecture at OOPSLA
2004
Smalltalk 1
Object-
Object-Oriented Programming OOP
Object: encapsulates data describing Inheritance: reuse of classes by
something (often an object in the real specializing general behavior
world) as well as methods (or programs) Polymorphism: many different objects can
that manipulate that data respond to the same message
Message: communication between objects; Dynamic Binding: resolution of message
method invocations binding is deferred until runtime
Class: defines structure and common
behavior of a group of objects
Smalltalk 2
Messages and Methods Classes and Instances
Class: The abstract definition of the
Message: a request to an object to perform behavior of a class of objects
an operation (analogous to function call)
Method: implementation of an operation Instance: an individual object defined by a
(function) class
Examples of messages:
‘hello, world’ size
#(1 12 24 36) includes: 4 factorial
3 < 4 ifTrue: [‘Yes’] ifFalse: [‘No’]
Can be constants (Float pi) or even Subclasses inherit the variables and
references to existing instances, such as methods of the superclass
Students class that maintains a list of
Student instances
Smalltalk 3
The Magnitude Class Hierarchy
Inheritance in Smalltalk Magnitude
Association
Is a strict tree structure: a subclass can Character
have one and only one parent class Date
Number
Float
Subclasses usually “specialize” the more Fraction
general behavior of the parent class Integer
– Can add new variables or methods LargeInteger
SmallInteger
– can also hide inherited functionality
Time
Expressions
Smalltalk does not have a “statement” in the
Literals and Variables
sense used by procedural languages
Computation is achieved by evaluating Literals
expressions
#aSymbol #(1 2 4 16 32 64)
All expressions return an object
‘Hello, World’
Types:
– Literals
– Variable names Variables
– Message expressions Smalltalk x selectedDictionary
– Blocks of code
Smalltalk 4
Variables Public and Private Variables
Names are syntactically similar to other Public variables are shared and visible
languages globally
All variables are pointers to objects Name begins with upperclass letter
All variables are inherently typeless Private variables are local to an object,
No difference between pointing to the number block or method
42 and pointing to an instance of a text editor – Name begins with lowerclass letter
– Accepting the single object returned as the array at: 1 put: self
“message answer”
Smalltalk 5
Selector Evaluation Order Cascading Messages
A series of messages sent to same object
Rules are a bit odd unless you are used to
APL myPen home; up; goto: 100@200; down; home
Unary and binary expressions associate left
to right Equivalent to:
12 - 3 * 3 -> 27 myPen home
12 - (3 * 3) -> 3 myPen up
12 - 12 sin * 3 -> 0 myPen goto: 100@200
myPen down
myPen home
Smalltalk 6
Binary method example index := self size
index ~= aCollection size
= aCollection
ifTrue: [^false]
"answer true if elements contained by
receiver are equal to the elements [index <= 0]
contained by aCollection " whileFalse: [
| index | (self at: index) = aCollection at: index)
self == aCollection ifFalse: [^false].
ifTrue: [^true]. index := index – 1.]
(self class == aCollection class) ^true
ifFalse: [^false].
Note: == is equivalence (test for same object)
while = is test for equality (equal values)
Smalltalk 7
Iteration Iteration
count := 0.
sum := 0. "copy a disk file"
[ count <= 20 ] | input output |
whileTrue: [ sum := sum + count. input : = File pathName: 'go'.
count := count + 1 ] output := File pathName: 'junk'.
WhileTrue: is a method of Class Boolean
[input atEnd]
whileFalse: [output nextPut: input next],
value is a method of Class Block
input close,
whileTrue: sends message "value" to conditional block output close
Conditional block returns object true or false
If results is true, WhileTrue: evaluates code in parameter
block
44
45
Smalltalk 8
Classes and Message Lookup Polymorphism
A message sent to an object causes lookup Polymorphism: a specific message may be
in class definition sent to different instances of different class
If search fails, then lookup proceeds to at different times
superclass
Top of hierarchy is class Object Method lookup in Smalltalk occurs at
If no method found, error results execution time
A Stack
Inheritance class name
superclass name
Stack
Object
instance variable names stack
A subclass inherits all of the instance variables,
instance methods and class methods of the "Class Methods"
superclass new
– New instance variables can be added "Create an instance"
stack = OrderedCollection new.
– Names must differ from names of instance variables
^self
in ancestor classes
A subclass can define new methods or redefine "Instance Methods"
methods implemented in an ancestor class pop
"Answer the receiver with last item removed from
Redefinition hides definition in ancestor class stack"
Pseudovariable "super" can be used in methods self size = 0
to refer method search to the superclass ifTrue: [self error: "Attempt to pop empty
stack"]
ifFalse: [stack removeFirst. ^self]
Smalltalk 9
push: anItem Another Stack
"Answer the receiver with anItem added to the class name Stack
top"
stack addFirst: anItem. superclass name OrderedCollection
^self instance variable names none
"Class Methods"
top new
"Answer the top item on the receiver" "Create an instance"
^self size = 0 ^super new.
ifTrue: [self error: "Attempt to take top of pop
empty stack"]
^self removeFirst
ifFalse: [^stack at: 1]
push: anItem
empty ^self addFirst: anItem
"Answer true if the receiver is empty" top
^self size = 0 ^self at: 1
empty
size ^self size = 0
"Answer the size of the receiver"
^stack size
Smalltalk 10
Of interest to Ruby users: 99 Bottles of Beer
"Copy into a workspace, highlight the code and choose do
Ruby The Smalltalk Way it."
"Tested under Squeak 3.7 and VisualWorks 7.3"
[Link] | verseBlock |
verseBlock := [ :bottles | | verse |
verse := WriteStream with: (String new).
bottles = 0 ifTrue:
[verse
nextPutAll: 'No more bottles of beer on the wall.
No more bottles of beer...'; cr;
nextPutAll: 'Go to the store and buy some more...
99 bottles of beer.'; cr].
bottles = 1 ifTrue:
61 62
[verse
nextPutAll: '1 bottle of beer on the wall. 1 bottle of
beer...'; cr;
nextPutAll: 'Take one down and pass it around, no more
bottles of beer on the wall'; cr].
bottles > 1 ifTrue:
Example: Polynomials
[verse
nextPutAll: bottles printString; nextPutAll: ' bottles
of beer on the wall. ';
nextPutAll: bottles printString; nextPutAll: ' bottles
of beer...'; cr;
Polynomials
nextPutAll: 'Take one down and pass it around, ';
nextPutAll: (bottles - 1) printString, ' bottle';
– Represent Polynomials such 3x2 + 5x - 7
nextPutAll: (((bottles - 1) > 1)
ifTrue: ['s '] ifFalse: [' ']); – Representation is a collection of coefficients:
nextPutAll: 'of beer on the wall'; cr].
verse contents]. #(-7 5 3)
99 to: 0 by: -1 do: – Subclass of Magnitude
[: i | Transcript show: (verseBlock value: i); cr].
degree
"Highest non-zero power"
Polynomial class ^ coefficient size - 1
new asArray
"Unary class constructor: return 0*x^0" ^ coefficient deepCopy
^ self new: #( 0 )
= aPoly
new: array ^ coefficient = aPoly asArray
"Keyword class constructor"
^ (super new) init: array != aPoly
^ (self = aPoly) not
init: array
"Private: initialize coefficient" < aPoly
coefficient := array deepCopy 65 "not defined" 66
^ self shouldNotImplement
Smalltalk 11
Complex class
Evaluate method Object Subclass: #Complex
instanceVariableNames: 'realpart imagpart'
classVariableNames:: ''
evaluate: aPolynomial x: aNumber poolDictionaries: ''
"Return the results of evaluating aPolynomial new
for the value aNumber" "Unary class constructor: Invalid"
^ self error 'use real:imaginary:'
| index val | new: aComplex
index := 1 "Class constructor aComplex"
val := 0 ^ (super new) copy: aComplex
[index < coefficient size] whileTrue:
real: r imaginary: i
[ val := val + (coefficient at: index) *
"Class Constructor"
(aNumber raisedToInteger: (index – 1)) ] ^ (super new) setReal: r setImaginary: i
^ val
setReal: r setImaginary: i
"Private instance method to initialize self"
realpart := r
imagpart := i
67 68
^self
real
"Return real part"
^ realpart
negated
"Return new complex number: - self"
imaginary
^ Complex real: realpart negated imaginary:
"Return imaginary part" imagpart negated
^ imagpart
= val
+ val "Return self = val"
"Return new complex number: self + val" ^ (realpart = val real) & (imagpart = val
^ Complex real: realpart + val real imaginary)
imaginary: imagpart + val imaginary
< val
- val "Not mathemtically defined"
"Return new complex number: self - val" ^ self shouldNotImplement
^ Complex real: realpart - val real
imaginary: imagpart - val imaginary
69 70
Smalltalk 12