何时使用带有“裸”形式参数的lambda定义?

时间:2012-01-11 13:18:29

标签: lambda scheme guile

我正在学习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)

是否存在差异 - 或许是为了更复杂的例子 - 我需要注意并且是否有理由更喜欢一个而不是另一个?

2 个答案:

答案 0 :(得分: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))

答案 1 :(得分:1)

  

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

请注意,(a . args)(a b . args)之类的内容也不是真正的列表。 (a . args)是一对car是符号acdr是符号args(a b . args)是一对,其中car是符号a,而cdrcar是符号b的一对cdr是符号args)。它看起来有点像一段时间的列表,ab,但是因为它不以null /空列表结尾,所以它不是一个合适的列表。像这样的结构通常被称为不正确的列表。如果你想,你可以阅读一些点缀对符号here或其他地方...

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

因此。 (a b . args)之类的内容只是常规的点对符号,用于放置上一个cdr中非空的内容。如果Scheme中的形式参数 - 事物可能是那些不正确的列表之一或正确的列表或只是符号,那么形式参数的定义必须是这样的:形式参数 - 事物必须为空,符号,或car为符号且cdr为正式参数的对。

(我认为这是一种很酷的事情,它使得参数的参数绑定得相当优雅。就像,你看一下形式参数的东西,如果它是一个符号你将参数列表绑定到那个如果它是一对,你将参数的car绑定到形式参数的cdr并且重复cdr正式的参数 - 事物/参数(哦,如果它是null就像你做的那样或其他什么东西。这让我觉得比Common Lisp的方式更漂亮“如果car中的符号是&rest你将其余的参数绑定到之后的符号“。)