関数型言語の勉強にSICPを読もう - (66) 4章 - 超言語的抽象(222ページ) C++でSchemeインタプリタを作ろう15

問題4.6

letのサポートを入れようという話。
letはlambdaを使って等価変換ができる。
例えば

(let ((a "hello") (b "good bye"))
  (display a) (display b))

((lambda (a b) (display a) (display b)) "hello" "goodbye")

となる。


なのでTranslatorの時点で let式を見つけたら、Letオブジェクト生成する。
で、Letのeval時に Lambda式に変換してから evalする。
こんな感じ。

Application* Let::expand()
{
    Lambda* lambda = new Lambda(body_, variables_);
    return new Application(lambda, values_);
}

Object* Let::eval(Environment* env)
{
    Object* application = expand();
    return application->eval(env);
}

問題4.7

let*の話。

(let* ((a 3) (b (+ a 3)) (c (- b 1)))
  (display c))

let* では左から順に評価されて、左側の変数を参照できる。
これを let で表現して let*をインタプリタでサポートせよという問題。


let*は let の入れ子でかけると思う。

(let ((a 3))
  (let ((b (+ a 3)))
    (let ((c (- b 1)))
      (display c))))

こんな感じで。
Let* を Letに変換する部分を書いて(もちろん再帰)、きちんと動いた。
なんだかマクロを実装した方が早いんじゃないかという気もしなくもない。
でもまあSICPではマクロが出てこないから微妙。



※「SICPを読もう」の目次はこちら


計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン 和田 英一
ピアソンエデュケーション (2000/02)
売り上げランキング: 56,404