球拍/方案 - 语法 - 案例

时间:2013-11-30 19:24:02

标签: macros scheme racket

我正在研究关于球拍宏的分类。在其中一个问题中,我们被要求定义一个宏观集!其行为如下:

(define x 3)
(define y 5)
(define z 7)
(my-set! (x (+ x y)))
(my-set! (x (+ x y)) (z 6))
x
13
y
5
z
6

我在syntax-case http://www.cs.indiana.edu/~dyb/pubs/tr356.pdf

上找到了这个有趣的文档

目前我的宏工作,但我正在尝试在文档的第10页上添加“挡泥板”,以抵御错误,例如其中一个变量不是标识符或其他任何内容。

这是我的代码:

(define-syntax my-set!
  (letrec ((all-ids?
            (λ (ls)
              (or (null? ls)
                  (and (identifier? (car ls))
                       (all-ids? (cdr ls)))))))
    (lambda (x)
      (syntax-case x ()
        ((_ (var val) (var2 val2) (var3 val3) ...)
         (all-ids? (syntax (var var2 var3 ...)))
         (syntax (begin (set! var val) (my-set! (var2 val2) (var3 val3) ...))))
        ((_ (var val))
         (syntax (set! var val)))))))

如果我在没有挡泥板的情况下测试这个确切的代码,它可以完美地运行。但是当我运行时:

(define a 1)
(define b 1)
(define c 1)

(my-set! (a 3) (b 4) (c 5))

我明白了:

  

汽车:合同违规预期:配对?
  给定:语法:C:\ Users \ mgiroux \ Desktop \ define-myset.rkt:40:26(a b c)

好像全友ids? (a b c)的cant(car)导致它不是一个列表?我尝试将其作为列表传递,但也没有工作,我似乎完全复制了他们在我链接的PDF格式中的方式..我在这里缺少什么?

1 个答案:

答案 0 :(得分:3)

#'(var var2 var3 ...)确实不是一个列表。它是一个包装列表的语法对象。您应该使用syntax->list将项目提取到列表中,因此您的后卫应该如下所示:

(all-ids? (syntax->list #'(var var2 var3 ...)))