and-let*
の嫌なところを除いた let*-and
をマクロで実装をしてみた。syntax-case
でなく syntax-rules
での簡易実装だからユーザーが間違って使った場合のエラーを排除仕切れないけど差し当たりは良しとする。syntax-case
が良く分からないので。
仕様
-
let*-and :=
(let*-and (
束縛節…)
本体式…)
-
束縛節 :=
(
変数名)
-
束縛節 :=
(
変数名(where
条件式))
let*
と同じように、束縛節が左から右に順に処理される。
(wher
条件式)
がある場合は、次の束縛節が処理される前に条件式が評価されて、それが #f
なら次の束縛節の処理は実行されずに let*-and
全体の評価が終わる。その値は #f
になる。
それ以外の場合、最後に評価された(=最も右にある) 本体式
または 条件式
または 評価値が束縛される式
の値が let*-and
全体の評価値になる。
束縛節… も 本体式… もどちらも空にすることができて、両方が空の (let*-and ())
の評価値は #t
。
コード
(define-syntax let*-and
(syntax-rules (where)
((let*-and ())
; then
#t)
((let*-and (clause clauses ...))
; then
(let*-and
"let*-and clauses:" (clause clauses ...)
"let* clauses:" ()))
((let*-and (clauses ...) body bodies ...)
; then
(let*-and
"let*-and clauses:" (clauses ... ["begin" body bodies ...])
"let* clauses:" ()))
;; implements ...
((let*-and
"let*-and clauses:" (["begin" body bodies ...])
"let* clauses:" (let*_clauses ...))
; then
(let* (let*_clauses ...) body bodies ...))
((let*-and
"let*-and clauses:" ([var expr (where pred)])
"let* clauses:" (let*_clauses ...))
; then
(let* (let*_clauses ... (var expr)) pred))
((let*-and
"let*-and clauses:" ([var expr])
"let* clauses:" (let*_clauses ...))
; then
(let* (let*_clauses ... [var expr]) var))
((let*-and
"let*-and clauses:" ([var expr (where pred)] let*-and_clauses ...)
"let* clauses:" (let*_clauses ...))
; then
(let* (let*_clauses ... [var expr])
(and pred
(let*-and
"let*-and clauses:" (let*-and_clauses ...)
"let* clauses:" ()))))
((let*-and
"let*-and clauses:" ([var expr] let*-and_clauses ...)
"let* clauses:" (let*_clauses ...))
; then
(let*-and
"let*-and clauses:" (let*-and_clauses ...)
"let* clauses:" (let*_clauses ... [var expr])))))