两个相似定义之间的差异 [英] Differences between two similar definitions

查看:40
本文介绍了两个相似定义之间的差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么区别吗

(define make-point cons)

(define (make-point x y)
  (cons x y))

?

一种比另一种更有效,还是完全等效?

Is one more efficient than the other, or are they totally equivalent?

推荐答案

这里有几个不同的问题.

There are a few different issues here.

正如 Oscar Lopez 指出的,一个是间接引用,一个是包装器.Christophe De Troyer 进行了一些计时 并指出,如果不进行优化,间接调用的时间可能是间接调用的两倍.那是因为别名使两个变量的 value 成为 same 函数.当系统评估 (cons …)(make-point …) 时,它会评估变量 consma​​ke-point 并取回 same 函数.在间接版本中,ma​​ke-pointcons 不是相同的功能.ma​​ke-point 是一个 函数,它再次调用 cons.这是两个函数调用而不是一个.因此速度可能是一个问题,但一个好的优化编译器可能能够使差异忽略不计.

As Oscar Lopez points out, one is an indirection, and one is a wrapper. Christophe De Troyer did some timing and noted that without optimization, the indirection can take twice as much time as the indirection. That's because the alias makes the value of the two variables be the same function. When the system evaluates (cons …) and (make-point …) it evaluates the variables cons and make-point and gets the same function back. In the indirection version, make-point and cons are not the same function. make-point is a new function that makes another call to cons. That's two function calls instead of one. So speed can be an issue, but a good optimizing compiler might be able to make the difference negligible.

但是,如果您以后能够更改这两个变量中的任何一个的值,则存在一个非常重要的区别.当您评估(定义make-point kons)时,您评估变量kons 一次并设置ma​​ke-point<的值/strong> 到您在该评估时间获得的one 值.当您计算 (define (make-point x y) (kons x y)) 时,您将 ma​​ke-point 的值设置为一个新函数.每次调用该函数时,都会评估变量 kons,因此会反映对变量 kons 的任何更改.我们来看一个例子:

However, there's a very important difference if you have the ability to change the value of either of these variables later. When you evaluate (define make-point kons), you evaluate the variable kons once and set the value of make-point to that one value that you get at that evaluation time. When you evaluate (define (make-point x y) (kons x y)), you're setting the value of make-point to a new function. Each time that function is called, the variable kons is evaluated, so any change to the variable kons is reflected. Let's look at an example:

(define (kons x y)
  (cons x y))

(display (kons 1 2))
;=> (1 . 2)

现在,让我们写一个间接和别名:

Now, let's write an indirection and an alias:

(define (kons-indirection x y)
  (kons x y))

(define kons-alias kons)

这些现在产生相同的输出:

These produce the same output now:

(display (kons-indirection 1 2))
;=> (1 . 2)

(display (kons-alias 1 2))
;=> (1 . 2)

现在让我们重新定义 kons 函数:

Now let's redefine the kons function:

(set! kons (lambda (x y) (cons y x))) ; "backwards" cons

kons 周围的 wrapper 函数,即间接,看到 kons 的新值,但别名不会不是:

The function that was a wrapper around kons, that is, the indirection, sees the new value of kons, but the alias does not:

(display (kons-indirection 1 2)) 
;=> (2 . 1)  ; NEW value of kons

(display (kons-alias 1 2))
;=> (1 . 2)  ; OLD value of kons

这篇关于两个相似定义之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆