Common Lisp には、(do *vars* *test* *body*)
;の逐次形式があります。letの 順次 parallel とlet*
同じよう*vars*
に、一度に 1 つずつ処理されるため、以前に定義した変数を次のように参照できます。
(do* ((a '(1 2 3) (cdr a))
(b (mapcar (lambda (x) (1+ x)) a) (cdr b)))
((= 1 1) (list 'a a 'b b)))
; (a (1 2 3) b (2 3 4))
スキームでは、知る限り、相関する関数やマクロはありません。ありますがdo
、ありませんdo*
。私はdo*
チキンスキームの実装を書こうとしてきましたが、これまでのところ、前進するのに苦労しています...私は本当にわからないと思います。私は Chicken Scheme に精通していますが、Scheme マクロはいつも混乱を招きます。
ここに私がこれまでに持っているものがあります:
(##sys#extend-macro-environment
'do*
'()
(##sys#er-transformer
(lambda (form r c)
(##sys#check-syntax 'do* form '(_ #((symbol _ . #(_)) 0) . #(_ 1)))
(let* ((bindings (cadr form))
(test (caddr form))
(body (cdddr form))
(do*var (r 'doloop)))
`(let*
,do*var
,(##sys#map (lambda (b) (list (car b) (car (cdr b)))) bindings)
(##core#if ,(car test)
,(let ((tbody (cdr test)))
(if (eq? tbody '())
'(##core#undefined)
`(##core#begin ,@tbody) ) )
(##core#begin
,(if (eq? body '())
'(##core#undefined)
`(##core#let () ,@body) )
(##core#app
,do*var ,@(##sys#map (lambda (b)
(if (eq? (cdr (cdr b)) '())
(car b)
(car (cdr (cdr b))) ) )
bindings) ) ) ) ) ) ) ) )
しかし、リストではないなどのエラーが発生し続けdoloop
ます-現在、私は取得しています
Error: during expansion of (do* ...) - in `do*' - symbol expected: (do* ((a (quote (1 2 3)) (cdr a)) (b (map (lambda (x) (+ 1 x)) a) (cdr b)) ((= 1 1) (list (quote a) a (quote b) b))))
Call history:
<syntax> (do* ((a (quote (1 2 3)) (cdr a)) (b (map (lambda (x) (+ 1 x)) a) (cdr b)) ((= 1 1) (list (quote a) a...
<eval> (##sys#check-syntax (quote do*) form (quote (_ #((symbol _ . #(_)) 0) . #(_ 1)))) <--
以下は、 HyerSpecdo*
から取得した Common Lispのラフです。
(block nil (let ((var1 init1) (var2 init2) ... (varn initn)) declarations (loop (when end-test (return (progn . result))) (tagbody . tagbody) (psetq var1 step1 var2 step2 ... varn stepn))))
do* は似ていますが、let* と setq がそれぞれ let と psetq を置き換えている点が異なります。
do*
CL での展開は次のとおりです。
(expand-form '(do* ((a '(1 2 3) (cdr a))
(b (mapcar (lambda (x) (1+ x)) a) (cdr b)))
((= 1 1) (list 'a a 'b b))))
(block nil
(let* ((a '(1 2 3)) (b (mapcar #'(lambda (x) (declare (system::source ((x) (1+ x)))) (1+ x)) a)))
(tagbody #:loop-5382 (if (= 1 1) (go #:end-5383)) (setq a (cdr a) b (cdr b)) (go #:loop-5382) #:end-5383 (return-from nil (list 'a a 'b b))))) ;
;t