【问题标题】:Macro pattern not matching宏模式不匹配
【发布时间】:2016-04-14 20:00:33
【问题描述】:

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的错误信息在源码中

【问题讨论】:

    标签: macros scheme pattern-matching


    【解决方案1】:

    据我了解,第一个示例也不应该工作,事实上,我无法让它工作。我认为您不能在同一级别上使用两个椭圆。因此,定义类似的东西会更容易

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

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

    (define-syntax testclass
      (syntax-rules (public private)
        ((testclass public (var val) . rest)
         (testclass ((var val)) public . rest))
        ((testclass ((var val) ...) public (var1 val1) . rest)
         (testclass ((var val) ... (var1 val1)) public . rest))
        ((testclass lst public private . rest)
         (list (quote lst) (quote rest)))))
    

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

    【讨论】:

    • 你在执行什么方案?我使用的是 chicken,并且正在 IRC 上解决这个问题,我们使用两个椭圆肯定没有问题,其他人能够使用第一个示例
    • IE我正在与实现设计师交谈,他们说它在语法上是正确的。
    • 并且它也在 r5rs 中定义了行为
    • 省略号的使用没有定义R5RS/R7RS。请参见第 4.3.2 节(巧合的是,R5 和 R7 对此具有相同的节号)。如果你想编写可移植的代码,那么最好将椭圆分成 2 种模式。
    • @Anandamide 实现者对这个问题有什么要说的吗?据我所知,这两个示例在结构上是相同的。我能看到的唯一(可能相关的)区别是两个椭圆匹配的列表数量在示例一中是相同的,而在示例二中是不同的。
    猜你喜欢
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-13
    • 2021-05-22
    相关资源
    最近更新 更多