【问题标题】:racket expanding a macro which is in quoted list form球拍扩展了引用列表形式的宏
【发布时间】:2021-08-12 07:03:44
【问题描述】:

我有一个宏

(define-syntax-rule (with tag body)
    (string-append (format "<span class=\"~s\">" 'tag)
                    body
                    (format "</span>")))

> (display (with p "some text"))
<span class="p">some text</span>

这是想要的结果

我如何“宏观扩展”然后评估列表'(with p "some text")?这是一个示例,当我读取这些表单的文件并打算将它们全部展开时返回的内容。

eval 有效,但我知道这不是要走的路。

我知道有许多可用的 html 模板解决方案 - 但这里的目标不是 HTML - 不要问! :)

提前致谢

【问题讨论】:

    标签: macros racket eval


    【解决方案1】:

    Racket 没有这样的内置函数,但是添加起来很简单:

    (define (macroexpand form)
      (syntax->datum
         (expand-to-top-form
          form)))
    

    例子:

    > (macroexpand '(with p "some text"))
    '(string-append (format "<span class=\"~s\">" 'p) "some text" (format "</span>"))
    

    【讨论】:

    • 非常感谢 - 我不知道 expand-to-top-form。我已经编辑了我的问题(可以吗??)添加“然后评估” - 然后我如何动态评估现在扩展的宏。再次感谢
    • @user2162871 你能详细说明你为什么不想使用eval吗?
    • 它在交互式提示下对我有用(Racket 博士的交互窗口:&gt; (eval '(with p "foo")) =&gt; "&lt;span class=\"p\"&gt;foo&lt;/span&gt;",但如果我“运行”一个包含 with 宏和 (eval '(with p "foo")) 的文件,则不能. 这给出了一个错误 - with: unbound identifier; also, no #%app syntax transformer is bound in: with - 所以我想我也不太了解 Racket 中的 eval !感谢您的帮助,非常感谢
    • 我刚刚发现:stackoverflow.com/questions/20778926/… 这可能很有用...关于在使用 eval 时绑定命名空间...
    • @user2162871 是的,可以。将(define-namespace-anchor anc) (define ns (namespace-anchor-&gt;namespace anc)) 添加到您的文件中,然后您可以调用(eval '(with p "some text") ns)
    猜你喜欢
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 2016-06-06
    • 2013-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多