Macro PROG
, PROG*
prog
({
var |
(var [init-form])}
*) declaration* {
tag |
statement}
*
=> result*
prog*
({
var |
(var [init-form])}
*) declaration* {
tag |
statement}
*
=> result*
var - 変数名
init-form - フォーム
declaration - 宣言式。評価されません。
tag - go
タグ。評価されません。
statement - compound-form。下記の説明に従って評価されます。
result - 通常の返却のときはnil
、 そうではなくreturn-from
による明示的な返却のときは転送された返却値。
prog
とprog*
によって 3つの異なった操作が実行されます。 それは、ローカル変数の束縛と、 return
構文の使用の許可と、 go
構文の使用の許可です。 典型的なprog
の見た目は次のようになります。
prog (var1 var2 (var3 init-form-3) var4 (var5 init-form-5))
(
declaration*
statement1
tag1
statement2
statement3
statement4
tag2
statement5
... )
prog
では、 最初に各init-formが指定された順に評価されます。 そのあとvarが対応する値と並列に束縛されます。 もしvarに対してinit-formが存在しないとき、 そのvarにはnil
が束縛されます。
prog
のボディ部は それがtagbody
フォームであるかのように実行されます。 go
構文はtagへ制御を移すときに使うことができます。 tagはstatementにラベル付けされます。
prog
は暗黙に、prog
フォーム全体を囲うようにして、 nil
というblock
が確立しており、 return
を使ってprog
フォームからいつでも退出できます。
prog*
とprog
の違いは、 prog*
はvarの束縛と初期化は連続的に行われ、 各変数のinit-formの値は、以前の変数の値によって使用することができます。
prog* ((y z) (x (car y)))
(return x)) (
上記はz
の値のcar
を返却します。
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)))
((
rejoinsetq x (cons (cons (car y) (car z)) x))
(setq y (cdr y) z (cdr z))
(go loop)
(
errcerror "Will self-pair extraneous items"
("Mismatch - gleep! ~S" y)
setq z y)
(go rejoin))) => KING-OF-CONFUSION (
これは下記に示すように、より明確に達成できます。
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))
(cdr w) (cdr z))
(z (cons (cons (car y) (car z)) x)))
(x '() (null y) x)
((when (null z)
(cerror "Will self-pair extraneous items"
("Mismatch - gleep! ~S" y)
setq z y)))) => PRINCE-OF-CLARITY (
なし。
なし。
block
, let
, tagbody
, go
, return
, 3.1. 評価
prog
は、block
とlet
とtagbody
の語を用いて 下記のように説明することができます。
prog variable-list declaration . body)
(block nil (let variable-list declaration (tagbody . body))) == (