< ピアノレッスン18回目 | らむ太と言葉 >
2011/10/14
runonce
『プログラミングClojure』に、マルチスレッド環境でも 与えた関数を一度だけ実行するrunonceという仕組みを作る例が出てくる。 似たようなことをGaucheでやる必要が出てきたのでちょいと書いてみた。
runonceは関数を引数に取り、
- その関数が既に実行されたかどうかを調べる関数 (has-run?)
- 初期状態に戻す関数 (reset)
- 引数を与えてその関数を実際に実行する関数。但し、既に実行されていた場合は実行せずに前の結果を返す。(once)
という3つの関数を返す関数だ。
Gauche風に書くとこんな感じになるかなあ。
atom
は名前をClojureから取ったんだけど、使い勝手はかなり違うので注意。
Gaucheにトランザクションはないので、atomicな領域で副作用を起こして構わない。
gosh> (define-values [print-has-run? print-reset print-once] (runonce print)) #<undef> gosh> (print-has-run?) #f gosh> (print-once "Aloha") Aloha #<undef> gosh> (print-has-run?) #t gosh> (print-once "Mahalo") #<undef> gosh> (print-reset) #f gosh> (print-once "Mahalo") Mahalo #<undef>
なお、fnが引数を取らず、resetとかhas-run?が不要で 「引数なしの関数を一度だけ走らせれば良い」ということなら、単にdelayを使えば済むのだけれど。 (但し、0.9.2までのforceはスレッドセーフになっていないので注意。 開発版は安全。)
Tags: Programming, Gauche, Clojure
Post a comment