方案宏产生意想不到的结果

Posted

技术标签:

【中文标题】方案宏产生意想不到的结果【英文标题】: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))

【问题讨论】:

【参考方案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 为习惯于定义宏的人解释语法案例。

【讨论】:

非常感谢!!你确实为我节省了几个小时。

以上是关于方案宏产生意想不到的结果的主要内容,如果未能解决你的问题,请参考以下文章

流星空格键:#each 内的 #if 会产生意想不到的结果

使用“%”进行操作会产生意想不到的结果[重复]

R 用 lubridate 在 DST 上添加月份会产生意想不到的结果

MySQL - 使用 LEFT JOIN 会产生意想不到的结果

用 np.savez 存储字典会产生意想不到的结果?

使用 Javascript 设置元素的宽度会产生意想不到的结果