ToC | DocOverview | CGDoc | RelNotes | Index | PermutedIndex
| Allegro CL

| ANSI Common Lisp 5 Data and Control Flow 5.3 Dictionary of Data and Control Flow
5.3.57 prog, prog* | Macro
  Syntax: prog (`{`var | (var [init-form])`}`*) {declaration}* `{`tag | statement`}`* {result}* prog* (`{`var | (var [init-form])`}`*) {declaration}* `{`tag | statement`}`* {result}* Arguments and Values: var - variable name. init-form - a form. declaration - a declare expression; not evaluated. tag - a go tag; not evaluated. statement - a compound form; evaluated as described below. results - nil if a normal return occurs, or else, if an explicit return occurs, the values that were transferred. Description: Three distinct operations are performed by prog and prog*: they bind local variables, they permit use of the return statement, and they permit use of the go statement. A typical prog looks like this:
       (prog (var1 var2 (var3 init-form-3) var4 (var5 init-form-5))
             {declaration}*
             statement1
        tag1
             statement2
             statement3
             statement4
        tag2
             statement5
             ...
             )
  For prog, init-forms are evaluated first, in the order in which they are supplied. The vars are then bound to the corresponding values in parallel. If no init-form is supplied for a given var, that var is bound to nil. The body of prog is executed as if it were a tagbody form; the go statement can be used to transfer control to a tag. Tags label statements. prog implicitly establishes a block named nil around the entire prog form, so that return can be used at any time to exit from the prog form. The difference between prog* and prog is that in prog* the binding and initialization of the vars is done sequentially, so that the init-form for each one can use the values of previous ones. Examples:
      (prog* ((y z) (x (car y)))
             (return x))
  returns the car of the value of `z`.
       (setq a 1)  1
       (prog ((a 2) (b a)) (return (if (= a b) '= '/=)))  /=
       (prog* ((a 2) (b a)) (return (if (= a b) '= '/=)))  =
       (prog () 'no-return-value)   NIL
       (defun king-of-confusion (w)
         "Take a cons of two lists and make a list of conses.
          Think of this function as being like a zipper."
         (prog (x y z)          ;Initialize x, y, z to NIL
              (setq y (car w) z (cdr w))
          loop
              (cond ((null y) (return x))
                    ((null z) (go err)))
          rejoin
              (setq x (cons (cons (car y) (car z)) x))
              (setq y (cdr y) z (cdr z))
              (go loop)
          err
              (cerror "Will self-pair extraneous items"
                      "Mismatch - gleep!  ~S" y)
              (setq z y)
              (go rejoin)))   KING-OF-CONFUSION
  This can be accomplished more perspicuously as follows:
       (defun prince-of-clarity (w)
         "Take a cons of two lists and make a list of conses.
          Think of this function as being like a zipper."
         (do ((y (car w) (cdr y))
              (z (cdr w) (cdr z))
              (x '() (cons (cons (car y) (car z)) x)))
             ((null y) x)
           (when (null z)
             (cerror "Will self-pair extraneous items"
                    "Mismatch - gleep!  ~S" y)
             (setq z y))))   PRINCE-OF-CLARITY
  See Also: block, let, tagbody, go, return, Section 3.1 Evaluation Notes: prog can be explained in terms of block, let, and tagbody as follows:
       (prog variable-list declaration . body)
          ==(block nil (let variable-list declaration (tagbody . body)))
Allegro CL Implementation Details: None.

© Franz Inc. All Rights Reserved - File last updated 2022-07-25