8

我现在正在学习 Guile Scheme,在文档中我突然遇到了以下结构:

((lambda args (display args)) 42)
=> (42)

这让我陷入了困境;到目前为止,我一直假设形式参数总是包含在一个列表中:

((lambda (args) (display args)) 42)
=> 42

我想知道何时使用此变体,以及这与可变数量参数的点表示法有何不同。具体来说,以下两种变体有什么区别:

((lambda args (display args)) 1 2 3)     => (1 2 3)
((lambda (. args) (display args)) 1 2 3) => (1 2 3)

是否有区别——也许对于更复杂的例子——我需要注意,有什么理由更喜欢其中一个吗?

4

2 回答 2

6

不同之处在于此版本接收一个名为 的参数args,这对于您确切知道lambda表单预期的实际参数数量的情况很有用:

(lambda (args) (display args))

这个版本接收一个(可能是空的)参数列表,称为args,当您期望lambda表单的参数数量可变时很有用:

(lambda args (display args))

以下两个版本之间应该没有区别,但并非所有解释器都会接受第二个版本,因为它缺少点之前的部分(因此应该避免):

(lambda args (display args))
(lambda (. args) (display args))

当您要指定lambda表单具有一个或多个强制参数(点左侧的符号)和零个或多个可选参数列表(点右侧的单个符号)时,以下版本很有用:

(lambda (mandadory1 mandatory2 . optional) (display mandatory1))
于 2012-01-11T14:11:25.257 回答
1

这让我陷入了困境;到目前为止,我一直假设形式参数总是包含在一个列表中:

请注意,类似(a . args)and(a b . args)也不是真正的列表。(a . args)是一对,其中car是符号a,而cdr是符号args(a b . args)是一对,其中car是符号acdr(一对car是符号bcdr符号args)。有一段时间它看起来有点像一个列表,带有aandb和 that,但由于它没有以 null/空列表结尾,它并不是一个真正的正确列表。像这样的结构通常被称为不正确的列表。如果你愿意,你可以在这里或其他地方阅读一些关于点对符号的信息......

(. args)可能会说“这是一对cdr符号args”。或者它可能会像“ caris and the cdris args”一样出现。无论哪种方式,它都没有多大意义,而且,正如 Chris Jester-Young 所说,它不是真正有效的 Scheme。

所以。像这样的东西(a b . args)只是常规的点对符号,用于将不为空的东西放在 last 中cdr。如果 Scheme 中的形参-thing 可以是那些不正确的列表之一或正确的列表或只是一个符号,那么形参-thing 的定义必须类似于:形参-thing 必须为空、符号、或一对,其中car是一个符号,而cdr是一个形式参数 - 事物。

(我认为这是一种很酷的东西,它提供了一种将参数绑定到参数的相当优雅的方式。就像,你看看形式参数的东西,如果它是一个符号,你将参数列表绑定到它,如果它是一对你将car参数绑定到cdr形式参数的东西并重复cdr形式参数的东西/参数(哦,如果它是空的,你就像完成了一样)。这让我觉得有点漂亮比 Common Lisp 的方式“如果符号car&rest你将其余的参数绑定到之后的符号”。)

于 2012-01-26T20:31:09.847 回答