[:let,
[[:fact,
[:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]]],
[:fact, 1]]
[
[:lambda, [:fact], [:fact, 1]],
[:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]
]
※ばらすとこんな感じ(逆にわかりにくいかも)
[
[:lambda, # <- ここからcar
[:fact], # <-carのlambdaの仮引数
[:fact, 1] # <-carのlambdaのbody
], # <- ここまでcar
[:lambda, # <- ここからcdr
[:n], # <- cdrのlambdaの仮引数
[:if, # ここからcdrのlambdaのbody
[:<, :n, 1], # <- if式の条件
1, # <- TRUE節
[:*, :n, [:fact, [:-, :n, 1] # <- FALSE節
] # <- ここまでcdrのlambdaのbody
] # <- ここまでcdr
]
[:lambda, [:fact], [:fact, 1]]
↓
[:closure, [:fact], [:fact, 1], [$global_env]]
(carはlambdaなのでそのときの環境と併せてclosure化する)
[:lambda, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]]
↓
[:closure, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]], [$global_env]]
(この式ではcdrもlambdaなのでclosure化する)
closureへのapplyとはつまり..
carのparameter [:fact]
に
cdr[:closure, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]
を束縛した環境を新しく作って...
[{:fact => [:closure, [:n], [:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1], [$global_env]]]]},
$global_env]
carのbodyを実行
[:fact, 1]
[[:closure,
[:n],
[:if, [:<, :n, 1], 1, [:*, :n, [:fact, [:-, :n, 1]]]]},
[$global_env]],
1]
[{:n => 1},
$global_env]
という環境をつくって
[:if, [:<, :n, 1], 1], [:*, :n, [:fact, [:-, :n, 1]]]]
の実行
[:<, :n, 1]
でnを環境に見に行くと、6で束縛した1なので,
[:<, 1, 1]
はfalse。
[:fact, [:-, :n, 1]]
このときの環境は、6で作った
[{:n => 1}, $global_env]
なので、:fact
がいない!
-> よってエラー