XLISP progv

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference

# progv

Type: | - | special form (fsubr)
Source: | - | xlcont.c

## Syntax

(progv symbols values [expr1 expr2 ... ])
  symbols - a list of symbols to be bound
  values - a list of values to be bound to symbols
  exprN - expressions for the body of the loop
  returns - the value of the last expression

## Description

The 'progv' special form is basically a 'block' construct that contains a block of code [expressions] to evaluate. 'progv' is different from prog1, prog2 and progn in that it contains a pair of lists, 'symbols' and 'values'. Before evaluating the expressions, 'progv' will dynamically bind the 'values' to the corresponding 'symbols'. If there are too many 'symbols' for the 'values', the 'symbols' with no corresponding 'values' will be bound to NIL. The variables will be unbound after the execution of 'progv'. The value of the last 'expr' will be returned as the result of 'progv'. If there are no 'exprs', NIL is returned.

## Examples

    > (progv '(var) '(2)
        (print var)
        (print "two"))
    2      ; output of PRINT
    "two"  ; output of PRINT
    "two"  ; return value

    > (setq a "beginning")   ; initialize A
    "beginning"

    > (progv '(a) '(during)  ; bind A to a new value
        (print a))
    DURING  ; output of PRINT
    DURING  ; return value     restore A the original value

    > (print a)
    "beginning"              ; prints the original value
    "beginning"

    > (progv '(no-way) '(no-how))
    NIL

    > (progv)
    error: too few arguments

Note: 'progv' is different from prog, which allows symbols and initialization forms, in that 'progv' allows its 'symbols' and 'values' to be evaluated. This allows you to pass in forms that generate the 'symbols' and their 'values'.

Note: prog1, prog2, progn and 'progv' do not allow the use of return or go or tags for go.

Important: In contrast to all other binding constructs, 'progv' binds global variables and not lexical variables, so 'progv' behaves like:

    (defun progv (symbols values &rest body)  ; this function does
      (push symbol-values *internal-stack*)   ; not really work,
      (setq symbols values)                   ; it only demonstates
      (prog1                                  ; the principle
        (eval body)
        (setq symbol-values (pop *internal-stack*))))

Variables bound by 'progv' can be manipulated by global functions including symbol-value. All changes to the 'progv' variables by other functions, called in the 'progv' body, will be lost after 'progv' is finished, because the original value from the beginning of 'progv' will be restored. This can be good or bad, depending on the situation.

Back to Top

Nyquist / XLISP 2.0 - Contents | Tutorials | Examples | Reference