Схема макроса дает неожиданный результат - PullRequest
2 голосов
/ 29 февраля 2012

Кто-нибудь знает, почему следующее дает ожидаемый результат - (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 ]

4 голосов
/ 29 февраля 2012

Макрос "аргументы" не оцениваются.Таким образом, когда вы передаете '(1 2 3), то есть (quote (1 2 3)), это именно то, что видит макрос.

PS Вам гораздо лучше использовать гигиенические макросы в Scheme.Вот пример использования syntax-case:

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

(Это по-прежнему не так, как идиоматически написан такой макрос, но я попытался отразить вашу версию как можно точнее.)

3 голосов
/ 29 февраля 2012

Это потому что '(1 2 3) расширяется читателем до (quote (1 2 3)).Поскольку вы деструктурируете только один список в макросе, он не будет работать должным образом.

Несколько общих советов: если вы работаете в Racket, вам, вероятно, следует избегать использования defmacro.Это определенно не идиоматический способ написания макросов.Взгляните на синтаксические правила и, если вы хотите определить более сложные макросы, синтаксический-синтаксический анализ .Илай также написал статью , в которой объясняется синтаксический случай для людей, привыкших к defmacro.

...