2012-12-17 33 views
3

通常在方案中 - syntax: (if test consequent alternate)如果條件下的方案運行

我試圖在consequent部分中執行一些操作,例如:如果爲true,則將sum1設置爲44並返回1
在Scheme代碼的 -

(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 
+0

看到我的最新答案的替代解決方案這個問題 –

回答

4

在方案中,括號總是用於應用程序;您不能爲分組添加額外的括號。

consequent這裏是:

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

外對括號使得計劃嘗試使用的(set! sum1 44)結果作爲一個過程,它應用到的(if #t 1)結果。

你想要什麼(我認爲)是按順序評估這兩個表達式,然後返回最後一個的結果。做到這一點的形式是begin,所以它應該是:

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

一些口譯(球拍,例如),如果你寫一個if沒有else部分抱怨。爲了應對這個問題,並避免需要明確使用begin當多於一種的表達去在事件部分,最好是使用when特殊形式(如果可用,因爲它的非標):

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

在一般情況下,這是一個whenunless的結構和它的兄弟:

(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>) 

如果同時隨之而來的和不信教有多於一種的表達,你可以使用if在每個部分begin

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

...但它會是更實際使用cond,在其每個條款的隱含地使用begin

(cond (<condition> 
     <exp1> ; consequent 
     <exp2>) 
     (else ; alternative 
     <exp3> 
     <exp4>))