怎么样?在Racket工作?

lam*_*kie 7 lisp scheme racket

在我的大学,我们不得不与Racket合作,因为我很喜欢它,我从No Starch购买了最近出版的书"Realm Of Racket".

到目前为止它很棒,但是,当他们试图解释eq时,我无法弄清楚它们在第4章中的含义是什么作品:

  1. 首先,他们解释了如何平等?比较两个值是否由相同的部分组成.好的,没问题,我明白了:平等?与Java的equals(someObject)方法完全相同.如果两个对象/结构/任何内容相同,则返回#t.
  2. 然后,我想,eq?必须等同于Java的==运算符,它不会按内容进行比较,而是基于引用.
  3. 这个想法似乎得到了书中的以下句子的证实:"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?是在做.也许我错了,它与引用没有任何关系......

如果有人知道这一点,请分享你的智慧;)

Ósc*_*pez 7

有关如何eq?工作的技术说明,请查看当前的规范,您将找不到更详细的参考.或者干脆检查球拍的文档,关于这个问题,尤其是程序eq?,eqv?equal?.关于你的问题 - 结果与Scheme代码中的预期和正确一样,让我们​​看看为什么.请注意,在Java中的这一行:

p1.x = 42;
Run Code Online (Sandbox Code Playgroud)

您正在修改的同一多数民众赞成由两个指向对象p1p2.而在这一行:

(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)