INPUT /  OUTPUT /  LANGUAGE





Repetition

Your program can repeat things with its own loops, of course. But sometimes it's handy for the console to repeat something itself: generating a list of values, doing the same thing to every element of an array, or doing something again and again over time. ioL has two tags for this: for, which repeats as fast as it can, and timer, which repeats at regular intervals.


The for tag

A for tag counts from one number to another, and carries out the code in its do field once for each number:

<n:for 1 limit=5 do=n>           <! generates 1, 2, 3, 4, 5 !>

Whatever do generates each time round, the for tag generates too, one after another. So this displays the seven times table:

<n:for 1 limit=12 do={<n> x 7 = <mul n, 7></n>}>
1 x 7 = 7
2 x 7 = 14
3 x 7 = 21
...
12 x 7 = 84

And this adds up the numbers from 1 to 100, by carrying out an action each time round instead:

<total:scalar 0>
<m:for 1 limit=100 do=<total | add total, m>>
<putLn total>                    <! sends 5050 !>

Values, not tag instances

A for loop generates values, and can carry out actions, but it can't create presentation tags: a span in its do field won't appear on screen. To create many tag instances from one definition, use an array, which is what arrays are for.

Looping over an array

A for loop is the natural way to do something to every element of an array: make each one the current element in turn, and act on it. Here's how you could clear the noughts and crosses board from the chapter on arrays, to start a new game:

<i:for 1 limit=cells.# do=<cells i>, <cells.*.mark {</ >}>>

Keep loops short

While a for loop is running, nothing else can happen in the console: the user can't click anything until it's finished. To keep the console responsive, a loop is cut off after 4096 times round (this may vary between computers), without any warning. So use for for quick jobs on a handful of things. Anything bigger belongs in your program.

The timer tag

A timer carries out the code in its onTimer field every so often. Unlike for, it waits between repetitions, and the user can carry on using the console in the meantime.

<t:timer period=1,{s} limit=10 onTimer=<putLn {tick}>>

This sends tick to your program once a second, ten times.

Unlike a for tag, a timer is a persistent logic tag: it stays in the console until you clear it, and you can control it by changing its fields.

Starting and stopping

A timer with a period of 0 is stopped. So the easy way to control a timer is to create it with period=0 and limit=inf, then start it by giving it a period, and stop it again by setting the period back to 0:

<t:timer period=0 limit=inf onTimer=...>
<t.period 1,{s}>         <! start: go off every second !>
<t.period 0>             <! stop !>

Starting it again carries on where it left off.

Example: a stopwatch

This stopwatch runs entirely in the console. The timer goes off every tenth of a second, and each time it adds one to tenths and displays the time in seconds.

print('''
<console.title {Stopwatch}>
<tenths:scalar 0>
<ticker:timer period=0 limit=inf onTimer=<tenths | add tenths, 1>, <shown | div tenths, 10>>
<shown:span size=48,pt bold=true {0}></n>
<button {Start} onClick=<ticker.period 100>>
<button {Stop} onClick=<ticker.period 0>>
<button {Reset} onClick=<tenths 0>, <shown 0>>
<button {Quit} onClick=<putLn {/quit}>>
''')
while input() != '/quit':
    pass
3.1
Start Stop Reset Quit

The stopwatch keeps its own count in tenths, rather than using the timer's count, so that Reset can set it back to zero without touching the timer.

A timer goes off about as often as you ask. It's good enough for animations and for keeping a display up to date, but this stopwatch will drift slowly behind a real clock. If you need accurate timing, have your program measure the time, and use the timer only to ask the program for an update.

Try it

  1. Use a for loop to display the numbers from 10 down to 1. (Hint: there's no way to count backwards, but you can calculate with the count.)
  2. Add a "New game" button to noughts and crosses that clears the board using the loop above. What does your program also need to do?
  3. Make a countdown timer: the user types a number of seconds, clicks Start, and the display counts down to zero and then says "Time's up!".
  4. Make a box that changes to a random colour every second. (Hint: your program can pick the colour, if the timer asks it.)