3.5. Control Structures


Control structure are lisp functions specially designed for controlling how a program is executed. There are control structures for starting the execution (e.g. eval ) and control structures for programming loops (e.g. while ).



3.5.0. (eval l1...ln)
[DX]


See: The Tlisp Evaluator.
The function eval calls the evaluator on objects l1 to ln , and returns the result of the last evaluation, i.e. (eval ln) .

Example:

? (eval (cons '+ '(3 4)))
= 7



3.5.1. (apply f l)
[DX]


Function apply applies function f to the argument list l .

First of all, f is evaluated. The result can be a function, a symbol whose value is a function or even a list whose result is a function. This function is then applied to arguments l .

Evaluating (apply f l) is quite similar to (eval (cons f l)) . It blocks however the evaluation of the arguments stored in list l.

Example:

? (apply 'append '((1 2 3) (1 3 5)))
= (1 2 3 1 3 5)

? (apply append '((list 2 3) (list 4 (+ 1 2))))
= (list 2 3 list 4 (+ 1 2))

? (eval (cons append '((list 2 3) (list 4 (+ 1 2)))))
= (2 3 4 3)



3.5.2. (quote a)
[DX]


See: ' a
See: ` expr , a ,@ a


Function quote returns the Tlisp object a without evaluating it.

In most cases indeed, functions evaluate their arguments and operate on the results of these evaluations. In (car (range 2 5)) for instance, function car evaluates the arguments (range 2 5) giving (2 3 4 5) and returns the first element of this list.

? (car (range 2 5))
= 2

Using the function quote prevents a function from evaluating a Tlisp object passed as argument. It evaluates thhhe list (quote a) instead, returning the object a itself.

? (car '(range 2 5))
= range



3.5.3. 'a
[DMC] (sysenv.lsh)


See: (quote a )
See: ` expr , a ,@ a


The function quote usually is called by using the quote ' macro-character. Writing 'a is a shorthand for (quote a) .

Example:

? (car '(range 2 5))
= range

? '(range 2 5)
= (quote (range 2 5))



3.5.4. `expr ,a ,@a


The backquote ` macro provides a handy syntax for producing complex lists depending of external conditions. The backquote macro works like the quote macro with the following additions:

Example:

? `(1 2 ,(+ 4 5) (+ 4 5 ,(range 1 4))))
= (1 2 9 (+ 4 5 (1 2 3 4)))
? `(1 2 ,(+ 4 5) (+ 4 5 ,@(range 1 4))))
= (1 2 9 (+ 4 5 1 2 3 4))

Implementation: Combinations of backquote and comma macros are expanded into lisp expressions composed of calls to functions list , append and cons , which builds the result.

Example:

;; note the quote <'> followed by a backquote <`>
? ' `(1 2 ,(+ 4 5) (+ 4 5 ,@(range 1 4)))
= (list '1 '2 (+ 4 5) (append '(+ 4 5) (range 1 4)))


3.5.5. (progn l1...ln)
[DY]


Evaluates l1 to ln and returns the result of the evaluation of ln .

Example:

? (progn
    (print (+ 2 3))
    (* 2 3) )
5
= 6



3.5.6. (prog1 l1...ln)
[DY]


Evaluates l1 to ln and returns the result of the evaluation of l1 .

Example:

? (prog1
      (print (+ 2 3))
    (* 2 3) )
5
= 5



3.5.7. (let ((s1 v1) ... (sn vn)) l1 ... ln)
[DY]


The function let is used to define local variables.

Function let performs the following operations:

Example:

? (let ((s 0))
    (for (i 1 10)
      (setq s (+ s i)) ) )
= 55



3.5.8. (let* ((s1 v1) ... (sn vn)) l1 ... ln)
[DY]


Function let* is also used for defining local variables. Unlike function let however, the evaluation of the variable initial values are performed after setting the previous variables. You can therefore refer to the previously defined variabled.

Function let* performs the following operations:

Example:

? (let* ((i 1)
         (j (1+ i)) )
    (print i j)
    (* 2 j) )
1 2
= 4



3.5.9. (let-filter ((filter data)) l1...ln)
[DM] (sysenv.lsh)


The function let-filter attempts to match the data expression data with the filter expression filter . A filter expression is a lisp expression composed uniquely with lists and symbols. For instance, argument filter can be a single symbol, a list of symbols, or something more complex such as (a ((b c)) d . e) .

If there is a match, function let-filter evaluates the lists l1 ... ln with the new values of the symbols listed in the match expression, restores the initial value of the symbols, and return the result of the last evaluation. Otherwise, function let-filter simply restores the initial values of the symbol and returns the empty list.



3.5.10. (if cond yes [no1...non])
[DY]


First, expression cond is evaluated. If the result is not the empty list, expression yes is evaluated, otherwise the remaining expressions no1 ... non are evaluated. Function if returns the result of the last evaluation.

Example:

? (if (> 3 4)
      3
    4 )
= 4



3.5.11. (when cond yes1...yesn)
[DY]


First, expression cond is evaluated. If the result is not the empty list, expressions yes1 to yesn are evaluated and the result of yesn is returned.

Example:

? (when (> 3 4)
    (print "error") )
= ()



3.5.12. (while cond l1...ln)
[DY]


While the evaluation of cond gives a result different from the empty list, expressions l1 to ln are evaluated in a loop.

If the result of the first evaluation of cond is the empty list, expressions l1 to ln are never evaluated and function while returns the empty list. Otherwise function while returns the result of the last evaluation of ln .

Example:

? (let ((l (range 2 5)))
    (while l
      (print (car l) (sqrt (car l)))
      (setq l (cdr l)) ) )
2 1.4142
3 1.7321
4 2
5 2.2361
= ()



3.5.13. (do-while cond l1...ln)
[DY]


Function do-while evaluates lists l1 to ln and loops until the evaluation of condition cond returns the empty list. The result of the last evaluation of ln is then returned.

Expressions l1 to ln are evaluated before testing for the loop condition. If the result of the first evaluation of cond is the empty list, expression l1 ... ln are evaluated exactly once.

Example:

 (de input(prompt regex)
    (let ((answer ()))
       (do-while (not (regex-match regex answer))
          (printf "%s" prompt)
          (flush)
          (setq answer (read-string)) )
       answer) )


3.5.14. (repeat n l1...ln)
[DY]


Repeats n times the evaluation of l1 to ln . Function repeat returns the result of the last evaluation of ln .

Example:

? (repeat 4
    (prin 1) )
1111= 1



3.5.15. (mapwhile cond l1...ln)
[DM] (sysenv.lsh)


See: (while cond l1 ... ln )


Function mapwhile first evaluates expression expr . If this evaluation returns a non nil result, it evaluates lists l1 to ln . This process is repeated until the evaluation of cond returns the empty list.

Unlike function while however, function mapwhile returns a list containing all the results of the successive evaluation of ln .

? (let ((i 0))
    (mapwhile (< i 5)
      (incr i)
      (* i i) ) )
= (1 4 9 16 25)



3.5.16. (for (symb start end [step]) l1...ln)
[DY]


Function for implements a classical ``for'' loop. The value of symbol symb is first saved. Then symb takes numeric values from start to end stepping by step (default 1). For each value, expression l1 to ln are evaluated. The value of symb is then restored.

Function for returns the result of last evaluation of ln .

Example:

? (for (i 2 5)
    (print i (sqrt i)) )
2 1.4142
3 1.7321
4 2
5 2.2361
= 2.2361



3.5.17. (mapfor (symb start end [step]) l1...ln)
[DMD] (sysenv.lsh)


See: (for ( symb start end [ step ]) l1 ... ln )


Function mapfor implements a loop like function for . It returns however a list containing the results of the evaluation of ln for all values of the loop index.

Example:

? (mapfor (i 2 5)
    (sqrt i) )
= (1.4142 1.7321 2 2.2361)



3.5.18. (cond l1...ln)
[DY]


Function cond implements the standard lisp ``cond'' form.

Arguments l1 ... ln are lists of the form (cond . body) . The conditions cond are evaluated sequentially until one returns a result different from the empty list. The function progn is applied to the corresponding body and the result is returned.

Example:

 ;; a function for returning the sign of a number
 (de sign(x)
   (cond
      ((< x 0) -1)
      ((> x 0) +1)
      (t        0) ) )



3.5.19. (selectq s l1...ln)
[DY]


The arguments l1 to ln are lists of the form (case . body) .

The argument s is first evaluated. The lists l1 to ln are then checked until s is equal to case , or s is a member of the list case , or case is equal to t . The function progn is applied to the corresponding body and the result is returned.

Example:

 (selectq x
    (0             (print "zero"))
    ((2 4 6 8)     (print "even"))
    ((1 2 3 5 7)   (print "prime"))
    (t             (print "nothing interesting")) )



3.5.20. (mapc f l1...ln)
[DX]


For i=1 till (length l1) this function constructs a list containing the i-th element of each list l1 ... ln and applies the function f to to it. Th lists l1 till ln should have the same length. This function returns the result of the last evaluation.

Example:

? (mapc print '(1 2 3))
1
2
3
= 3



3.5.21. (mapcar f l1...ln)
[DX]


Like mapc but returning the list of all evaluation results rather than just the last one.

Example:

? (mapcar '+ '(1 2 3) '(4 5 6))
= (5 7 9)



3.5.22. (rmapc f l1...ln)
[DX]


See: (mapc f l1 ... ln )
rmapc works like mapc , but is able to recursively scan sublists in l1 .. ln .

Example:

? (rmapc 'prin '(1 2 (3 (4)) 5))
12345= 5



3.5.23. (rmapcar f l1...ln)
[DX]


See: (mapcar f l1 ... ln )
rmapcar works like mapcar , but is able to recursively scan sublists in l1 .. ln .

Example:

? (rmapcar 'prin '(1 2 (3 (4)) 5))
12345= (1 2 (3 (4)) 5)



3.5.24. (each ((s1 v1) ... (sn vn)) l1 ... ln)
[DY]


For i=1 till (length v1) this function performs the let function

The lists v1 till vn should have the same length. This function returns the result of the last evaluation. Example:

? (each ((i '(1 2 3 5 7)))
    (print i (sqrt i)) )
1 1
2 1.4142
3 1.7321
5 2.2361
7 2.6458
= 2.6458



3.5.25. (all ((s1 v1) ... (sn vn)) l1 ... ln)
[DY]


Like each but returning the list of all evaluation results rather than just the last one.

Example:

? (all ((i '(1 2 3 5 7)))
    (sqrt i) )
= (1 1.4142 1.7321 2.2361 2.6458)