lisp - 情商如何?在 Racket 工作?

标签 lisp scheme racket

在我的大学里,我们不得不使用 Racket,因为我有点喜欢它,所以我从 No Starch 买了最近出版的书“Realm Of Racket”。

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

  1. 首先,他们解释了如何相等?比较两个值是否由相同的部分组成。好的,没问题,我明白了:equal? 与 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
    

    让我们在 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).
    

    为什么? cons2 指向 cons1,cons1 本身指向 '(2)。另外,他们不是说只要一改变就等于吗?

显然,现在我不明白为什么它没有按预期运行,因此,我不明白 eq? 在做什么。也许我错了,它与引用文献没有任何关系......

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

最佳答案

有关 eq? 工作原理的技术解释,请查看当前的 specification ,您找不到更详细的引用资料。或者简单地检查 Racket 的 documentation关于这个主题,特别是程序 eq?eqv?equal?。关于您的问题 - 结果符合预期并且在 Scheme 代码中是正确的,让我们看看为什么。请注意,在 Java 的这一行中:

p1.x = 42;

您正在修改p1p2 所指向的相同 对象。而在这一行中:

(set! cons1 (cons 2 empty))

您正在创建一个,不同的对象并设置 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

关于lisp - 情商如何?在 Racket 工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17572181/

相关文章:

sorting - lisp 中的非破坏性排序?

lisp - 元循环评估器,实现环境

lambda - 使用词法闭包的 Racket

Emacs 中的 Java 模式参数缩进

scheme - 打印列表的相邻副本(方案)

list - 检查列表中是否有一定数量的元素

macros - 如何在 lisp 中用 if 形式定义递归 cond 宏?

comparison - 如何测试Scheme中引用符号的相等性?

load - 如何(重新)加载 Racket (X)REPL 中的文件?

loops - 在 Racket 中通过循环附加的正确方法是什么?