【问题标题】:Why use a Lambda-notation instead of normal notation为什么使用 Lambda 符号而不是普通符号
【发布时间】:2019-10-10 12:40:02
【问题描述】:
我们正在为一个班级学习 Racket 的一个子集。随课附上的书总是使用 lambda 的内部 (define f (lambda () E)) 而不是 (define f E)。
有什么好的理由吗?似乎没有必要在里面有一个匿名函数。
(define plus-one (+ 0 1))
(define plus-one-l (lambda () (+ 0 1)))
第一个在调用加一后返回 1,另一个说它是一个过程,在它周围使用 () 也返回 1。
但是为什么你更喜欢这个过程而不是仅仅拥有价值呢?
【问题讨论】:
标签:
lambda
scheme
racket
computer-science
lambda-calculus
【解决方案1】:
为什么要使用 lambda?
要回答您标题中的问题,我们将使用 lambda,因为我们需要一个过程或函数,而不是值。这就是 Racket 定义函数的方式。
如您所见,第一行将值 1 分配给 plus-one,而第二行将向 plus-one-l 分配 0 到 1 的过程。
为什么你更喜欢过程而不是仅仅拥有价值?
这是一个不好的例子,因为这个过程总是会返回相同的值,但是想象一下我们想要一个函数对任何数字加一。那么我们会有这样的东西:
(define plus-one-n (lambda (n) (+ n 1)))
现在我们可以调用(plus-one-n 3) 获取4,或(plus-one-n 1336) 获取1337。
如果我们发现自己在不同的地方重复相同的代码,那么不带任何参数的过程很有用。如果我们需要多次将 1 加到 0,我们可以将该代码分组到一个过程中,然后调用它。如果我们随后需要更改所有代码,我们只需要更改过程的主体。因此,如果我们的需求发生了变化,以至于我们现在想要将 2 加到 0,我们只需要更改过程的主体(尽管在这种情况下我们可能还想更改名称)。
【解决方案2】:
延迟评估。
没有参数的 lambda 被称为“thunk”。 Thunk 可用于:
- 无限惰性流:
(define-syntax-rule (cons-stream x y)
(cons x (lambda () y)))
(define ones (cons-stream 1 ones))
- 作为对象的函数:
(define (f x)
(lambda () x))
(define a (f 2))
(a) ; --> 2