我正在学习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)
是否存在差异 - 或许是为了更复杂的例子 - 我需要注意并且是否有理由更喜欢一个而不是另一个?
答案 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
是符号a
,cdr
是符号args
。 (a b . args)
是一对,其中car
是符号a
,而cdr
是car
是符号b
的一对cdr
是符号args
)。它看起来有点像一段时间的列表,a
和b
,但是因为它不以null /空列表结尾,所以它不是一个合适的列表。像这样的结构通常被称为不正确的列表。如果你想,你可以阅读一些点缀对符号here或其他地方...
(. args)
我可能会说“这是一对cdr
是符号args
”。或者它可能会像“一对car
而cdr
是args
”那样出现。无论哪种方式,它都没有多大意义,正如Chris Jester-Young所说,这不是真正有效的方案。
因此。 (a b . args)
之类的内容只是常规的点对符号,用于放置上一个cdr
中非空的内容。如果Scheme中的形式参数 - 事物可能是那些不正确的列表之一或正确的列表或只是符号,那么形式参数的定义必须是这样的:形式参数 - 事物必须为空,符号,或car
为符号且cdr
为正式参数的对。
(我认为这是一种很酷的事情,它使得参数的参数绑定得相当优雅。就像,你看一下形式参数的东西,如果它是一个符号你将参数列表绑定到那个如果它是一对,你将参数的car
绑定到形式参数的cdr
并且重复cdr
正式的参数 - 事物/参数(哦,如果它是null就像你做的那样或其他什么东西。这让我觉得比Common Lisp的方式更漂亮“如果car
中的符号是&rest
你将其余的参数绑定到之后的符号“。)