コンピュータはプログラムをどのように動かしているのでしょうか. いままで見てきたプログラムは比較的単純な例ばかりだったので, 「人間が数式を計算するのと同じように計算する」という理解で充分だったかも知れません.
しかしOcamlのような言語のプログラムは, あくまでも人間にとって読み書きしやすいようになっているものであって, コンピュータのCPUはそれを直接実行することはできません. 実際には, 与えられた式を一定の規則に従って変形してゆくことで答えを求めていっています.
例えば
let square(x) = x *. x
let discriminant(a,b,c) = square(b) -. 4.0 *. a *. c
という関数が定義されていたときに、 discriminant(1.0,-5.0,6.0) という式を入力した場合の実行を見てみましょう。
- discriminant(1.0,-5.0,6.0) …… この式は、 discriminant という関数の定義の本体で置きかえます。つまり、square(b) -. 4.0 *. a *. c という式に置きかえるわけです。ただし、a, b, cという変数はそれぞれ 1.0, -5.0, 6.0 という値が渡されています. 結局, 次のような式に置きかわります.
- square(-5.0) -. 4.0 *. 1.0 *. 6.0 …… この式は引き算ですので、-. の左側と右側にある式をそれぞれ計算します。
- (右側) 4.0 *. 1.0 *. 6.0 …… -. の右側の式はそのまま計算した結果に置きかわります.
- (右側) 24.0 …… この式はこれ以上計算できません. そこで元の式の -. の右側を 24.0 で置きかえます.
- (左側) square(-5.0) …… 同様に -. の左側を計算します. この式は、square という関数の定義本体で置きかえます。つまり次のようになります
- (左側) -5.0 *. -5.0 …… この式はそのまま計算し, その結果に置きかえます. つまり次のようになります.
- (左側) 25.0 …… この式はこれ以上計算できません. そこで元の式の -. の左側は 25.0 で置きかわります. 左側、右側両方の置きかえをすると元の式は次のようになります.
- 25.0 - 24.0 …… この式は引き算を行ってその結果に置きかわりますので,
- 1.0 …… この式はこれ以上計算できません. 結局、入力した式の値は 1.0 と求められたことになります.
計算に使った方針をまとめると、次のようになります:
- 関数(式1,式2,...) という形の式は、式1, 式2,... の値をそれぞれ計算します。
- 関数(値1,値2,...) という形の式は、関数の定義本体で置きかえます。つまり let 関数(変数1,変数2,...) = 式 という定義がされていた場合,
- 関数(値1,値2,...) を 式 に置きかえる
- その際, 式の中に現われる変数1, 変数2, ... を値1, 値2, ... で置きかえる.
- 式1 + 式2 のような計算式は,
- 式1 や 式2 の値をまず計算し 値1, 値2 を求めておき
- 値1と値2の和を求めたものに置きかえます.