为什么是;1、2、3“;一个有效的Scheme表达式?

为什么是;1、2、3“;一个有效的Scheme表达式?,scheme,Scheme,这是一个有效的方案 1 2 3 返回3。但这是无效的 (1 2 3) 这也不是有效的 (1) (2) (3) 最后两个是无效的,这是有道理的。但是我不明白第一个怎么有效?有人能解释一下吗?第一个是有效的,因为它被认为是一个简单的表达式。Scheme对它没有任何作用,只是将它反馈给您。这不仅适用于数字,也适用于所有常量,包括字符串、符号甚至列表(如果您引用它们以创建实际列表而不是函数调用)。例如,如果您键入”(1、2、3),它只会回显给您,而不会被解释 scheme和其他Lisp对表达式求值

这是一个有效的方案

1 2 3
返回3。但这是无效的

(1 2 3)
这也不是有效的

(1) (2) (3)

最后两个是无效的,这是有道理的。但是我不明白第一个怎么有效?有人能解释一下吗?

第一个是有效的,因为它被认为是一个简单的表达式。Scheme对它没有任何作用,只是将它反馈给您。这不仅适用于数字,也适用于所有常量,包括字符串、符号甚至列表(如果您引用它们以创建实际列表而不是函数调用)。例如,如果您键入
”(1、2、3)
,它只会回显给您,而不会被解释

scheme和其他Lisp对表达式求值的方式可以用两条广泛的规则来描述(这可能是一种幼稚的解释):

  • 如果输入的表达式是常量(字符串、数字、符号、列表或其他),则常量本身就是值。只需回显一下
  • 如果表达式的形式为
    (过程arg1…arg-n)
    ,请查找
    过程的值,计算或查找所有参数(arg1到arg-n)的值,并将
    过程
    应用于参数
  • 更多详细信息可在本书的章节中找到。

    可能,实现的关键是读取非空的表达式序列并计算所有表达式并给出结果序列。(我认为REPL的这种行为是特定于实现的。在其§5.7中没有提及。它可能与的其他实现不同,我从未使用过它;我同意它可能是一种奇特而有用的功能)

    Scheme能够返回和处理多个值,例如使用
    调用值
    ;另见

    因此,从技术上讲,12 3不是一个表达式,而是三个表达式的序列。调用
    (read)
    不会给出这样的序列。在Linux上的guile 2上,
    (+2(读取))5566
    立即给出两个结果,而不是三个(等待输入后)


    还可以阅读关于,和。可能存在一些间接关系(当REPL按顺序读取多个表单时,REPL如何在内部处理它们)(这也是常见的Lisp实现的工作方式)。考虑到用户输入了多个表单,还会发生什么

    • 显示错误是正确的,但没有帮助
    • 丢弃上一个/下一个表单会令人困惑

    IMHO阅读所有给定表单的行为,就像它们在隐式
    progn
    中一样,对用户来说是最有用的。它还与文件的读取方式一致,例如允许您将文件内容直接粘贴到REPL中。

    关键的观察是,不允许在Scheme中添加额外的括号。在
    (+12)
    中,计算表达式
    +
    ,结果是一个加号函数。该函数应用于12,得到结果3

    在您的示例中,
    (1)
    表示计算1,结果为1。然后将1应用于无参数。因为1不是一个函数,你会得到一个错误

    在示例
    (1 2 3)
    中,您的系统尝试将1应用于参数2和3并获得错误

    简言之:算术中的括号用于对运算进行分组——在方案中,它表示函数应用


    最后:1 2 3不是一个表达式,而是三个表达式。最后一个计算为3。

    但您的两个项目并不代表第一次交互,其中有3个表达式一个接一个。这似乎是scheme repl的一个怪癖/特性(我在这里猜测)。在将三个数字中的每一个作为单独的表达式求值后,它将丢弃前面的两个输出,只打印最后一个输出。对repl中的其他表达式进行一些快速检查会得到类似的结果(当然,打印到控制台的语句除外)。虽然clojure repl打印了所有三个。这感觉很小,但是失败的选民能解释一下原因吗?哪种方案?哪种标准(R5RS、R6RS、R7RS等)?哪种实现和操作系统?对于n=0到n=7,RnRS中的答案是相同的。