Now we know how to do things, and we know how to choose whether or not we will do something. We’re getting close to having some real skills with REBOL. We just need to get the understanding of one more concept before we reach the first little plateau of programming knowledge. We need to learn how to do a task more than once. Well, besides just running the script again, but that doesn’t really count.
Simple Loops
The simplest sort of repetition involves doing exactly the same thing again and again. The simplest sort of repetition involves doing exactly the same thing again and again. The simplest sort of repetition involves doing exactly the same thing again and again. The simplest sort of repetition –
Sorry, I got carried away. Hopefully you get the idea. Sometimes all you need to do is repeat a process a set number of times.
loop
That’s a little boring. Let’s try something a little more involved. Maybe we could use loop
to create a simple math quiz program.
Nothing fancy is going on here. We just loop
through the question and answer process a few times, keeping track of the user’s correct answers. random/seed now
is necessary to get something close to what we would consider random. If we don’t provide it, then we get a specific sequence whenever we call random
. Try commenting out the random/seed
line and run the program a few times. You’ll see what I mean.
You’re right. A plain old loop
isn’t very interesting. Let’s move on.
Looping forever
I’m only telling you this because I can see that one or two of you really want to know. What if you want to run a loop forever? Well, you don’t want to. Maybe you want to run a loop until some signal is received, or the user wants to quit, or something sensible like that. You don’t want a loop to run forever. But that doesn’t mean you can’t run a loop forever. REBOL provides us with the forever
word to let us do exactly that.
And so on until you hit Ctrl + C
, or kill the process, or do something to make the program stop saying “spam”!
But please, don’t use forever
without a mighty good reason.
break
out of a loop
Sometimes you’re right in the middle of a loop and you want to break out of it and get back to the rest of the program. That’s easy enough.
Oh, you noticed that prin
in there? That’s a different way of printing. Each call to prin
puts its output immediately after the output from the previous prin
, rather than on a new line. It’s nothing major, but it is a nice feature to take advantage of every once in a while.
Right. So we’ve covered simple loops. Now let’s start getting a little more interesting.
Monitored Loops
Plain old repetition isn’t actually all that common. We usually want to do something a little different each time we step through the loop. REBOL gives us a few words which help us in that situation.
repeat
repeat
works almost exactly the same as loop
. The main difference is that it stores the number of trips you’ve taken through the loop in a variable that you can get to from inside the loop. The variable has a value of 1
on the first trip through, 2
on the second trip through, and so on.
for
The next sort of repetition structure is for
, which adds a starting point, stopping point, and step size to the repeat
loop. for
is useful for producing very specific loops. It might be a little wordy for simple loops which can be handled by the repeat
word:
We have a loop variable, num
, which starts at 1
and goes up to 9
1
number at a time. Of course, repeat num 9
does exactly the same thing. for
tends to be more useful in loops for “real-world” code, though, where you need more control over what’s being looped. You want some real world code? Hmm. Oh, I know. Let’s answer the age-old question, “How much should I tip? That way we can play a little bit with some datatypes while helping out our friends in the food service industry. Hey, what do you expect from me? I was a waiter for ten years, so this is the sort of stuff that pops into my head!
We can’t do that with a repeat
loop. At least, I don’t think we can. We set the starting bill at $10
, and moved up to $20
by $1
at a time, showing the bill and corresponding average tip. It’s still a very small thing. The fact that it recognizes the values as money and treats it appropriately is a special thrill for me. If you haven’t programmed before, then you might just assume that things are supposed to work like this. You would be right. Things should work like this: transparent, and the obvious stuff should do the obvious. But in C, there would be all sorts of chaos and printf
madness and general ugliness that would get you so angry that you might not even bother leaving a tip.
And that would be bad, my friends. Very bad indeed.
As long as I’m looking at datatypes in for
loops, let’s look at another example. Starting from Saturday, January 3 2009, what is the calendar date of each following Saturday until March 7 2009?
Start on January 3, step 7 days at a time until we reach March 7, and print the calendar date at each step. Not bad, eh? I know that these all occurred on a Saturday, but you’ll have to wait until later for me to explain it. You want a clue? Oh, all right. I used day/weekday
, got 6
, and figured out that the sixth day of the week is Saturday.
Or maybe I looked at a calendar. I’ll never tell.
Conditional Loops
Then there are the times when you aren’t sure exactly when you’ll need to stop. You need to keep going until it’s time to stop, basically. Now, you could use a forever
loop and break
whenever you need to stop. But I don’t want you to do that. Why am I so opposed to an approach like that? It comes down to clarity. Somebody will be reading your code a few weeks, months, or even years after you write it. That person could be you.
Don’t laugh - I’m still haunted by a script that I wrote years ago when I was first learning Perl. I thought I’d just be throwing that script away, but I still use it. I still cringe every time I have to read it, too. And yes, it had a couple of forever
-style loops. I want to save you from the embarrassment of bad code whenever possible.
But I digress. Let’s look at the conditional loops. There are two main conditional loops, until
and while
. The difference between the two from our perspective is when they test to see whether it’s time to quit the loop.
Keep going until
something is true
The until
loop tests at the end of each step of the loop. If the block returns true, then it’s time to quit. How do you know if the block returns true
? Because the block returns the value of the last statement in the block. This means that we could put a simple test as the last statement, using the guidelines from the chapter on selection structures.
Because it doesn’t test until the end of the loop, until
will step through the loop at least once.
Keep going while
something is true
while
takes a test block and a loop block. There’s all sorts of clever things we can do in the test block, but for now we’ll just put simple tests in it. If the test comes up false, then while
doesn’t bother running through the loop. If it’s true, then it runs through the loop and tests again.
Hrm, I need to think of a decent example of while
. For now, let’s just make a variation of what we might do with an until
loop.
while
will not run at all if the condition isn’t true at the start of the loop, because it tests the condition before beginning each step.
Stepping Through a List
The last form of repetition is iterating through a list. A copy of each item in the list is passed to a temporary variable that you can play with in the loop block. I will only look briefly at this form of repetition in this chapter, because list manipulation and iteration is a big topic in its own right. Nevertheless, many of you will want to do something with lists before I get around to writing that next chapter.
foreach
The basic list iteration function is foreach
. It takes a name, a list variable, and a block. foreach
repeats the loop once for each item in the list. The name is set to the value of the current item in the list. It is easier to demonstrate a foreach
loop than it is to describe one.
Here’s a quick example.
I would like to close this chapter with something a little meatier than that example, though. Let’s write a script that takes a list of dates and tells us how far from today each of those dates are.
Now that we’ve written the code, let’s run the script:
Naturally, your results may vary. In fact, they will almost definitely vary unless you read this article the day I updated it or your clock is set wrong. I encourage you to play with this script and come up with your own variations. How about a script that asks the user for a date and tells how far that day is from today? You’ll probably need to use to-date
on the user input.
Conclusion and Congratulations
Completing this chapter means you have hit a significant milestone in programming by learning all of the basic elements of something called “Structured Programming”. It is now possible for you to build non-trivial, “real-world” programs using REBOL. I will try to keep this in mind when putting together future chapters in this tutorial.
Backlinks
Added to vault 2024-01-15. Updated on 2024-02-01