我正在阅读r5rs方案标准,发现begin()其实是一个库语法,也就是说可以由scheme自己定义,标准在标准末尾给出了实现。
我按照 r5rs 使用如下定义语法实现了 begin():
(define-syntax mybegin
(syntax-rules ()
((mybegin expr) expr)
((mybegin expr1 expr2 ...)
(let ((x expr1))
(mybegin expr2 ...)))))
然后我尝试使用函数来实现它,这是我的代码:
(define begin-func
(lambda (expr1 expr2)
((lambda (x) expr2) expr1)))
这是我的测试用例:
(define x 3)
(define y 3)
(mybegin
(set! x 4)
(set! x 5))
(begin-func
(set! y 4)
(set! y 5))
我使用#lang 方案在 MIT-SCHEME 和 Racket 中运行我的代码,x 在 MIT-SCHEME 和 Racket 中都是 5,但是,y 在 MIT-SCHEME 中是 4,而在 Racket 中是 5
所以,这是我的问题:
- 我们真的可以使用纯函数方案实现 begin() 吗?
- 我的代码有什么问题吗,无论是使用宏的代码还是使用函数的代码?
- 为什么相同的代码在 MIT-SCHEME 和 Racket 中表现不同?