方案符号等价

发布于 2024-09-07 01:42:54 字数 678 浏览 8 评论 0原文

我正在使用的平台是 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魂归处 2024-09-14 01:42:54

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? 检查它们是否具有相同的内容。

l1 is also just a list containing the same elements. Note that this also returns #f:

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

While this returns #t:

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

The reason is that eq? checks whether l1 and l2 are references to the same object in memory, while equal? checks whether they have the same contents.

零時差 2024-09-14 01:42:54

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

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

eq? 仅测试内存位置。 eqv? 测试等价性,这是什么是模糊的,这取决于哪个实现,Scheme 标准对此相当自由,它只说它必须至少是 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. 

另外,有一点术语,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 number 3.

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 of eq? 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.

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

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.

彼岸花ソ最美的依靠 2024-09-14 01:42:54
> > (define l1 '(a b c))
> > (define l2 (list 'a 'b 'c))
> > l1 (a b c)
> > l2 (a b c)
> > (eq? l1 l2)
> #f

好吧,l2 只是一个列表(即过程等...),就像我所描述的那样
住所,但是... l1 是什么?一个符号?字符序列?无论如何
是,它是如何在语言中实现的?谢谢!

定义具有以下形式:

(define <名称> <表达式>)

在运行时,表达式<表达式>被评估,结果是一个值。
该值存储在内存中的某个位置。为了使用这个值
其他计算,可以使用名称。术语是
<名称>与值绑定。

需要注意的重要一点是,名称是只出现在你的
源代码。它在运行时不存在。询问名字 l1 是否是
因此,符号是没有意义的。

编译器翻译的一种可能策略(定义<名称><表达式>)
如下(忽略Scheme实现具有垃圾收集)。

  1. 为指针 p 保留一个存储单元 m
  2. 计算值 v 的输出代码 将
  3. 包含 v 的存储单元的地址存储在存储单元 m 中。

请注意,名称是没有出现在这个列表中。

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

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

  1. Reserve a memory cell m for a pointer p
  2. Output code that computes the value v of
  3. Store the address of the memory cell that contains v in the memory cell m.

Note, that the name <name> does not appear in this list.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文