私は(ちょうど下の例では簡略化のために拡大)を定義するだけのラケットのように動作するマクロを記述しようとしているが、いくつかの方法で完全に展開ラケットの手続きを処理しています:ラケット:ローカル・拡大再帰的定義
(define-syntax (define/expand stx)
(syntax-case stx()
[(_ (head args ...) body body-rest ...)
(let* ([define/racket (syntax/loc stx (define (head args ...) body body-rest ...))]
[fully-expanded (local-expand define/racket 'top-level (list))])
fully-expanded)]
[(_ id expr) (syntax/loc stx (define id expr))]))
再帰的定義が満たされない限り
すべてが正常である:
それは誤り合計提起実行
(define/expand (sum n) (if (<= n 0) 0 (+ n (sum (- n 1)))))
:unbouをNDにおけるモジュール識別子:合計
sum
のコール(定義ではない)を指します。明らかに、sum
の定義は、ローカルエクスパンダによってキャプチャされません。新しいローカル定義のコンテキストを作成し、その中にhead
を結合:私はそれを固定する簡単な方法を試してみた
(define-syntax (define/expand stx)
(syntax-case stx()
[(_ (head args ...) body body-rest ...)
(let* ([ctx (syntax-local-make-definition-context)] ; <- These two lines added
[_ (syntax-local-bind-syntaxes (list #'head) #f ctx)] ; <--/
[define/racket (syntax/loc stx (define (head args ...) body body-rest ...))]
[fully-expanded (local-expand define/racket 'top-level (list) ctx)])
fully-expanded)]
[(_ id expr) (syntax/loc stx (define id expr))]))
それは(地元の拡大に成功したdefine-values
に手続きを展開する)問題を解決するが、他のものを作成します。
モジュール:で定義のためのアウトコンテキスト識別子:和
和の定義を指します。なぜなら、エクスパンダは、現在のコンテキストではhead
ではなく、ctx
の識別子に識別子をバインドするからです。
直感的にはまれな問題ではないようですが、ネットワーク上で解決策を見つけることができませんでした。私は何とかlocal-expand/capture-lifts
とsyntax-local-lift-expression
を使うべきだと思っていましたが、正しく使用する方法はわかりません。誰かが何が起こっているかを明確にしたり、それを修正するヒントを与えたりできますか?
別時々、便利なトリック:パターンマッチ、その後、結合していない変数をバインドラムダに 'ローカルexpand'を呼び出します体を出すための結果。 –