プログラミング再入門

プログラミングをもう一度ちゃんと勉強する読書ノート

SICP 1.1.6 Conditional Expressions and Predicates

ノート

条件式と述語。
ここで習うのはcond、ifと<、>、=。それからbooleanの値を扱うand、or、not。

If none of the <p>'s is found to be true, the value of the cond is undefined.

との事なので、最後に必ずelseを書かないと簡単に不完全なプログラムになってしまう。
andとorはspecial formだがnotだけは普通の関数。

Exercise 1.1

この問題はただ実行してみるだけ。

> 10
10
> (+ 5 3 4)
12
> (- 9 1)
8
> (/ 6 2)
3
> (+ (* 2 4) (- 4 6))
6
> (define a 3)
> (define b (+ a 1))
> (+ a b (* a b))
19
> (= a b)
#f
> (if (and (> b a) (< b (* a b)))
      b
      a)
4
> (cond ((= a 4) 6)
        ((= b 4) (+ 6 7 a))
        (else 25))
16
> (+ 2 (if (> b a) b a))
6
> (* (cond ((> a b) a)
           ((< a b) b)
           (else -1))
     (+ a 1))
16
> 

Exercise 1.2

(やや)複雑な分数式をLispで表現すると:

Exercise 1.3

3つの引数を取り、大きい方の二つの引数の二乗和。
回答とテスト。

> (sum-square-of-larger-two 2 3 4)
25
> (sum-square-of-larger-two 3 4 2)
25
> (sum-square-of-larger-two 4 2 3)
25
> 

Exercise 1.4

この章での評価方法がオペレータですら式によって決まる式でも扱える事を示せ。

いきなりかなり高度な関数。基本は(普通のCの様なプログラミング言語なら)条件に応じて(+ a b)を返すか(- a b)を返すと書くが、ここではbの符号に応じて演算子のみを切り替えている。(if …)の部分は+あるいは-の演算子として解釈され、引数a、bに適用される。bが負の場合は引き算なので、結果としてbの絶対値をaに足す事となる。

Exercise 1.5

Ben Bitdiddle君(diddleは『騙す』)がapplicative orderで評価されているのかnormal orderで評価されているのかを判定する関数を作った。この関数の結末は?
applicative orderの場合はtestを展開する前に引数部分を評価する。(test 0 (p))を評価するには

  1. test : これはdefineで定義された関数が見つかる
  2. 0 : 定数0として評価される。
  3. (p) : pを適用して値を決める必要があるが、pは一度適用してしまうと無限に再帰してしまう。

normalの場合はtestを最初に展開するので

  1. ( (if (= 0 0) 0 (p) )と展開される、ここでxは0、yは(p)
  2. ifの条件式が評価出来るので、(if …)の値として0と評価される。

pは適用しないため計算は終わる。