2

一般在 Scheme - syntax: (if test consequent alternate).

我尝试在该consequent部分中进行一些操作,例如:如果为 true,则将 sum1 设置为 44 并返回 1
在方案代码中 -

(if #t ( 
          (set! sum1 44)
          (if #t 1)
          )) 

上面的代码行不通并提示——

application: not a procedure;
 expected a procedure that can be applied to arguments
  given: #<void>
  arguments...:
   1 
4

3 回答 3

4

在 Scheme 中,括号总是用于应用程序;您不能为分组添加额外的括号。

你的consequent这里是:

((set! sum1 44) (if #t 1))

外圆括号使 Scheme 尝试将 的结果(set! sum1 44)用作过程,将其应用于 的结果(if #t 1)

您想要的(我认为)是按顺序评估两个表达式,然后返回最后一个表达式的结果。这样做的形式是begin,所以它应该是:

(begin (set! sum1 44) (if #t 1))
于 2012-12-17T10:42:24.567 回答
3
(if #t (begin 
          (set! sum1 44)
          (if #t 1))) 
于 2012-12-17T10:42:31.060 回答
3

if如果你写了一个没有部分的解释器,一些解释器(例如 Racket)会抱怨else。为了处理这个问题,并且为了避免begin在结果部分中有多个表达式时显式使用 a ,最好使用when特殊形式(如果可用,因为它是非标准的):

(when #t
  (set! sum1 44)
  (when #t 1))

一般来说,这是 awhen及其兄弟的结构unless

(when <condition>    ; equivalent to (if <condition> (begin ...))
  <exp1>             ; consequent, no alternative
  <exp2>)

(unless <condition>  ; equivalent to (if (not <condition>) (begin ...))
  <exp1>             ; consequent, no alternative
  <exp2>)

如果 consequent 和 alternative 都有多个表达式,则可以在每个部分中使用ifwith a :begin

(if <condition>
    (begin     ; consequent
      <exp1>
      <exp2>)
    (begin     ; alternative
      <exp3>
      <exp4>))

...但是使用 a 会更实用,它在每个子句中都cond隐式使用 a :begin

(cond (<condition>
       <exp1>  ; consequent
       <exp2>)
      (else    ; alternative
       <exp3>
       <exp4>))
于 2012-12-17T14:16:28.163 回答