宏模式不匹配

时间:2016-04-14 20:00:33

标签: macros scheme pattern-matching

Full source

所以我有一个用于制作对象的宏,它的用法如下:

(define ob 
  (class (a 10) (b 20)
         (set-a! (lambda (x) (set! a x)))
         (set-b! (lambda (x) (set! b x)))
         (foo (lambda (x)
                (* (+ a b) (- a b))))))

(ob 'a) -> 10
(ob 'b) -> 20
(ob 'set-a! 50)
(ob 'a) -> 50
(ob 'foo) -> 2100

我为公共和私人成员添加了另一种模式,

(define ob
  (class private
         (a 10) (b 20)
         public
         (get-a (lambda (x) a))
         (set-a! (lambda (x) (set! a x)))))

这是有效的,但由于某种原因,它不符合这种模式:

(define ob2
  (class private
         (a 10) (b 20) (c '())
         public
         (get-a (lambda (x) a))
         (get-b (lambda (x) b))
         (set-a! (lambda (x) (set! a x)))
         (set-b! (lambda (x) (set! b x)))
         (push-c! (lambda (x)
                    (set! c (cons x c))))
         (pop-c! (lambda (x)
                   (if (not (eq? c '()))
                       (set! c (cdr c))
                       (error "stack empty!"))))))

尝试使用ob2的错误消息位于源

1 个答案:

答案 0 :(得分:2)

据我所知,第一个例子也不应该工作,事实上,我无法让它工作。我不认为你可以在同一级别上使用两个椭圆。因此,定义像

这样的东西会更容易
onchange="window.location.href='roadster.html'

但是,如果必须在相同的语法级别上完成所有操作,则可以通过递归应用宏来执行此操作,如下所示:

(define-syntax class
  (syntax-rules (public private)
    ((class (public (?var ?val) ...) (private  (?var1 ?val1) ...))
     (list  (list ?var ?val) ... (list ?var1 ?val1) ...))))

为了使其更加健壮,您必须为空的公共和私有表达式添加规则。