[英]Why doesn't Dr. Racket expand nested macros?
我正在使用5.3.1版的Racket博士。 我正在嘗試使用宏步進器功能,“嵌套”宏有問題。 (通過“嵌套”宏,我的意思是宏擴展為包含更多(使用定義的)宏的形式。我不知道這是否是正確的術語)。 宏步進器只將這些宏擴展一次,然后再繼續擴展就不再麻煩了。
例如,我在Dr. Racket定義區域中鍵入以下內容:
#lang racket
(define-syntax foo
(syntax-rules ()
((foo a) 1)
((foo a stuff ...) (+ 1 (foo stuff ...)))))
(foo a b c d e)
運行此程序將按預期返回5。 此外,在“交互”窗口中輸入(expand '(foo abcde))
產生語法'(#%app + '1 (#%app + '1 (#%app + '1 (#%app + '1 '1))))
,也符合預期。 但是,進入宏步進器(隱藏標准宏)並按“ End
按鈕,我只會看到(+ 1 (foo bcde))
。 如果禁用宏隱藏,則可以得到預期的結果,但也會產生很多我不希望看到的線路噪聲。
這是錯誤還是預期的行為? 我發誓Racket博士以前就沒有這種行為...
我實際上是在一個月前提交了與此有關的錯誤報告( http://bugs.racket-lang.org/query/?cmd=view&pr=13203 ),但是隨后我開始重新考慮是否是錯誤,所以我決定在這里問。
PS-關於此的其他隨機注釋:
它似乎取決於嵌套宏是否是擴展形式中的最外面的表達式。 例如,如果我定義(除了foo):
(define-syntax bar
(syntax-rules ()
((bar xs ...) (foo xs ...))))
(define-syntax baz
(syntax-rules ()
((baz xs ...) (bar xs ...))))
(baz a b c d e)
然后宏步進器顯示(baz abcde)
擴展到(bar abcde)
到(foo abcde)
到(+ 1 (foo bcde))
,但隨后停止。
前面的示例可能使您認為它與擴展到自身的宏有關,但事實並非如此。 例如,如果我按以下方式重新定義foo:
(define-syntax foo
(syntax-rules ()
((foo a) 1)
((foo a stuff ...) (+ 1 (blah stuff ...)))))
用
(define-syntax blah
(syntax-rules ()
((blah xs ...) 10)))
然后(foo abcde)
擴展為(+ 1 (blah bcde))
,然后停止。
我不確定這是否是錯誤,盡管擴展代碼中的foo與原始foo的顏色不同,所以我傾向於認為這是造成混淆的原因。
默認情況下,宏步進器會嘗試簡化擴展宏以僅顯示模塊中定義的宏以及字符串所需的文件(即來自“項目”的文件)。 這個功能似乎正在拋棄它。
解決此問題的一種方法(至少在較小的文件中)是禁用此功能。 為此,請轉到窗口左下方顯示的內容: Macro hiding:
,單擊下拉菜單並選擇Disable
。
Macro hiding:
-> Disable
從那里,您應該看到模塊的整個擴展,包括foo
的擴展。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.