【问题标题】:scheme macro produces unexpected result方案宏产生意想不到的结果
【发布时间】:2012-02-29 17:06:42
【问题描述】:

有人知道为什么以下会产生预期的结果 - (2 4 6)

(defmacro mult2 (lst)
  (define (itter x)
    (list '* 2 x))
  `(list ,@(map itter lst))) 

(mult2 (1 2 3))

虽然我预计这个会(带有列表标识符)

(defmacro mult2 (lst)
  (define (itter x)
    (list '* 2 x))
  `(list ,@(map itter lst)))

(mult2 '(1 2 3))

【问题讨论】:

    标签: macros scheme racket


    【解决方案1】:

    不评估宏“参数”。所以,当你传入'(1 2 3),即(quote (1 2 3)),这正是宏所看到的。

    附:在 Scheme 中使用卫生宏会更好。这是一个使用syntax-case的示例:

    (define-syntax mult2
      (lambda (stx)
        (define (double x)
          #`(* 2 #,x))
        (syntax-case stx ()
          ((_ lst)
           #`(list #,@(map double (syntax-e #'lst)))))))
    

    (这仍然不是这样一个宏的惯用方式,但我试图尽可能地反映您的版本。)

    【讨论】:

      【解决方案2】:

      这是因为'(1 2 3) 被读者扩展为(quote (1 2 3))。由于您只在宏中解构了一个列表,因此它不会按预期工作。

      一些一般性建议:如果您在 Racket 中工作,您可能希望避免使用 defmacro。这绝对不是编写宏的惯用方式。看看syntax-rules,如果你想定义更复杂的宏,syntax-parse。 Eli 还写了一个 article 为习惯于定义宏的人解释语法案例。

      【讨论】:

      • 非常感谢!!你确实为我节省了几个小时。
      猜你喜欢
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-07
      • 1970-01-01
      • 2016-06-20
      • 2011-06-04
      • 1970-01-01
      相关资源
      最近更新 更多