In this session, we'll talk about loops in Pharo.
In Pharo, loops are messages sent to objects.
There are many types of loops.
They're messages sent to numbers, collections,
or even to blocks.
In some cases, they are iterators over the elements of a collection.
This is an example:
I send the message timesRepeat:
to the integer 4.
I pass it a block as a parameter.
We studied blocks in the previous course.
This blocks starts here and ends there.
This message repeats the evaluation of this block
several times: in this example, four times
as the receiver is 4.
There are other types of messages to create loops.
In this example, it's the message to:do:.
The message to:do: is defined on the class Number.
I'll also pass it a block as a parameter,
the last argument of the message.
This block gets executed a number of times
with a loop cursor that goes from the receiver
to the first argument of the message.
For instance,
with the exact same example:
I send the message to:do: to the integer 1.
In the block, you display the parameter of the block,
the parameter i at each loop.
In the transcript, you have all the integers between 1 and 100.
There are other messages to create loops.
For instance, the message to:by:do
to increment by more than 1.
You control the scale of the increment.
You can increment by 3 in this example.
With every loop, i takes values by step of 3.
You can see what happens when you execute this bit of code.
You can see i went from 1 to 100
with an increment of 3 each time.
There are also iterators to create loops.
Iterators are messages that must be sent to collections,
to collection objects.
There are many types such as do:.
do: iterates over every element of a collection.
collect: iterates over the elements of a collection
but also collects the results
to put them in a new collection.
select: selects matching elements in a collection:
you build a new collection with those you selected.
reject: rejects the elements of a collection you don't want.
detect: helps to determine
whether an element exists in a given collection, etc.
We'll study some of these in the next slides.
do:, for instance, is the most common message.
You send the message do: to a collection and pass it a block.
With every loop,
the parameter of the block, :each,
receives the first element of the collection,
then the second, until the final element of the collection.
This is an example: it's a defined collection.
A reminder of the syntax: open with #(
and close with ) for literal collections.
This collection contains four integers: 15, 10, 19, and 68.
You send the message do: to the collection and pass it a block.
i, the parameter of the block,
takes the value 15 on the first loop,
then 10, 19, and 68.
This is another message: whileTrue:.
whileTrue: can also create loops,
but it is a message you send to a block.
It is defined over the class Block.
This is the receiver block.
There's a block of arguments here.
I give you a concrete example from the class Color.
This is whileTrue:.
In the receiver block, there's a condition.
The block is evaluated to true or false.
Depending on the evaluation of the first block, the receiver,
you trigger or don't trigger the execution
of the second block, which is the parameter of whileTrue:.
There's another version of whileTrue:.
It's the method whileTrue without a parameter.
It takes the receiver block and evaluates it.
If it returns true or false,
it is re-evaluated once more, and so on.
You re-evaluate the block as long as its value is true.
You have the twins of whileTrue with the methods whileFalse,
with and without parameters.
Every variation exists when it comes to classes and blocks.
To sum up, in this course,
we saw that loops are expressed as normal messages in Pharo.
They're sent to objects
(integers, collections, blocks...).
You can use them to build plenty of different loops.
You can even add some if you wish.