Clojure + Proce55ing
話題の Clojure(http://clojure.org/)。 id:g000001 さん(http://cadr.g.hatena.ne.jp/g000001/)がとても詳しい。
Clojure って JVM で動くんだよなぁ、ってことは Java のライブラリも呼べるよなぁ、そうすると Proce55ing も呼べるなぁ、そうするとhttp://d.hatena.ne.jp/cranebird/20080906 で書いた、
Common Lisp + jython + PApplet の環境
が作れるかもなぁ、とやってみたら、あっさりできた。Clojure は Common Lisp でもないし Scheme でもないのでまだ全然慣れていないけど。
以下では、
- CLASSPATH に processing の pde.jar, core.jar を追加して clojure の Repl を起動
- PApplet, PDrawEventListener, Frame を import
- 関数定義(※動的にReplで行ってもOK)。 Frame に PApplet のインスタンスを追加して表示する。ただしこの時点では PApplet は空っぽなので何も描かない。
- PDrawEventListener を定義してランダムに線を描かせてみる。ここでは clojure の proxy によって動的に PDrawEventListener を定義している。
- 上の動的な機能は jython と同様。ただし微妙な違いとして、jython では = でイベントリスナーを登録できた(内部では reflection を使用)が、 clojure ではもっと java っぽい。まだ見ていないだけかもしれない。
~/clojure_20080916 $ java -classpath $CLASSPATH:./clojure.jar clojure.lang.Repl Clojure user=> (import '(processing.core PApplet PDrawEventListener) '(java.awt Frame)) nil user=> (defn p5 [] (let [p (new PApplet) f (new Frame)] (. f setSize 300 300) (. p (addPDrawEventListener (proxy [PDrawEventListener] [] (doDraw [evt] (let [w (. p width) h (. p height)] (. p line (. p random w) (. p random h) (. p random w) (. p random h))))))) (. f add p) (. p init) (. f setVisible true) f)) #'user/p5 user=> (p5) java.awt.Frame[frame0,0,22,300x300,layout=java.awt.BorderLayout,title=,resizable,normal]
なお、上記 PApplet は自作のパッチ(http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Integrate;action=display;num=1220794099)を当ててあるけど本質ではない。(残念ながら芳しい反応は無かったが、、、)
Clojure が JVM 上で動くということは膨大な Java 資産が使える、ということを実感。いままで「ふうがわりな Lisp 方言だな」くらいに思っていてあまり気にしていなかったけど、これは強力。ABCL(Armed Bear Common Lisp) もいつか試そうと思っていたけど、 Clojure の方が活気がありそうだなぁ。