2008年6月30日
手続きによる抽象の構築(7)
結局、vimでいくことにしました。
Lisp開発環境
Emacsの設定をしようかとも思ったのですが、馴れているviにすることにしました。幸い、Mac OS Xに標準でインストールされているvimにLisp indentが含まれていたので、このままで行く方向です。
問題 1.3
昨日のソースでは動かなかったので、問題を細分化してみる。まずは3つのうちから最大のものを求めるスクリプトを作る。vimの括弧対応表示のおかげでバグを見つける。出来上がったソースはこちら。
(define a 1)
(define b 2)
(define c 3)
(define biggest (cond ((and (> a b) (> a c)) a)
((and (> b a) (> b c)) b)
(else c)
)
)
これをGaucheでテストする方法に軽くハマりました。「gosh ファイル名」で読み込みはするのですが、biggestに何が設定されているのか、わかりません。まだSICPでは標準入出力に関する処理は出てきていないのです。結局、「gosh -lファイル名」でREPL起動前に上記ファイルを読み込ませた後、「biggest」と入力することで表示することにしました。
$ gosh -l./tmp.scm
gosh> biggest
3
良さそうです。同様にbiggerも定義。
(define bigger (cond ((or (and (> a b) (< a c)) (and (< a b) (> a c)) ) a)
((or (and (> b a) (< b c)) (and (< b a) (> b c)) ) b)
(else c)
)
)
$ gosh -l./tmp.scm
gosh> biggest
3
gosh> bigger
2
こちらもよさそう。ソースがDRY(Don't Repeat Yourself)じゃないのが気に入りませんが・・・。まずは動作するものを作ることを優先。これら二つの変数をグローバル変数から関数内のローカル変数へ格下げし、最後に「最大の数の二乗」+「次に大きな数の二乗」を求める処理を追加します。
(define (hoge a b c)
(define biggest (cond ((and (> a b) (> a c)) a)
((and (> b a) (> b c)) b)
(else c)
)
)
(define bigger (cond ((or (and (> a b) (< a c)) (and (< a b) (> a c)) ) a)
((or (and (> b a) (< b c)) (and (< b a) (> b c)) ) b)
(else c)
)
)
(+ (* biggest biggest)
(* bigger bigger)
)
)
$ gosh -l./tmp.scm
gosh> (hoge 3 2 1)
13
gosh> (hoge 1 2 3)
13
gosh> (hoge 3 3 3)
18
gosh> (hoge -1 -2 -3)
5
良さそうな雰囲気。
さらに改修しようと思ったのですが、ローカル変数の定義方法はdefineではないようで、うまく行かないので、さ樹に進みます。
問題 1.5
関数a-plus-abs-bを定義している。引数はa・bの2つ。この関数の戻り値は引数a・bに対してプラス・もしくはマイナスの演算子を適用した値となる。引数bが0より大きい場合はプラスを、そうでない場合はマイナスの演算子を適用する。
問題 1.6
作用的順序の評価の場合
(test 0 (p))
↓
(test 0 (p))
↓
(test 0 (p))
↓
以下、無限に続く
正規順序の評価の場合
(test 0 (p))
↓
(if ( = 0 0)
0
(p))
↓
0
実際の処理系は前者で処理をしているとのことなので、Gaucheで試してみたところ、無限ループなることを確認。
Trackback on "手続きによる抽象の構築(7)"
このエントリーのトラックバックURL:
"手続きによる抽象の構築(7)"へのトラックバックはまだありません。
"手続きによる抽象の構築(7)"へのコメントはまだありません。