方案:为什么重新定义预定义运算符时会出现这种结果?

10

我尝试使用guile重新定义scheme程序中的+运算符时,结果出乎意料。需要指出的是,这是在尝试理解语言的过程中发生的;这里并没有尝试编写一个有用的程序。

以下是代码:

(define (f a b) 4)

(define (show)
  (display (+ 2 2)) (display ",") (display (f 2 2)) (newline))

(show)
; guile & mit-scheme: "4,4"

(define (+ a b) 5)
(define (f a b) 5)

(show)
; mit-scheme: "5,5"
; guile: "4,5" - this "4" is the unexpected result

(define (show)
  (display (+ 2 2)) (display ",") (display (f 2 2)) (newline))

(show)
; guile & mit-scheme: "5,5"
在guile中,即使我重新定义了它,函数show仍使用+的预定义定义,但它使用+的新定义。我必须重新定义show才能让它识别+的新定义。在mit-scheme中,两个新定义都会立即被识别,这正是我期望发生的。此外,任何进一步的+定义都会被这两个解释器立即识别,而不需要重新定义show。
Guile和MIT Scheme背后发生了什么,使其以不同的方式绑定对这些重新定义的运算符的引用?
为什么这两个解释器之间会有差异?

有趣。+1 非常清晰地解释了问题。 - Justin Ardini
1个回答

7
看起来Guile错误地假设没有人会疯狂到重新定义+,并且正在优化折叠(+ 2 2) => 4,使得(display (+ 2 2))变成(display 4)。这就解释了为什么您需要重新定义show以反映您的新+
实际上,如果您首先在程序的最顶端执行(define (+ a b) 4),则Guile将不会进行该优化,您将获得与MIT Scheme相同的4,45,5
编辑:实际上,看起来Guile将优化+以引用其自己的本地+结构,这意味着即使您不使用常数(无常数折叠),您仍将无法像那样重新定义+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接