方案符号等价
我正在使用的平台是 DrScheme。
我已经看到一对 (ab)
[由 (cons ab)
构造] 在语言中实现,就像这样的过程:
(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 只是一个列表(即,一个过程等...),就像我所描述的 abode 一样,但是... l1 是什么?一个符号?字符序列?不管它是什么,它是如何在语言中实现的? 谢谢!
The platform i'm working with is DrScheme.
I've seen that a pair (a b)
[constructed by (cons a b)
] is implemented within the language like a procedure that looks like this:
(define (cons a b)
(lambda(pick)
(cond ((= pick 1) a)
((= pick 2) b))))
and the selectors:
(define (car x) (x 1))
(define (cdr x) (x 2))
Then there are lists, constructed with expression like (cons a (cons b (cons c (cons ...))))
.
Now, what i was trying to understand is this (typed on DrScheme's prompt):
> (define l1 '(a b c))
> (define l2 (list 'a 'b 'c))
> l1
(a b c)
> l2
(a b c)
> (eq? l1 l2)
#f
Ok, l2 is just a list (that is, a procedure, ect...) like i've described abode, but... what is l1? A symbol? A sequence of character? And whatever it is, how is it implemented within the language?
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
l1
也只是一个包含相同元素的列表。请注意,这也会返回#f
:而这会返回
#t
:原因是
eq?
检查是否l1
和l2
是对内存中同一对象的引用,而equal?
检查它们是否具有相同的内容。l1
is also just a list containing the same elements. Note that this also returns#f
:While this returns
#t
:The reason is that
eq?
checks whetherl1
andl2
are references to the same object in memory, whileequal?
checks whether they have the same contents.列表不是原子,这是这里的重要部分。符号虽然是原子,这意味着当它们相同时,它们驻留在同一内存中,它们就像数字一样,并且确实可以被视为指针。符号也不可变,符号
foo
就像数字3
。然而,列表不是原子,具有相同内容的向量的两个列表或字符串可以很好地驻留在内存的两个不同位置。
eq?
仅测试内存位置。eqv?
测试等价性,这是什么是模糊的,这取决于哪个实现,Scheme 标准对此相当自由,它只说它必须至少是eq 的超集?基本上。另一方面,
equal?
测试结构相等性并递归地执行此操作,因此这是一个非常昂贵的操作,这就是为什么符号通常比字符串更适合作为标识符。另外,有一点术语,cons 创建一个对,这与两个元素的列表不同,它创建一个对
(a . b)
列表(ab)
实际上与(a . (b . ()))对相同
另外,cons、car 和 cdr 都是原语,您在下面看到的实现是结构和实现中的演示计算机程序表明它们并不是严格需要的,但将它们作为原语可以显着提高性能,因此最好不要重新定义您的缺点、汽车和 cdrs。
Lists are not atoms, that's the important part here. Symbols though are atoms, that means that when they are the same, they reside in the same memory, they are like numbers and can indeed be seen as pointers. Symbols are not mutable too, a symbol
foo
is like a number3
.Lists however are not atoms, two lists, or strings, of vectors with the same contents can very well reside into two different places of memory.
eq?
tests on memory location only.eqv?
tests in equivalence, what that is is vague and it depends on which implementation, the Scheme standard is fairly liberal with this, it only says that it must at least be a superset ofeq?
basically.equal?
on the other end tests on structural equality and does so recursively, so it's a very expensive operation and that's why symbols are often preferred to strings for identifiers.Also, a bit of terminology, cons creates a pair, this is different from a list of two elements, it creates a pair
(a . b)
the list(a b)
is in fact identical to the pair(a . (b . ()))
Also, cons and car and cdr are primitives, the implementation you see below is the demonstration in Structure and Implementation of Computer Programs that shows they aren't strictly needed as them, but having them as primitives dramatically increases performance, so better not re-define your cons, car and cdrs.
定义具有以下形式:
(define <名称> <表达式>)
在运行时,表达式<表达式>被评估,结果是一个值。。术语是
该值存储在内存中的某个位置。为了使用这个值
其他计算,可以使用名称
<名称>与值绑定。
需要注意的重要一点是,名称是只出现在你的
源代码。它在运行时不存在。询问名字 l1 是否是
因此,符号是没有意义的。
编译器翻译的一种可能策略(定义<名称><表达式>)
如下(忽略Scheme实现具有垃圾收集)。
请注意,名称是没有出现在这个列表中。
A definition has the form:
(define <name> <expression>)
At runtime the expression <expression> is evaluated, and the result is a value.
That value is stored somewhere in memory. In order to use this value in
other calculations, one can use the name <name>. The termininology is that
<name> is bound to the value.
The important thing to note is, that the name <name> only appears in your
source code. It is not present at runtime. Asking whether the name l1 is
a symbol therefore makes no sense.
One possible strategy for a compiler to translate (define <name> <expression>)
is as follows (ignoring that Scheme implementations have garbage collection).
Note, that the name <name> does not appear in this list.