Skip to content

dotraceの使い方

syou6162 edited this page Feb 18, 2012 · 5 revisions

dotraceの使い方

なぜdotraceが必要なのか?

SICP(の特に第一章)では、線形再帰プロセスと線形反復プロセスのことが多く出てきます。もちろん、自分の手で書き下すのは勉強になるのですが、慣れてくると手で書くのが面倒になってくるのもまた事実です。Clojure(やGauche)にはどのように式が展開されていったかを表示してくれるような機能があり、それがdotraceです。

準備

まず、project.cljに以下を書きましょう(差分だけ)。tools.traceのところが必要なところです。

(defproject sicp-practice "0.0.1-SNAPSHOT"
  :description "syou6162のSICPの練習問題置き場"
  :dependencies [[org.clojure/clojure "1.3.0"]
		 [org.clojure/clojure-contrib "1.2.0"]
		 [org.clojure/tools.trace "0.7.1"]]
  :dev-dependencies [[swank-clojure "1.3.2"]])

lein depsとやると必要なライブラリを落としてきてくれます。

使い方

階乗の例を使って説明していきます。まず、初めのほうに以下を書いておきます。

(use 'clojure.tools.trace)

階乗の関数を以下のように定義していきます。

(defn ^:dynamic fact [n]
  (if (= n 1)
    1
    (* n (#'fact (- n 1)))))

Clojureのバージョン1.3.0を使っている場合は定義の初めのほうに^:dynamicや再帰の中身のところに#'といったおまじないが必要になっています(理由はこの辺を参照)。実際にdotraceを使うときにはtraceして欲しい関数をブラケットで囲い、評価したい式を書きます。例えばこんな感じ。

(dotrace [fact] (fact 5))

評価の結果を見てみると、横に広がっていて、これは線形再帰プロセスになっているということが分かります。

TRACE t2399: (fact 5)
TRACE t2400: | (fact 4)
TRACE t2401: | | (fact 3)
TRACE t2402: | | | (fact 2)
TRACE t2403: | | | | (fact 1)
TRACE t2403: | | | | => 1
TRACE t2402: | | | => 2
TRACE t2401: | | => 6
TRACE t2400: | => 24
TRACE t2399: => 120
Clone this wiki locally