【发布时间】:2018-04-23 13:18:17
【问题描述】:
我正在尝试使用语法规则编写一个超小型的面向对象系统,主要是为了学习它。无论如何,我正在尝试引入一个“this”变量。这是我想做的事情:
(oo-class Counter
(
(attr value 0)
(attr skip 1)
)
(
(method (next) (set! value (+ value skip)) value)
(method (nextnext) (this 'next) (this 'next))
(method (set-value newval) (set! value newval))
(method (set-skip newskip) (set! skip newskip))
)
)
(define c (Counter))
((c 'set-value) 23)
((c 'next))
((c 'nextnext))
除了“this”之外,我可以让一切正常工作。似乎语法规则不允许变量引入。我认为我可以通过将其定义为语法规则中的文字之一来获得它,但这似乎不起作用。
下面是我的面向对象系统:
(define-syntax oo-class
(syntax-rules (attr method this)
(
(oo-class class-name
((attr attr-name initial-val) ...)
((method (meth-name meth-arg ...) body ...) ...))
(define class-name
(lambda ()
(letrec
(
(this #f)
(attr-name initial-val)
...
(funcmap
(list
(cons (quote meth-name) (cons (lambda (meth-arg ...) body ...) '()))
...
)
)
)
(set! this (lambda (methname)
(cadr (assoc methname funcmap))
))
this
)
)
)
)
)
)
这适用于除 'nextnext 之外的所有内容,当它尝试引用“this”时会出错。
这是正确的方法吗?还有其他方法可以做到这一点吗?我承认这有点不卫生,但这至少不是指定文字的一部分吗?
我在 Chicken Scheme 和 DrRacket 的 R5RS 模式下都试过这个(其他模式会抱怨“this”)。
以下是整个文件。你可以用“csi object.scm”在Chicken上运行它
https://gist.github.com/johnnyb/211e105882248e892fa485327039cc90
我还尝试使用 let-syntax 并使用 (this) 作为语法说明符来引用 (this) 变量。但是,据我所知,它并没有让我在语法重写中直接访问我自己制作的变量。
奖励问题:查看语法规则转换结果以进行调试的简单方法是什么?有没有办法让鸡肉(或其他东西)进行转换并吐出结果?我在 DrRacket 上尝试了一些东西,但它在 R5RS 模式下不起作用。
【问题讨论】:
标签: macros scheme chicken-scheme syntax-rules