Loop Index, Start and End Lines

Home, Up: Loops

 

On this page:

The Loop Index I, Start and End Lines, The Loop Timer TIME, ISLOOP -- Is it a Loop? PASSES -- How Many Passes?

 

As always, the question mark at the beginning of a line is Hypatia's input prompt, you do not type it.

 

The Loop Index I

The loop index I counts the loop passes, starting with 1.

Technically I is a "pseudo constant", you can use it in calculations the same way you'd use a number or a constant (though, of course, its value will change at each loop pass).

To illustrate, let's add up the numbers 1 to 100 (of course there is a simple formula by which we could compute the result, but we want to see the loop index at work).

First we have to set the result variable $ to zero, then 100 times we add the value of I to the previous result:

? 0

? DO 100 :: I +

= 5050

(I + is short for $ I + because $ can be omitted at the start of the line.)

 

The loop index I can be used in any calculations, whether in single line loops or in scripts. It can, of course, also be used in IF ... conditions -- for instance, if in a script you want the value of $ to be shown at every tenth loop pass, you can write:

IF I 10 MULTIPLE THEN =

(= as a command shows the value of $, that is, the most recent calculation result, in the currently chosen format. If you want to see it with the maximum number of digits, use ==.)

Even though the loop index I is not a variable, you can use SHOW I to display its current value.

 

If you have some experience with programming languages, you'll be used to defining start value, end value and increment of your loop variable.

While Hypatia's loop index always starts with 1 and always has an increment of 1, you can easily create your own index variable, either by deriving it from I, or by using a variable for doing your own counting.

 

Start and End Lines

Often it will be necessary to do certain things either at the start of a loop (for instance, set $ to zero, initialize variables, prompt for user input, start buffer mode, etc.), or at the end of a loop (for instance, display values of variables, save the buffer, etc.).

This can easily be done by putting I1: or I*: before any line to be executed at the first or last loop pass, for instance:

I1: 0

I1: BUFFER START

... ...

I*: BUFFER FLUSH

 

I1: and I*: lines can be commands, calculations or comments.

I1: and I*: can be followed by IF ... THEN ...

I1: and I*: can NOT be followed by ALSO: or ELSE:

If I1: or I*: are followed by a comment (that is, a text beginning with a hash sign #), this comment will be displayed.

I*: lines will not be executed when the loop ends with an error, or with an ABORT command -- see next page.

 

If your script begins with lines that modify Hypatia's settings (e.g. USE DEG, INTEGER OFF, $zero = ...) then use them with I1: so that these lines will only be executed once.

 

The Loop Timer TIME

A loop with thousands or even millions of passes may take some time to complete, and if it is something you need more often you may want to optimize its speed.

The timer pseudo constant TIME can help you with this task, it measures the time in seconds since the start of the loop.

TIME can be used with the SHOW command. You will probably want to do that in an I*: line to display the time it took the loop to reach the end:

I*: SHOW TIME

It is unlikely, but in case you need it you can use TIME in calculations or IF ... conditions.

Outside of a loop TIME has the value zero -- that means that the value of TIME has to be displayed (or assigned to a variable) before the loop ends.

The value of TIME is a number with three digits after the decimal point, but Windows only allows only the first digit after the decimal point to be accurate. During the first few passes of the loop its value will remain 0, then it will increase in steps. Still, for optmizing loops with a high number of passes TIME will be accurate enough.

 

ISLOOP -- Is it a Loop?

One more pseudo constant: Some scripts can be meant to be either called directly or in a loop, and then it may be relevant to know which is the case.

Neither the loop index I nor the timer TIME can help to decide this -- the value of I is 1 both outside of a loop and during the first pass, while TIME will be 0 both outside of a loop and during the first passes.

ISLOOP provides the answer: outside of a loop its value is 0, within a loop it is 1.

ISLOOP is meant to be used in IF ... conditions. Other than the values of I and TIME you cannot display its value with SHOW.

 

PASSES -- How Many Passes?

The PASSES pseudo constant lets a script that has been called in a loop know how many loop passes there will be (unless it is cut short by a different end of loop condition). This is either the number in DO n :: _scriptfile (or DO n :: RUN scriptfile), or the current value of maximum number of loops in _*scriptfile or DO * :: _scriptfile, or DO * RUN scriptfile. (This maximum is one hundred thousand by default, unless you change it with the MAXLOOP command.)

This can be used for two purposes:

- If a script should be called with a certain number of passes, or not too large or not to low a number, this can be checked in an I1: line at the start of the script, for instance I1: IF PASSES 100 >> THEN ABORT if it shouldn't be more than 100 passes.

- If you want a script to show intermediate results for instance ten times, you can use PASSES to calculate every how many passes this should happen -- so, when you call the script with DO 100 :: _myscript then these results will be shown every tenth loop pass, when you call it with DO 5000 :: _myscript then every fivehundredth, when the loop index I is a multiple of a tenth of the specified number of loop passes:

I1: $every = PASSES 10 /

...

IF I $every MULTIPLE THEN SHOW ...

 

Home, Up: Loops, Prev: The DO Loop Command, Next: Exiting a Loop