lam*_*kie 7 lisp scheme racket
在我的大学,我们不得不与Racket合作,因为我很喜欢它,我从No Starch购买了最近出版的书"Realm Of Racket".
到目前为止它很棒,但是,当他们试图解释eq时,我无法弄清楚它们在第4章中的含义是什么?作品:
这个想法似乎得到了书中的以下句子的证实:"eq?比较改变一个结构是否会改变其他结构......"太棒了!让我们将它与下面的Java代码进行比较:
Point p1 = new Point(5, 5);
Point p2 = p1;
System.out.println(p1 == p2); // true, since the reference has been copied.
System.out.println(p1.x); // 5
System.out.println(p2.x); // 5
p1.x = 42;
System.out.println(p1.x); // 42
System.out.println(p2.x); // Accordingly, 42
Run Code Online (Sandbox Code Playgroud)
让我们在Racket中尝试一下:
(define cons1 (cons 1 empty))
(define cons2 cons1)
(eq? cons1 cons2) ;; #t, since the refernce has been copied.
(set! cons1 (cons 2 empty))
cons1 ;; Returns '(2) - as expected.
cons2 ;; Still returns '(1).
Run Code Online (Sandbox Code Playgroud)
为什么?cons2指向cons1,它本身指向'(2).另外,他们不是只是说一改变另一个就等于他们是平等的吗?
显然,现在我不明白为什么这不会像预期的那样表现,因此,我看不出什么是eq?是在做.也许我错了,它与引用没有任何关系......
如果有人知道这一点,请分享你的智慧;)
有关如何eq?工作的技术说明,请查看当前的规范,您将找不到更详细的参考.或者干脆检查球拍的文档,关于这个问题,尤其是程序eq?,eqv?和equal?.关于你的问题 - 结果与Scheme代码中的预期和正确一样,让我们看看为什么.请注意,在Java中的这一行:
p1.x = 42;
Run Code Online (Sandbox Code Playgroud)
您正在修改的同一多数民众赞成由两个指向对象p1和p2.而在这一行:
(set! cons1 (cons 2 empty))
Run Code Online (Sandbox Code Playgroud)
您正在创建一个新的不同对象并设置cons1为指向它,但cons2仍指向旧对象.您可以在上一行之后确认,比较(eq? cons1 cons2)将返回#f.
关键是:这些例子并不等同.Java示例处理由两个不同引用指向的单个对象,而Scheme示例处理两个对象和两个引用.
为了进行比较,这里是一个与Java代码类似的Scheme示例,并按预期工作,因为在这里我们正在修改一个由两个引用指向的可变对象:
#lang racket
(require scheme/mpair) ;; `m` stands for "mutable"
(define p1 (mlist 5 5))
(define p2 p1)
(eq? p1 p2) ;; #t
(mcar p1) ;; 5
(mcar p2) ;; 5
(set-mcar! p1 42)
(eq? p1 p2) ;; #t
(mcar p1) ;; 42
(mcar p2) ;; 42
Run Code Online (Sandbox Code Playgroud)