1.1.4~1.1.6
1.1.4 合成手続き
defineにより合成手続きに名前を付けることができる(前回は数や演算結果に名前を付けていた)。
一度defineで定義された場合、ユーザ定義の合成手続きと、解釈系にあらかじめ備わっている基本演算子の区別はつかない。
合成手続きのbodyには手続きの本体(式の並び)が入り、評価するさいには最後の式を手続き作用の値として評価する。
ここでは合成手続きに名前を付けていたが、λ計算においては合成手続きに名前を付けない。脚注のように手続きを作ることと、手続きに名前を付けることはそれぞれ分離することができる。
ちなみに以下のように、基本演算子に名前をつけることもできる。
> (define myplus +) > myplus #<procedure:+> > (myplus 3 4) 7
1.1.5 手続き作用の置き換えモデル
基本演算子(演算子が解釈系にあらかじめ組み込まれている)の評価規則は、1.1.3で示された。
ここでは演算子が合成手続きの場合の評価規則が2つあることを示す。
作用的順序:あらかじめ引数を評価して、演算子を作用させる評価方法。解釈系の実際の評価規則。
正規順序:演算子が基本演算子となるまで、引数に対する演算子の展開を最初に行い、基本演算子が現れてから初めて引数の評価を行う評価方法。
両者においては、引数の評価するタイミングと演算子の評価する順序がそれぞれ異なる。
演算子が基本的演算子の場合は、演算子の評価というフェイズがないため、評価方法は一意となる。
注意:
本来計算機の内部ではレジスタ等を用いて処理を行っているが、置き換えモデルはそれを人間が把握できるように、手続きやパラメータをステップ単位で置き換えることで可視化したもの。そのため作用的順序評価の置き換えモデルもあるし、正規順序評価の置き換えモデルも存在する。(問題1.20を参照せよ)
1.1.6 条件式と述語
and,or,ifはdefineと同じく特殊形式。
普通のプログラミング言語ではandは一般的には真偽を返すが、以下のように真偽を返すのでなく、式の評価結果(この場合2)を返す。
> (and 1 2) 2
注意
解釈系が述語の値を調べる時, #fを偽と解釈する. 他の値は真として扱う. (従って#tは論理的には不要だが, 便利でもある.)
schemeにおいて、真とは偽意外の全てを指します(下の例を参照:1が偽以外と評価された結果2が評価されています)。
この辺りは言語によって違うので紛らわしいところです。
> (if 1 2 3) 2
さらに注意
ifは 場合分けが丁度二つであるような制限つき条件式である. if式の一般形は
(if ⟨predicate⟩ ⟨consequent⟩ ⟨alternative⟩)
である. if式を評価するには, 解釈系は式の 述語⟨predicate⟩部分を評価する. ⟨predicate⟩の評価の結果が真なら, 解釈系は 帰結部⟨consequent⟩を評価しその値を返す. そうでなければ, 代替部⟨alternative⟩を評価し, その値を返す.
この場合predicateは評価はなされますが、predicateの評価結果の値は返されません。あくまでもconsequentの評価結果が返されます。上のif文でも1は評価されいますが印字されていません。
ただし問題22のようにdisplayを用いた場合は別です。