一時識別子の生成


Tags: R6RS, マクロ

変数名のリストと多値を生成する式を受け取り、生成された値を変数に代入する set!-values を考える。

(import (rnrs))

(define-syntax set!-values
  (lambda (x)
    (syntax-case x ()
      ((_ (var vars ...) expr)
       (with-syntax (((t ts ...) (generate-temporaries #'(var vars ...))))
         #'(let-values (([t ts ...] expr))
             (set! var t)
             (set! vars ts) ...))))))

手続き generate-temporaries は引数として受け取ったリストと同一個数の一時識別子のリストを返す。これと同じことは syntax-rules を用いても可能だが多少手間がかかる。

(library (set!-values aux)
  (export %set!-values)
  (import (rnrs))

  (define-syntax %set!-values
    (syntax-rules ()
      ((_ () (ts ...) (vs ...) expr)
       (let-values (([ts ...] expr))
         (set! vs ts) ...))
      ((_ (v vs ...) (ts ...) (ws ...) expr)
       (%set!-values (vs ...) (x ts ...) (ws ... v) expr))))
  )

(import (rnrs) (for (set!-values aux) expand))

(define-syntax set!-values
  (syntax-rules ()
    ((_ (v vs ...) expr)
     (%set!-values (v vs ...) () () expr))))