Scheme Lambda表达式,参数周围没有括号

时间:2013-11-16 11:31:22

标签: parameters lambda scheme matrix-multiplication

我无法理解Rosetta Code中的这个矩阵乘法示例:

(define multiplyMatrices
    (lambda (matrix1 matrix2)
        (map (lambda (row)
            (apply map (lambda column
                (apply + (map * row column)))
            matrix2))
        matrix1)))

其中matrix1matrix2都是列表。我的问题是:为什么第四行的column没有用括号括起来?

据我了解,lambda表达式的格式为(lambda (<id1 id2 ...>) <exp>)。从测试代码我知道它的工作原理,我知道在括号中包装column确实会破坏程序,但我不明白该行是如何语法的,以及我找到的lambda表达式的每个解释在线总是像我上面那样描述它们。

3 个答案:

答案 0 :(得分:3)

其他答案是正确的,但我想指出这不是一种特殊的语法,而是涉及 rest参数的更一般语法的特定情况。

考虑以下功能:

(lambda () ...)
(lambda (first) ...)
(lambda (first second) ...)
(lambda (first second third) ...)

这些函数分别采用0,1,2和3个参数。

现在考虑以下这些功能:

(lambda rest ...)
(lambda (first . rest) ...)
(lambda (first second . rest) ...)
(lambda (first second third . rest) ...)

这些函数分别使用至少 0,1,2和3个参数。在这些情况下,任何进一步的参数都会被收集到列表中并绑定到rest

第一组函数使用正确列表作为lambda列表。第二组函数使用不正确列表作为其lambda列表。那两者之间的区别是什么? 正确的列表只是一个列表,其中()作为最终的cdr,不正确的列表是一个列表,其他东西作为其最终的cdr。就是这么简单。

为了在两组函数之间提供更大的视觉对称性,可以用这种方式编写第一组函数:

(lambda () ...)
(lambda (first . ()) ...)
(lambda (first second . ()) ...)
(lambda (first second third . ()) ...)

列表(first second third) 与<{1}}完全相同。读入这些表达式后,无法区分这两个表达式。

答案 1 :(得分:1)

此语法将所有参数放入列表中:

(define test (lambda x x))

(test 1)
=> '(1)

(test 1 2 3)
=> '(1 2 3)

(test '(1 2 3))
=> '((1 2 3))

另请参阅here:“如果形式是单个变量(不在列表中),例如z,则它绑定到实际参数列表。

答案 2 :(得分:0)

注意以下两个函数之间的区别:

> (define f1 (lambda (x) x))
> (f1 "HELLO")
"HELLO"

> (define f2 (lambda y y))    
> (f2 "HELLO")
'("HELLO")

在scheme中调用函数时,参数绑定到函数的参数列表。由于f1的参数列表是(x)(括号括起来),列表是 destructured ,因此x指的是列表中的一个参数被传递给了它。

f2在其参数列表y周围不包括括号,因此发送给它的参数列表不会被解构,因此返回列表。