scheme macro产生意想不到的结果

时间:2012-02-29 17:06:43

标签: macros scheme racket

有人知道为什么以下产生预期结果 - (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))

2 个答案:

答案 0 :(得分:4)

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

P.S。你最好在Scheme中使用卫生宏。以下是使用syntax-case的示例:

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

(这仍然不是这样的宏是如何写出来的,但我试图尽可能地反映你的版本。)

答案 1 :(得分:3)

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

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