Skip to content

Instantly share code, notes, and snippets.

@syou6162
Created February 11, 2012 10:06
Show Gist options
  • Save syou6162/1798391 to your computer and use it in GitHub Desktop.
Save syou6162/1798391 to your computer and use it in GitHub Desktop.
SICPで同じような関数を定義、その度に名前を付け変えるのは結構面倒なんだけど、clojureだとdynamic varsを使うとその場で関数の定義を変えれて便利だなーと思った例
(defn average [x y]
(/ (+ x y) 2))
(defn improve [guess x]
(average guess (/ x guess)))
(defn square [x] (* x x))
(defn good-enough? [guess x]
(< (Math/abs (- (square guess) x)) 0.001))
(defn ^:dynamic sqrt-iter [guess x]
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(defn sqrt [x]
(sqrt-iter 1.0 x))
(println (sqrt 9)) ; 3.00009155413138
(defn new-if [predicate then-clause else-clause]
(cond predicate then-clause
:else else-clause))
(new-if (= 2 3) 0 5) ; 5
(new-if (= 1 1) 0 5) ; 0
(binding [sqrt-iter (fn [guess x]
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))]
(try
(sqrt 9)
(catch StackOverflowError e (.toString e))))
(defn average [x y]
(/ (+ x y) 2))
(defn improve [guess x]
(average guess (/ x guess)))
(defn square [x] (* x x))
(defn good-enough? [guess x]
(< (Math/abs (- (square guess) x)) 0.001))
(defn sqrt-iter [guess x]
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
(defn sqrt [x]
(sqrt-iter 1.0 x))
(println (sqrt 9)) ; 3.00009155413138
(defn new-if [predicate then-clause else-clause]
(cond predicate then-clause
:else else-clause))
(new-if (= 2 3) 0 5) ; 5
(new-if (= 1 1) 0 5) ; 0
(with-redefs [sqrt-iter (fn [guess x]
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))]
(try
(sqrt 9)
(catch StackOverflowError e (.toString e))))
@syou6162
Copy link
Author

ifを置き変えれるとよかったんだけど、ifは特殊形式だからか怒られてしまいました。。。

@syou6162
Copy link
Author

このアドバイスを使って書き変えてみます。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment