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:
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
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
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
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)