Understanding Smalltalk control structures
TL;DR
This page gives a high-level overview of how control structures in Smalltalk are all implemented by messages sent to objects.
Overview
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.
Simple conditionals
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
blocks
, so they will only be conditionally evaluated.
There are also a few variants of this method, such as #ifTrue:
(with an
else
case), #ifFalse:
(without a
then
case), and so on. See the controlling
methods of the Boolean
class for other methods.
Loops
A
for-loop
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!
Iterators
You can iterate over any collection by sending it the #do:
message:
n := 1. #(1 2 3 4 5 6 7 8 9 10) do: [ :i | n := n * i ]. n
But #do:
is probably the least interesting message you can send to a collection.
(1 to: 10) inject: 1 into: [ :product :each | product * each ]
The #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
reduce
or
fold
in other languages.
For many more examples, have a look at Working with collections in Pharo.