【问题标题】:Scheme Lambda expression with no parentheses around parameterScheme Lambda 表达式,参数周围没有括号
【发布时间】:2013-11-16 11:31:22
【问题描述】:

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

(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 表达式的每个解释总是描述它们就像我在上面所做的那样。

【问题讨论】:

    标签: parameters lambda scheme matrix-multiplication


    【解决方案1】:

    其他答案是正确的,但我想指出这不是特殊语法,而是涉及 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)完全(first second third . ()) 相同。一旦读入这些表达式,就无法区分两者。

    【讨论】:

      【解决方案2】:

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

      (define test (lambda x x))
      
      (test 1)
      => '(1)
      
      (test 1 2 3)
      => '(1 2 3)
      
      (test '(1 2 3))
      => '((1 2 3))
      

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

      【讨论】:

        【解决方案3】:

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

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

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

        在scheme中调用函数时,参数绑定到函数的参数列表。由于f1 的参数列表是(x)(用括号括起来),该列表是解构的,所以x 指的是传递给它的列表中的一个参数。

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多