W Wrapl, The Programming Language

Chapter 5

Loops

There are two different forms of looping in Wrapl.

Regular Loops

The simplest way to write a loop in Wrapl is with the expression REP body, which simply keeps evaluating body.

--> IMP IO.Terminal USE Out; NIL --> REP Out:write("Hello world!\n"); Hello world! Hello world! Hello world! Hello world! Hello world! Hello world!^CInterrupted -->

By itself, a REP expression is not much use. However, the body of a loop may be a block which may contain exit expressions EXIT value which cause the loop to terminate producing the values of value. For example:

--> VAR n <- 1; 1 --> REP ( ... n > 1000 => EXIT n; ... n <- n + n; ... ); 1024 -->

The value after EXIT is optional; if no value is provided, then the loop produces NIL. The two expressions WHILE condition and UNTIL condition are syntax sugar for condition // EXIT NIL and condition => EXIT NIL respectively. Thus a loop like:

1while condition do { 2 body 3};

in C would look like

1REP (WHILE condition; 2 body 3);

in Wrapl. A loop like:

1do { 2 body 3} while (condition);

would be equivalent to

1REP ( 2 body 3WHILE condition);

You can have any number of EXIT expressions (and hence WHILE and UNTIL expressions) in a loop. The step expression STEP causes the loop to start the next iteration immediately.

--> IMP IO.Terminal USE Out; NIL --> VAR i <- 0; 0 --> REP ( ... i <- i + 1; ... i = 5 => STEP; ... Out:write('i = {i}\n'); ... UNTIL i = 10; ... ); i = 1 i = 2 i = 3 i = 4 i = 6 i = 7 i = 8 i = 9 i = 10 NIL -->

Generator Loops

Since expressions in Wrapl can produce more than value, they can be used for looping using an EVERY expression. The expression EVERY condition DO body evaluates body once for each value produced by condition. Since an EVERY expression normally terminates when condition fails to produce any more values, usually the entire EVERY expression fails to produce any value.

--> VAR i; NIL --> EVERY i <- 1:to(5) DO Out:write('i = {i}\n'); i = 1 i = 2 i = 3 i = 4 i = 5 failure

Both STEP and EXIT expressions (and hence WHILE and UNTIL expressions) can be used within condition and body, allowing EVERY expressions to produce values. The DO body clause can be omitted, which is equivalent to using DO NIL.

--> EVERY Out:write('{1:to(5)} '); 1 2 3 4 5 failure -->

References

Variables are one example of references, i.e. they both have a value and can be assigned a new value. Wrapl allows references to be passed to and returned from functions. Arguments which evaluate to references are passed as such to functions, however when the function is called, it normally only uses the current values of those arguments. Declaring a parameter with a proceeding + indicates that the parameter should use the reference to the argument, so that assigning a value to the parameter within the function changes the value of the argument itself.

--> VAR x; NIL --> DEF F(x) x <- 10; NIL --> F(x); 10 --> x; NIL --> DEF G(x+) x <- 10; NIL --> G(x); 10 --> x; 10 --> VAR y <- 20; 20 --> DEF Swap(a+, b+) ( ... VAR c <- a; ... a <- b; ... b <- c; ... NIL; ... ); NIL --> Swap(x, y); NIL --> x; 20 --> y; 10

Similarly, references are returned from functions as such, and can be assigned to like a variable.

--> VAR y; NIL --> DEF H() y; NIL --> H() <- 200; 200 --> y; 200

The result of any expression can be a reference.

--> VAR a; NIL --> VAR b; NIL --> (1 > 2 => a // b) <- 40; 40 --> a; NIL --> b; 40

Navigate