Understanding Smalltalk control structures
This page gives a high-level overview of how control structures in Smalltalk are all implemented by messages sent to objects.
Smalltalk has no built-in control structures. Instead, all control structures are realized by sending messages to objects, usually Booleans, Integers and Collections.
We will show a few examples here, but please note that the list is open-ended: you can always add new control structures as needed.
The most basic control structures are messages sent to Booleans .
An if-then-else is just an
#ifTrue:ifFalse: message sent to a Boolean value.
Date today weekday = 'Friday' ifTrue: [ 'Clock out early!' ] ifFalse: [ 'Work till closing' ]
Note that the arguments to
#ifTrue:ifFalse: must be
, so they will only be conditionally evaluated.
There are also a few variants of this method, such as
#ifTrue: (with an
#ifFalse: (without a
case), and so on. See the
controlling methods of the
Object subclass: #Boolean
class for other methods.
in Smalltalk can be realized by sending
#to:do: to a number.
n := 1. 1 to: 10 do: [ :i | n := n * i ]. n
Note that this is equivalent to sending
#do: to an Interval:
n := 1. (1 to: 10) do: [ :i | n := n * i ]. n
A while-loop , on the other hand, is a message to a block:
n := 1. i := 0. [ i < 10 ] whileTrue: [ i := i + 1. n := n * i ]. n
Note that the receiver of
#whileTrue: must be a block rather than simply an expression, as it needs to be reevaluated on each iteration!
You can iterate over any collection by sending it the
n := 1. #(1 2 3 4 5 6 7 8 9 10) do: [ :i | n := n * i ]. n
#do: is probably the least interesting message you can send to a collection.
(1 to: 10) inject: 1 into: [ :product :each | product * each ]
#inject:into: message takes an initial value and a two-argument block as arguments, and iteratively applies the block the initial value with each element of the collection. This is commonly known as
in other languages.
For many more examples, have a look at Working with collections in Pharo.