Skip to content

Instantly share code, notes, and snippets.

@ypsilon-takai
Created December 20, 2012 04:01
Show Gist options
  • Save ypsilon-takai/4342882 to your computer and use it in GitHub Desktop.
Save ypsilon-takai/4342882 to your computer and use it in GitHub Desktop.

#clojure 入門者向け勉強会 #mitori_cljでClojureのメモ化関数についてこんなのどう?という提案をいただいたのでちょっと確認してみました。

結果はやっぱりだめでした。

(12/20 16:05)というのはうそでした。 指摘いただいたやりかたの実装が間違ってました。ひぇー。

以下は修正版です。

(defn fib [n]
  (do
     (println "-->" n)
     (if (<= n 1)
        n
        (+ (fib (dec n)) (fib (- n 2))))))

これを実行するとこう

user> (fib 4)
--> 4
--> 3
--> 2
--> 1
--> 0
--> 1
--> 2
--> 1
--> 0
3
user> (fib 5)
--> 5
--> 4
--> 3
--> 2
--> 1
--> 0
--> 1
--> 2
--> 1
--> 0
--> 3
--> 2
--> 1
--> 0
--> 1
5

関数が呼ばれると毎回計算します。

まずは普通にメモ化してみます。

(def fib-outmem (memoize fib))

実行するとこう

user> (fib-outmem 4)
--> 4
--> 3
--> 2
--> 1
--> 0
--> 1
--> 2
--> 1
--> 0
3
user> (fib-outmem 5)
--> 5
--> 4
--> 3
--> 2
--> 1
--> 0
--> 1
--> 2
--> 1
--> 0
--> 3
--> 2
--> 1
--> 0
--> 1
5
  • 関数内部での呼び出しでメモ化が効いてません。
  • 外部でも(fib 5)の呼び出しで(fib 4)の結果が使われていません。

提案いただいたのは、memoizeに無名関数を渡してやればいいのでは?というものなのでやってみます。

(def fib-inmem
  (memoize
   (fn [n]
     (do
       (println "-->" n)
       (if (<= n 1)
         n
         (+ (fib-inmem (dec n)) (fib-inmem (- n 2))))))))

実行してみると、ちゃんと動きます。

user> (fib-inmem 4)
--> 4
--> 3
--> 2
--> 1
--> 0
3
user> (fib-inmem 5)
--> 5
5

ちなみに、僕の作ったマクロでメモ化でやってもこうなります。(まちがえて5でやってしまった)

user> (fib-defmemo 5)
--> 5
--> 4
--> 3
--> 2
--> 1
--> 0
5
user> (fib-defmemo 6)
--> 6
8
@kohyama
Copy link

kohyama commented Dec 20, 2012

fib-inmem の中の再帰で typo で fib (メモ化されていない fib) を呼んでいるのが原因と思われます.

(def fib-inmem
  (memoize
    (fn [n]
      (do
        (println "-->" n)
        (if (<= n 1)
          n
          (+ (fib-inmem (dec n)) (fib-inmem (- n 2))))))))
user=> (fib-inmem 4)
--> 4
--> 3
--> 2
--> 1
--> 0
3
user=> (fib-inmem 5)
--> 5
5

一応, memoize は使えるみたいです. ということで.

ただ, 結局
(def foo (memoize foo)) のように先に定義した関数を後からメモ化することができず,
(def foo (memoize (fn [] ...))) のように最初からメモ化関数として書くことしかできませんから,
やはり, 御 defn-memo マクロの方が書きやすくて 👍 です.

@ypsilon-takai
Copy link
Author

なんというポカミスでしょう!!!!
やっぱりあわててやるといいことありませんね。

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