Gauche > Archives > 2016/11/24

2016/11/24 17:27:36 UTCkaki
#
internalな define と define-syntax を組み合わせた時の怪しい挙動を見付けました。
#
(let ()
  (define (f x)
    (if x
        42
        ((m) (not x))))
  (define-syntax m
    (syntax-rules ()
      ((_)
       f)))
  (f #f))
;; *** ERROR: unbound variable: #<identifier user#f.347c300>
;; Stack Trace:
;; _______________________________________
;;   0  ((m) (not x))

(macroexpand-all '(let () (define (f x) (if x 42 ((m) (not x)))) (define-syntax m (syntax-rules () ((_) f))) (f #f)))
;; => (letrec ((f.1 (lambda (x.0) (if x.0 '42 (f (not x.0)))))) (f.1 '#f))
#
f の中の (m) の展開で挿入される f が正しくリネームされてないように見えます。m の定義時に f が見えていることを期待しているのですが、見えないことになっている気がします。これはバグでしょうか?
#
因みにRacketでは期待通りに動き、R7RSではinternalなdefine-syntaxは無いと思います(5.3.2節 "internal definitions can always be converted into a completely equivalent letrec* expression")。