moshとYpsilonでスコープが異なるケース

追記 : 同じpsyntaxベースのikarusでも動くので、moshの実装上の都合かもしれない。
追記 : わかりづらいので手で展開した。

(import (rnrs))

(define (tx x) (+ 1 x))
(define (tp p)
    (syntax-case p ()
      ((k arg)
       (datum->syntax (syntax k) (tx (syntax->datum (syntax arg)))))))

(define-syntax tt tp)

(display (tt 2))(newline)

moshでは動作せず(define-syntaxにてtpがスコープ外)、Ypsilonでは動作する。直感的にはYpsilonの動作が正しいように思える。

以前の内容

先日のdefine-macro( http://d.hatena.ne.jp/mjt/20090701/p2 )を使った場合、スコープがmoshとYpsilonで異なるケースを見つけた。

(define (tx x) (+ 1 x))
(define-macro (tt x) (tx x))

(display (tt 2))(newline)

先日のdefine-macroを使ってこのようなコードを書いたとき、

$ mosh check.scm
 Condition components:
 1. &who           who: tx
 2. &message       message: "identifier out of context"
 3. &syntax        form: tx
                   subform: #f

のようにmoshではtxが参照できない。moshでtxを呼ぶためには、txの定義をdefine-macroの内側で行う必要が有る。つまり、

(define-macro (tt x)
  (define (tx x) (+ 1 x))
  (tx x)))

これは動作する。

  • Ypsilon
$ Ypsilon --sitelib=.\\ check.scm
3

Ypsilonでは呼び出せる。
要するに、スコープの取り扱いが :

  • mosh : define-macroを書いたところ
  • Ypsilon : define-macroを使ったところ

という違いになっている。