関数型言語の勉強にSICPを読もう - (32) 3章 - 小休止 beginを利用した print デバッグについて
以前、traceを利用したデバッグ方法を紹介しました。
今日は begin を利用した print デバッグの方法を紹介します。
SICPを1ページ目から順に読んでいくと begin がなかなか出てこないのですが、今日 begin を知りこのデバッグ方法に気づきました。
例えば
(define (a) (let ((state 0)) (define (b) (if (some-condition) (some-func) (else-func) ))) たくさんの処理 )
のような手続きがあるとします。
このときに手続き b の戻り値は (some-func)か、(else-func)なのですが、(some-codition)を実行後に state の値を知りたい場合があると思います。
この場合 (display state)をどこかに挿入すればよさそうなのですが、if の中に隙がなさそうです。
でも begin を使えばこんなことができてしまいます。
(define (a) (let ((state 0)) (define (b) (if (some-condition) (begin (display state) (some-func)) (begin (display state) (else-func)) ))) たくさんの処理 )
beginは以下のような手続きです。
[R5RS] formを順に評価し、最後の値を返します。
Beginはletのような「ブロック」を作成するわけではありません。 すなわち、一般的にはform …の先頭に「内部のdefine (internal define)」を 置くことはできません。意味的には、beginはまるでform …が beginを囲むコンテクスト中に展開されているかのように振舞います。 例えば、トップレベルに次のような式があった場合、それは2つのトップレベルのdefineと 同等です
このように、値を返す部分であっても begin を使えば print デバッグができちゃいます。これは便利!。
ちなみに良く似た手続きで begin0 というものがありこれを利用すると同じことを
(define (a) (let ((state 0)) (define (b) (if (begin0 (some-condition) (display state)) (some-func) (else-func) ))) たくさんの処理 )
と書けます。
もっと良い方法があるよなどご意見大歓迎です。
追記
Gaucheでは debug-printというマクロが用意されていてとてもよさげです。
コメントで教えていただきありがとうございました。
ピアソンエデュケーション (2000/02)
売り上げランキング: 56,404