Loops

Loops.

There are 3 kinds of loops in PicoLisp: for, do and loop.

For Loop. 

The first form of "for" loop repeats X number of times the lists provided as code :

: (for a 4 (println "hello"))
"hello"
"hello"
"hello"
"hello"
-> "hello"

The second form of "for" loop has the same meaning to "foreach" og Logo programming language. Accepts a variable as first argument, a list as second argument and a code list as third argument. The variable takes each value of the list provided and executes the list of code: 

: (for i (11 22 33)(print i))
112233-> 33
: (for i (11 22 33)(println i))
11
22
33
-> 33

: (for i '("hello" "my" "friend" "Tom")(println i))
"hello"
"my"
"friend"
"Tom"
-> "Tom"

Do Loop.

The do loop accepts a number as first argument and a list of code as second argument and repeats the code list as many times as the number of first argument. :

: (do 3 (println "Hello World!"))
"Hello World!"
"Hello World!"
"Hello World!"
-> "Hello World!"

Loop.

Loops through a code list until the last condition becomes true:

: (let a 5 (loop (prinl a) ( T(=0 (dec 'a)) "Done"))) 
5
4
3
2
1
-> "Done"

PicoLisp Functions Used On This Page.

The description of the picolisp functions used taken from official PicoLisp documentation (https://software-lab.de/doc/index.html) follows: 




(loop ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
Endless loop with multiple conditional exits: The body is executed an unlimited number of times. If a clause has NIL or T as its CAR, the clause's second element is evaluated as a condition and - if the result is NIL or non-NIL, respectively - the prg is executed and the result returned. See also do and for.

: (let N 3
   (loop
      (prinl N)
      (T (=0 (dec 'N)) 'done) ) )
3
2
1
-> done





(do 'flg|num ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
Counted loop with multiple conditional exits: The body is executed at most num times (or never (if the first argument is NIL), or an infinite number of times (if the first argument is T)). If a clause has NIL or T as its CAR, the clause's second element is evaluated as a condition and - if the result is NIL or non-NIL, respectively - the prg is executed and the result returned. Otherwise (if count drops to zero), the result of the last expression is returned. See also loop and for.

: (do 4 (printsp 'OK))
OK OK OK OK -> OK
: (do 4 (printsp 'OK) (T (= 3 3) (printsp 'done)))
OK done -> done




(for sym 'num ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
(for sym|(sym2 . sym) 'lst ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
(for (sym|(sym2 . sym) 'any1 'any2 [. prg]) ['any | (NIL 'any . prg) | (T 'any . prg) ..]) -> any
Conditional loop with local variable(s) and multiple conditional exits:
In the first form, the value of sym is saved, sym is bound to 1, and the body is executed with increasing values up to (and including) num.
In the second form, the value of sym is saved, sym is subsequently bound to the elements of lst, and the body is executed each time.
In the third form, the value of sym is saved, and sym is bound to any1. If sym2 is given, it is treated as a counter variable, first bound to 1 and then incremented for each execution of the body. While the condition any2 evaluates to non-NIL, the body is repeatedly executed and, if prg is given, sym is re-bound to the result of its evaluation.
If a clause has NIL or T as its CAR, the clause's second element is evaluated as a condition and - if the result is NIL or non-NIL, respectively - the prg is executed and the result returned. If the body is never executed, NIL is returned.
See also do and loop.

# First form:
: (for N 5 (printsp N))
1 2 3 4 5 -> 5
: (for N 5 (printsp N) (NIL (< N 3) (printsp 'enough)))
1 2 3 enough -> enough
: (for N 5 (T (> N 3) (printsp 'enough)) (printsp N))
1 2 3 enough -> enough

# Second form:
: (for X (1 a 2 b) (printsp X))
1 a 2 b -> b
: (for (I . X) '(a b c) (println I X))
1 a
2 b
3 c
-> c

# Third form:
: (for (L (1 2 3 4 5) L) (printsp (pop 'L)))
1 2 3 4 5 -> 5
: (for (N 1 (>= 5 N) (inc N)) (printsp N))
1 2 3 4 5 -> 5
: (for ((I . L) '(a b c d e f) L (cddr L)) (println I L))
1 (a b c d e f)
2 (c d e f)
3 (e f)
-> (e f)