clojureを分解する


昨夜、女房殿のWindows機を使っていると、目の前のモデムが突然チカチカし始めた。
自分はネットにアクセスしてないし、おかしいなあ。悪性ウィルスにでもやられて
勝手にネットにつながれちゃったの? すわ、一大事と思っていると、、、
javaのアップデート準備が整いました、だとさ。脅かすなよ。
Sunも最近、IBMに買収とかの話があるので、いい所を見せようと、言い寄って
きたのかな? それにしても、アップデートのご案内が遅いよ。>Sun殿。

さて、今日のタイトルについてだが、結論を先に書こう。
クロージャは、手続きと手続きが定義された時の環境で出来ています。
以上、説明終わり、、
じゃ、余りにも *aあれ* なので、Javaアプリのclojure を、真面目に分解してみます。


分解するには、あらかじめ内部構造が分かっていた方がいいだろう。
clojureのページの左側メニューにあるAPIのリンクを辿れば、実装されている
手続きが一望出来る。マニュアルなので、無味乾燥の感はいなめない。
もう少し、生の声を聞きたいなぁーと言う向きには、右メニューのWikiがお勧め。
FAQから順番に面白そうな所を見ていく事にする。

user=> (reduce + (range 100))
4950
user=> (range 10)
(0 1 2 3 4 5 6 7 8 9)

1から99までの合計が一発ですよ。range って、srfi-1 にある、iota の別名?

#!/bin/bash
CLOJURE_DIR=/path/to/clojure
CLOJURE_JAR=$CLOJURE_DIR/clojure.jar
if [ -z "$1" ]; then 
   java -cp $CLOJURE_DIR/jline-VERSION.jar:$CLOJURE_JAR \
   jline.ConsoleRunner clojure.lang.Repl    
else
    scriptname=$1
    java -cp $CLOJURE_JAR clojure.lang.Script $scriptname -- $*
fi

上記は、Getting start にあった、スクリプトとREPLの切り替え機。他にも
便利な設定が載っていた。設定すべし。
次のConseptの章では

user=> 2r1111
15
user=> (+ 0x10 10 010)  ;(+ 16 10 8)
34

2,8,10,16進数が扱えるよと。

user=>  (Integer/toHexString 10)
"a"
user=> (. Integer toOctalString 10)
"12"

rubyに有ったっけ?

user=>  (defstruct who :name :age)
#'user/who
user=> (def me (struct who "Sakae" 56))
#'user/me
user=> me
{:name "Sakae", :age 56}
user=> (:name me)
"Sakae"
user=> (me :age)
56

どちらが先でもOKってのは、面白いなあ。

user=> (def nums (iterate inc 3))
#'user/nums
user=> (take 5 nums)
(3 4 5 6 7)

ruby 1.9 対応?

Tips編では、、、

-----
; foo.clj
(ns user)
 
(defn foo [a b]
  (str a " " b))
-----
// Foo.java
 
import clojure.lang.RT;
import clojure.lang.Var;
 
public class Foo {
    public static void main(String[] args) throws Exception {
        // Load the Clojure script -- as a side effect this initializes the runtime.
        RT.loadResourceScript("foo.clj");
 
        // Get a reference to the foo function.
        Var foo = RT.var("user", "foo");
 
        // Call it!
        Object result = foo.invoke("Hi", "there");
        System.out.println(result);
    }
}
-----

>javac -cp clojure.jar Foo.java

>java -cp clojure.jar Foo
Hi there

へぇー、Javaとclojureのコラボーションが出来るんだ。
続いて、下記は、Schemerへの重要なお知らせです。

Scheme           Clojure
 cons              cons
 list?             seq?
  car              first
  cdr              rest
  caar, cadr,      ffirst, frest,

CLな人や、LLな人への注意も出ているので、左メニューの PDF version から
PDFに変換しておいて、そいつをNetBookにでも入れておく事をお勧めします。
あれ? 携帯にPDFを入れておいて、それを読む方法ってあるのかな?

大分、道草をしてしまいました。
本題のclojure分解ですね。ソースを紐解いていきます。手元には、svn版も
ありますが、小さい方が楽だろうと言う事で、release版にします。
まずは、ソースの構図ですね。

c:\>cd app\clojure\src
c:\app\clojure\src>tree.rb -d
|-+ .
  |-+ clj
  | |-+ clojure
  |-+ jvm
    |-+ clojure
      |-+ asm
      | |-+ commons
      |-+ lang

7 directores

clj/clojureの中は、きっと かっこ、こっか の嵐でしょう。

c:\app\clojure\src>grep def clj\clojure\*
 :
(defn remove
(def data '[[a * b] + [c * d]])
(def dz (vector-zip data))

はい、その通りでした。すると、jvm/clojure の下は、必然的にJavaですね。
ソース閲覧システムである global では、Javaもサポートしてたっけかな?
調べてみると、可能なようです。
ちょいと、FreeBSDへ行って、作ってきますわ。

[sakae@fb ~]$ cd clj/src/jvm
[sakae@fb ~/clj/src/jvm]$ gtags -v
  :
 [111/113] extracting tags of clojure/lang/Util.java
 [112/113] extracting tags of clojure/lang/Var.java
 [113/113] extracting tags of clojure/lang/XMLHandler.java
[Fri Mar 20 08:38:39 JST 2009] Done.
[sakae@fb ~/clj/src/jvm]$ htags -sanohITvt 'Welcome to clojure source tour!'
  :
 [113/115] converting clojure/lang/Util.java
 [114/115] converting clojure/lang/Var.java
 [115/115] converting clojure/lang/XMLHandler.java
[Fri Mar 20 08:40:53 JST 2009] Done.
[sakae@fb ~/clj/src/jvm]$ ls
GPATH           GSYMS           HTML/
GRTAGS          GTAGS           clojure/
[sakae@fb ~/clj/src/jvm]$ w3m HTML/index.html

-------------------------------------------------------------------------
Welcome to clojure source tour!

                                      Last updated Fri Mar 20 08:40:49 JST 2009
                                                     [Powered by GLOBAL-5.7.4.]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

MAINS

main               29 clojure/lang/Compile.java public static void main(String[]
main               36 clojure/lang/Repl.java public static void main(String[] ar
main               52 clojure/lang/Script.java public static void main(String[]

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

DEFINITIONS

[A] [B] [C] [D] [E] [F] [G] [H] [I] [K] [L] [M] [N] [O] [P] [R] [S] [T] [U] [V]
[W] [X] [_] [a] [b] [c] [d] [e] [f] [g] [h] [i] [k] [l] [m] [n] [o] [p] [q] [r]
[s] [t] [u] [v] [w] [x]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

FILES

[clojure/] clojure/

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
さあ、これからは、ひたすら クリック猿に変身だ。