我与之合作的平台是Drscheme。

我已经看到一对 (a b)(cons a b)]在语言中像这样的过程中实现:

(define (cons a b)
  (lambda(pick)
    (cond ((= pick 1) a)
          ((= pick 2) b))))

和选择器:

(define (car x) (x 1))
(define (cdr x) (x 2))

然后是列表,以表达方式构造 (cons a (cons b (cons c (cons ...)))).

现在,我试图理解的是(在Drscheme的提示下输入):

> (define l1 '(a b c))
> (define l2 (list 'a 'b 'c))
> l1
(a b c)
> l2
(a b c)
> (eq? l1 l2)
#f

好的,l2只是我所描述的居所的列表(即一个过程,ect ...),但是... 什么 是L1吗?符号?一系列字符?无论是什么,它如何在语言中实现?谢谢!

有帮助吗?

解决方案

l1 也只是包含相同元素的列表。请注意,这也返回 #f:

(define l1 '(a b c))
(define l2 '(a b c))
(eq? l1 l2)

当这返回时 #t:

(define l1 '(a b c))
(define l2 (list 'a 'b 'c))
(equal? l1 l2)

原因是 eq? 检查是否 l1l2 是内存中对同一对象的引用,而 equal? 检查它们是否具有相同的内容。

其他提示

列表不是 原子, ,这是这里的重要部分。符号是原子,这意味着当它们相同时,它们驻留在相同的记忆中,就像数字一样,确实可以被视为指针。符号也不可变,一个符号 foo 就像一个数字 3.

但是,具有相同内容的向量的列表不是原子,两个列表或字符串,可以很好地驻留在两个不同的内存位置。

eq? 仅在内存位置进行测试。 eqv? 等价测试是模糊的,它取决于哪种实施,计划标准是相当自由的,它只说它至少必须是一个超集 eq? 基本上。 equal? 在另一端的结构平等测试中,并递归进行,因此这是一个非常昂贵的操作,这就是为什么符号通常比标识符的字符串更喜欢的原因。

(define l1 (list 1 2 3))
(define l2 (list 1 2 3))
(eq? l1 l2) ; ===> #f in most implementations
(equal? l1 l2) ; ===> #t in all implementations
(eqv? l1 l2) ; ===> #t in some implementations
(define l3 (cdr l1))
(define l4 (cdr l1))
(eq? l3 l4) ; ===> #t, this means that they 'share memory', if you change l3 or l4, l1 will change with it, beware. This is how car and cdr work, they do not copy.
(define l6 (cons 1 l4));
(eq? l1 l6) ; ===> #f again, cons does allocate new memory, but the tails may very well share it, s in this case, l6 does share its tail with all lists except l2 here in memory. 

另外,有点术语会创建一对,这与两个元素的列表不同,它创建了一对 (a . b) 名单 (a b) 实际上与这对相同 (a . (b . ()))

另外,缺点,汽车和CDR是原始的,您在下面看到的实施是 计算机程序的结构和实施 这表明它们并不是严格必需的,但是将它们作为原始素大大提高了性能,因此最好不要重新定义您的缺点,汽车和CDR。

> > (define l1 '(a b c))
> > (define l2 (list 'a 'b 'c))
> > l1 (a b c)
> > l2 (a b c)
> > (eq? l1 l2)
> #f

好的,l2只是我所描述的居所的列表(即一个过程,ect ...),但是...什么是l1?符号?一系列字符?无论是什么,它如何在语言中实现?谢谢!

一个定义具有以下形式:

(定义u003Cname>u003Cexpression>)

在运行时表达式u003Cexpression>进行评估,结果是一个值。该值存储在内存中。为了在其他计算中使用此值,可以使用该名称u003Cname>。术语是u003Cname>与值绑定。

要注意的重要一件事是,名称u003Cname>仅出现在您的源代码中。它在运行时不存在。因此,询问名称L1是否是符号,因此没有任何意义。

编译器翻译的一种可能策略(定义u003Cname>u003Cexpression>)如下(忽略计划实施的垃圾收集)。

  1. 为指针P保留一个记忆单元m
  2. 计算值V的输出代码
  3. 存储内存单元格中包含V的内存单元的地址。

注意,名称u003Cname>没有出现在此列表中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top