参数的不同处理:lambda 与方案中的定义



我有两个结构,我希望它们在功能上是相同的,但它们不是,我无法弄清楚为什么。

使用定义

(define (x2 . b)
(display b)
(newline))
(x2 3 4 5) => (3 4 5)

使用λ

((lambda (. b) 
(display b) 
(newline)) 
3 4 5) => Error: invalid use of `.'

在 R5RS 中,定义和 lambda 都接受 。为了使它们的行为相同,我可以像这样构造 lambda:

((lambda b
(display b)
(newline))
3 4 5) => (3 4 5)

这是报表对形式参数的定义中列出的有效结构之一。但是,如果我尝试将其与定义一起使用,则会导致参数编号不匹配错误。

(define (x2 b)
(display b)
(newline))
(x2 3 4 5) => Error: bad argument count

我以为(define (x y) y)只是(define x (lambda (y) y))的句法糖。似乎这只在大多数情况下是正确的。谁能解释不同行为的基本原理?

这些表达式表示具有固定参数的匿名过程:

(define (x y) y)
(define (x y z) z)

它们相当于:

(define x (lambda (y) y))
(define x (lambda (y z) z))

但是采取此过程,参数数量可变:

(define (x . y) y)

它只相当于:

(define x (lambda y y))

继续这些示例,此过程具有单个必需参数,其他参数是可变的:

(define (x y . z) z)

其等效形式为:

(define x (lambda (y . z) z))

因此,隐式/显式使用lambda来定义具有可变参数数的过程之间的语法略有不同,这就是在这种情况下使用点表示法的目的。

此外,像'( . b)这样的语法是无效的,因为在这种情况下,点表示法表示不正确的列表,即最后一个元素不是空列表的列表。另一方面,这是有效的:'(a . b).这就解释了为什么表达式(lambda ( . x) x)无效;鉴于(lambda (x) x)表示具有单个强制参数的匿名过程,我们只剩下(lambda x x)来表示只有可变数量的参数且没有强制参数的匿名过程。

据我所知,为什么事情会这样的唯一理由是按照惯例,可能是因为它更容易解析。

(. arguments)是无效的语法。点表示一对的两个部分之间的分离,这里没有第一部分。我确实看到你的意思是arguments这里,它根本不应该是一个列表。

定义如下所示:

(define (name . arguments)
..)

与以下相同:

(define name 
(lambda arguments
..))

一个带有一个参数的示例:

(define (name arg1 . arguments)
..)

成为

(define name 
(lambda (arg1 . arguments)
..))

原因很简单:(cdr '(name . arguments)) ; ==> arguments(cdr '(name arg1 . arguments)) ; ==> '(arg1 . arguments).

相关内容

  • 没有找到相关文章

最新更新