リンクhttp://www.ccs.neu.edu/home/ryanc/macro-stepper/tutorial.htmlには、マクロ ステッパーを使用するための説明があります。
しかしいざやってみると非ゼロの定義で myor の二次展開が取れない?関数、最初のみ。また、「前学期」「次学期」のボタンもありません。
私の質問は次のとおりです。チュートリアルのように、2番目の拡張を取得するにはマクロステッパーをどのように構成する必要がありますか?
リンクhttp://www.ccs.neu.edu/home/ryanc/macro-stepper/tutorial.htmlには、マクロ ステッパーを使用するための説明があります。
しかしいざやってみると非ゼロの定義で myor の二次展開が取れない?関数、最初のみ。また、「前学期」「次学期」のボタンもありません。
私の質問は次のとおりです。チュートリアルのように、2番目の拡張を取得するにはマクロステッパーをどのように構成する必要がありますか?
ソースプログラムは次のようになっていると思います。
#lang racket
(define-syntax myor
(syntax-rules ()
[(myor e) e]
[(myor e1 . es)
(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
短い話:今のところ、 syntax-rulesではなくsyntax-caseを使用してください。マクロ ステッパーと構文規則に関連するバグがあるようです。Racket 開発者にバグ レポートを送信したので、これがすぐに修正されることを願っています。上記のプログラムの構文ケースバージョンは次のようになります。
#lang racket
(define-syntax (myor stx)
(syntax-case stx ()
[(_ e) #'e]
[(_ e1 . es)
#'(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
以下、話が長くなりますが…
5.2.1 のプレリリースでプログラムを実行すると、マクロ ステッパーに次のように表示され、マクロの非表示が「標準」に設定されています。
(module anonymous-module racket
(#%module-begin
(define-syntax myor
(syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(let:26 ([r:26 (negative? r)]) (if:26 r:26 r:26 (myor:26 (positive? r)))))))
これは間違っているように見えます。myorの 1 つの使用のみをifの使用に拡張します。非常に奇妙な!
Racket 5.2 でどのように見えるか見てみましょう...
(module anonymous-module racket
(#%module-begin
(define-syntax myor
(syntax-rules () [(myor e) e] [(myor e1 . es) (let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r) (let ([r (negative? r)]) (if r r (myor (positive? r)))))))
ああ。OK、Racket 5.2 とプレリリースで見られるのと同じ問題が見られることを確認できます。
このバグは、「マクロの非表示」機能の動作に関連しているようです。これは、標準に設定されているときに完全な拡張で圧倒されないようにします。これを「無効」に設定すると、マクロ デバッガーが展開をそのままの状態で完全に表示し、期待どおりの展開が含まれていることがわかります。
(module anonymous-module racket
(#%module-begin
(define-syntaxes (myor)
(lambda (x)
; ... I'm omitting the content here: it's way too long.
))
(define-values:20 (nonzero?)
(lambda:21 (r) (let-values:22 (((r) (#%app:23 negative? r))) (if r r (#%app:24 positive? r)))))))
バグレポートを書き、Racket 開発者に送信します。
syntax-rulesではなく、syntax-caseを使用してマクロを作成すると、Macro Stepper でより適切に機能するように見えます。
#lang racket
(define-syntax (myor stx)
(syntax-case stx ()
[(_ e) #'e]
[(_ e1 . es)
#'(let ([r e1]) (if r r (myor . es)))]))
(define (nonzero? r)
(myor (negative? r)
(positive? r)))
これをステップ実行すると、はるかにうまく機能するように見えます。したがって、バグの原因が何であれ、マクロ ステッパーとsyntax-rulesとの相互作用のようです。そのため、代わりに構文ケースを使用してみてください。
追加の操作をしなくてもうまくいきました。ラケットの最新バージョンを試し、メニューから別の言語を選択してみて、debugging
選択した言語が選択されていることを確認してください。