我是Scheme的新手,我主要使用C ++ / Java和一些Python进行后台编码。我在“计算机程序的研究和解释”中进行练习,遇到了这个问题:
这本书详细说明了“ if”特殊形式的结构,如(if(有条件)(后继子句)(替代子句))。但是,没有任何内容表明必须包含替代条款。
实际上,在我目前坚持的练习中(练习1.22,对于任何感兴趣的人),它们提供了一些代码,我们应该将其用于创建测试给定范围内质数的过程并给出找到它们所花费的时间。
(define (start-prime-test n start-time)
(if (is-prime n)
(report-prime (- (runtime) start-time))))
这行不通,所以我做了一点修改:
(define (start-prime-test n start-time)
(if (is-prime n)
(report-prime (- (runtime) start-time))
(display ""))) ;prints nothing
第一个版本导致“ SchemeError:操作数太少...”,我对其进行了修改,使其具有实质上不执行任何操作的替代子句,并且在测试过程时不再出现错误。
我只是想知道对于大多数Scheme解释器来说,要求替代子句是否是标准的,或者它是否对我正在使用的子句唯一。我目前使用的是两种不同的解释器,因为我使用的第一个解释器不包括本书中详细介绍的内置过程,因此我注意到Scheme解释器存在一些主要差异。但是据我所知,通过谷歌搜索找到有用的信息非常困难。
任何帮助将不胜感激;我不喜欢包含“不做”程序。
答案 0 :(得分:2)
在大多数Scheme解释器中,if
允许不带“ else”部分的表达式,这就是standard所说的,正如@codybartfast在回答中指出的那样。
我只知道Racket强制执行以下规则:if
必须始终具有结果部分和替代部分,这是有充分理由的:它将帮助您捕捉在发生以下情况时会发生的错误您忘了写“ else”部分。
尽管有if
表达式而没有其他部分是有效的,但这仅在我们编写过程代码时才发生(例如在示例中显示结果),这就是我们要使用方案时避免使用(因为我们偏爱函数式编程)。
话虽如此,如果您完全确定要编写过程代码,则应使用when
,它没有else
部分,与if
不同,它内部可以包含多个表达式,因为它具有隐式begin
。这将起作用:
(define (start-prime-test n start-time)
(when (is-prime n)
(report-prime (- (runtime) start-time))))
答案 1 :(得分:1)
我了解R5RS / R6RS实际上是语言标准。他们说替代条款是optional:
(if <test> <consequent> <alternate>)syntax
(if <test> <consequent>)syntax
Syntax: <Test>, <consequent>, and <alternate> must be expressions.
Semantics: An if expression is evaluated as follows: first, <test> is
evaluated. If it yields a true value (see section 5.7), then <consequent> is
evaluated and its values are returned. Otherwise <alternate> is evaluated
and its values are returned. If <test> yields #f and no <alternate> is
specified, then the result of the expression is unspecified.
但是在2009年(最近在该计划中很多),语言指导委员会said:
A:Scheme作为世界上最不可移植的编程语言而感到遗憾。将Scheme称为“编程语言”几乎是一种误导;将Scheme表征为方言族会更准确,所有这些都与词汇范围,动态类型,列表结构,高阶函数,适当的尾递归,垃圾回收,宏和(某种形式)的共同特征紧密相关基于s表达式的词法语法。
因此,尽管可能存在正式的标准,但几乎没有期望任何给定的实现都将遵守该标准。例如。默认情况下,Racket需要使用alter子句。 (尽管Racket还可以支持R6RS兼容的拨号程序。)
我个人将Racket与SICP language pack结合使用,以与书保持一致。
答案 2 :(得分:0)
单臂if
确实是Scheme的标准配置。
不幸的是,单臂if
会让一个人犯错-忘记第二个臂很容易做到。一些实现添加了when
和unless
以减少错误数量。