Primer : Looping (Part 1)
Repeating a series of instructions over and over again is what makes computers as
powerful as they are. Therefore, software must provide this mechanism in some
This primer briefly explains the concept of looping - telling a computer to repeat
a given number of instructions over and over again until you deem it appropriate
to stop the process.
For repeating a sequence of instructions over and over again, most computer languages
use a looping type of structure like the one below:
BeginFor example, below are a series of loops in Visual Basic.
Statements go here
For X = 1 to 100
Y = Y + X
Do While X < 100In Smalltalk, the structure is as follows:
Y = Y + X
X = X + 1
[ condition ] whileFalse: [ statements ]In Smalltalk, the square brackets ( [ ] ) comprise what is called a block. A block contains one of two types of code. The first block is Boolean and the second is a group of "normal" Smalltalk statements. For example:
[ condition ] ifTrue: [ statements ]
aCollection do: [ :var1 :var2 | statements ]
[ you are hungry ] ifTrue: [ eat something ]
In the first block, there is a Boolean statement. It will return either true or false. We then send the ifTrue: message to the Boolean object. Note that the ifTrue: message has a colon so it wants a parameter. The parameter is a block that can contain as many lines of code as you want or as little as one line of code. Our statement could look like this:
[ you are hungry ] ifTrue:
[ go to McDonalds.
order the Happy Meal.
take home the Happy Meal.
eat the Happy Meal. ]
A perfect example of using a whileFalse: message would be reading an external file line by line. Examine the code below:
| myFile myStream myLine addrIP |On the whileFalse: line, the condition is myStream atEnd which tests if we are at the end of our stream (file). The first time through, the answer is false so we send the whileFalse: message False. Strange as it may sound, the expression false whileFalse is true so Smalltalk then executes the lines of code in the block following the whileFalse: message.
myFile := 'ws000101.log' asFilename.
myStream := myFile readStream.
[ myStream atEnd ] whileFalse: [
myLine := myStream upTo: Character cr.
Transcript show: myLine.].
The first line of code in the block copies the stream into a temporary variable up to the first end-of-line character. It then displays that line in the Transcript. But here's the kicker. When it finishes executing all the lines of code in the "parameter" block, it returns to the "conditional" block. Then it tests the condition myStream atEnd again. This is still false because our stream is only at the end of the first line, not at the end of the entire stream, so Smalltalk executes the parameter block code again. When it does, it reads the stream of characters for the next line and displays them in the Transcript. Then it goes back to the ‘conditional’ block and tests the condition myStream atEnd again.
This process continues until eventually, we will get to the end of the stream and the condition of myStream atEnd will be true. When that happens, Smalltalk will skip the parameter block of code and proceed to the first line of code following the parameter block.
Wow! That's quite a lot for one line of code. But that's the whole point. Performing loops and testing conditions is something that software is constantly doing regardless of language. So the inventors of Smalltalk decided to make it simple to perform these routine tasks.
Here's another example of something that a programmer wants to do over and over again - iterating through a collection or an array. Instead of it being a bunch of lines of code, it's just one line of code.
| mySC |
mySC := SortedCollection new.
mySC add: 'one'.
mySC add: 'two'.
mySC add: 'three'.
mySC add: 'four'.
mySC add: 'five'.
mySC do: [ :X | Transcript show: X; cr.].
This is an example of the do loop. The temporary variable mySC stores five words and we wish to display these five words in the Transcript one by one. The way we iterate through the collection is with a do block. The do block has 2 parts. The first part identifies a temporary variable (in this case X). The second part is simply a group of Smalltalk statements. The 2 parts are separated by a vertical bar character.
Note that the declaration of the temporary variable X is preceded with a colon. The second part of the do block should look familiar to you - it's the good ole Transcript show: statement. What we are showing in the Transcript are the values (contents) of our sorted collection. So what happens is every element of the mySC collection is passed to the do block temporary variable X. The Transcript show: statement is then repeated for every element of the mySC collection. It's like saying "Take each element of the sorted collection and show it in the Transcript."
SummaryOf course, there is much more to looping than what is presented here. However, the important thing to remember is how these looping mechanisms use blocks. Boolean loops require 2 blocks - a "condition test block" first followed by a "grouping block". Iterative loops require just one block - a "grouping block" divided into 2 parts. The first part is where a parameter is (or parameters are) declared, followed by a normal group of Smalltalk statements.
If you find that you are still struggling with understanding what's going on here, don't worry about it right now. Study the syntax until it starts to make some sense. As you look at and play with more examples, they will.