这是有效的方案
1 2 3
并返回3.但这是无效的
(1 2 3)
这两个都没有效果
(1) (2) (3)
最后两个无效是有道理的。但我不知道第一个应该如何有效?有人可以解释一下吗?
答案 0 :(得分:3)
您的实现的REPL可能正在读取表达式的非空序列并评估所有表达式并给出结果的序列。 (我相信REPL的这种行为是特定于实现的。R7RS在其§5.7中没有提到它。它可能与Scheme的其他实现不同而且我从未使用过它;我同意{{} 3}}它可能是一个奇特而有用的特征)
Scheme能够返回并处理多个值,例如与call-with-values
& values
;另见coredump's answer
技术上 1 2 3
不 单表达式,但序列有三个表达式。拨打(read)
不会给您这样的顺序。在Linux上的guile 2上(+ 2 (read)) 55 66
立即给 两个结果57 66
,而不是三个(在等待输入之后)。
另请阅读this,call/cc和continuations。可能存在一些间接关系(当(read)
表达式时,你的 REPL如何在内部处理它们。)
答案 1 :(得分:3)
REPL正在按顺序读取多个表单(这也是Common Lisp实现的工作方式)。鉴于用户输入了多个表单,还会发生什么?
恕我直言,阅读所有给定表格的行为 - 如果它们处于隐式progn
中对用户最有用。它与文件的读取方式一致,并允许您将文件内容直接粘贴到REPL中。
答案 2 :(得分:1)
第一个是有效的,因为它被认为是一个简单的表达式。 Scheme不会对它做任何事情,只是回复给你。这不仅适用于数字,也适用于所有常量,包括字符串,符号甚至列表(如果引用它们来创建实际列表而不是函数调用)。对于前者如果你输入'(1 2 3)
,它就会在没有被解释的情况下回复给你。
计划方式,以及通常其他lisps,评估表达式可以通过两个广泛的规则来描述(这可能是一种天真的解释):
(procedure arg1 ... arg-n)
,请找到procedure
的值,评估或查找所有参数的值(arg1到arg-n),然后应用procedure
参数。更多详细信息,请参阅本书Evaluating Scheme Expressions中的The Scheme Programming Language 4e章节。
答案 3 :(得分:1)
关键的观察是不允许在Scheme中加入额外的括号。在(+ 1 2)
中,计算表达式+
,结果是加号函数。该函数应用于1 2,您得到结果3。
在您的示例中,(1)
表示评估1,结果为1.然后将1应用于无参数。由于1不是函数,因此会出错。
在示例(1 2 3)
中,您的系统尝试将1应用于参数2和3并获得错误。
简而言之:算术中的括号用于对操作进行分组 - 在Scheme中它表示功能应用。
最后:1 2 3不是单个表达式而是三个表达式。最后一个评估为3。