使用语法规则引入命名变量

时间:2018-04-23 13:18:17

标签: macros scheme chicken-scheme syntax-rules

我正在尝试编写一个带有语法规则的超小型面向对象系统,主要是为了学习它。无论如何,我试图引入一个“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
                    )
                )
            )
        )
    )
)

除了“这个”,我可以得到一切。似乎语法规则不允许变量引入。我思考我可以通过将其定义为语法规则中的文字之一来获得它,但这似乎不起作用。

下面是我的面向对象系统:

test_list = []
max_len = 1000
for i in range(max_len):
    test_list.append(np.random.randn(784))

这适用于除'nextnext之外的所有内容,当它试图引用“this”时会出错。

这是正确的方法吗?还有其他方法可以做到这一点吗?我认识到这有点不卫生,但这至少不是指定文字的一部分吗?

我在鸡计划以及R5RS模式的DrRacket中尝试了这个(其他模式对“这个”抱怨)。

以下是整个文件。你只需要“csi object.scm”

就可以在Chicken上运行它

https://gist.github.com/johnnyb/211e105882248e892fa485327039cc90

我还尝试使用let-syntax并使用(this)作为语法说明符来引用(this)变量。但是,就我所知,它并没有让我在语法重写中直接访问我自己的变量。

奖金问题:什么是查看语法规则转换结果以进行调试的简单方法?有没有办法让鸡(或其他东西)进行转化并吐出结果?我在DrRacket上尝试了一些东西,但它在R5RS模式下不起作用。

1 个答案:

答案 0 :(得分:1)

  

我认识到这有点不卫生,但至少不是指定文字的一部分吗?

不,文字存在,因此您可以按字面意思匹配关键字,例如=>else条款中的cond。它仍然是卫生的,因为如果=>else在词法上绑定到某个值,则优先:

(let ((else #f))
  (cond (else (display "hi!\n")))) ;; Will not print

现在,你可以编写一个非常繁琐的宏,它在任何可能的位置匹配this并在扩展中嵌套级别,但是它永远不会完整,并且它不会在词法上嵌套,要么。

-rules并且它在实现模块的情况下(一致地)不起作用(例如,正好在CHICKEN中我们已经Petrofsky extraction我们意外地打破了#34;此功能)

我建议写一个语法规则宏,在其输入中接受一个绑定到当前对象的标识符,然后编写一个简单的不卫生宏,用一个硬编码标识符{{来调用另一个宏。 1}}作为输入。

  

有什么简单的方法可以查看语法规则转换的结果以进行调试?有没有办法让鸡(或其他东西)进行转化并吐出结果?我在DrRacket上尝试了一些东西,但它在R5RS模式下不起作用。

在csi中,您可以使用this,但它只会进行一级扩展。

在每个Scheme实现中都有一个常见的技巧是更改宏定义以引用其输出。因此,它不会扩展到,x (macro-call),而是扩展到(foo)。这样,您可以在REPL中调用宏并立即查看其结果。