参数的不同处理方式:Lambda 与 Scheme 中的定义
Different treatment of parameters: lambdas vs. defines in Scheme
我有两个结构,我希望它们在功能上是相同的,但它们不是,我也不知道为什么。
使用定义
(define (x2 . b)
(display b)
(newline))
(x2 3 4 5) => (3 4 5)
使用 lambda
((lambda (. b)
(display b)
(newline))
3 4 5) => Error: invalid use of `.'
在R5RS, both definitions and lambdas接受。为了使它们的行为相同,我可以这样构造 lambda:
((lambda b
(display b)
(newline))
3 4 5) => (3 4 5)
这是报告的形式参数定义中列出的有效结构之一。但是,如果我尝试将它与 define 一起使用,则会导致参数编号不匹配错误。
(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))
因此,implicit/explicit 使用 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)
。
我有两个结构,我希望它们在功能上是相同的,但它们不是,我也不知道为什么。
使用定义
(define (x2 . b)
(display b)
(newline))
(x2 3 4 5) => (3 4 5)
使用 lambda
((lambda (. b)
(display b)
(newline))
3 4 5) => Error: invalid use of `.'
在R5RS, both definitions and lambdas接受。为了使它们的行为相同,我可以这样构造 lambda:
((lambda b
(display b)
(newline))
3 4 5) => (3 4 5)
这是报告的形式参数定义中列出的有效结构之一。但是,如果我尝试将它与 define 一起使用,则会导致参数编号不匹配错误。
(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))
因此,implicit/explicit 使用 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)
。