Clojure という言語がある。最近の言語はどれも関数型言語のアイデアを実用的に使えるようにするというのが目標に入っていると思うけど、Clojure は最も自然にそれを実現していて私はすごく気に入っている。という事で、実際にどんな感じなのか試してみた。
一番簡単なインストールと実行方法
ホームページにはインストールの方法が沢山書いてある。沢山ありすぎて正直うっとおしい。色々試して、結局素直に zip をダウンロードして適当な場所に置くだけというのが一番簡単だと分かった。具体的には http://clojure.googlecode.com/files/clojure-1.1.0.zip をダウンロードして中の clojure.jar を自分のディレクトリに置けば良い。実行は次のようにする。
$ java -jar clojure.jar Clojure 1.1.0 user=> (+ 3 4) 7
これで clojure を電卓のように使える。プログラムをファイルに書いて実行するやり方も色々ある。まず、hello.clj というファイルがあるとして、
;; hello.clj (javax.swing.JOptionPane/showMessageDialog nil "Hello, World!")
先ほどの clojure.jar の後ろにファイル名を書くとそのファイルが実行される。
$ java -jar clojure.jar hello.clj (Hello, World! というダイアログが表示される)
または LISP っぽく REPL の中でロードしてもよい。
$ java -jar clojure.jar Clojure 1.1.0 user=> (load "hello") nil
面白い事に、このロードも遅延評価でやっているらしく、括弧を多い目に書いたりするとプログラムが実行されてからエラーが出る。
Clojure はどのようにして Java を使っているか
私が今作ってるコンパイラの参考にしようと思って、Clojure のデータ構造について調べている。Clojure では わりと Java のデータをそのまま使って、無い奴だけ Clojure で実装している。型を知るのは type 関数を使う。ちなみに、シェルで (doc type) のようにすると関数の説明が出て来てとても親切。
;; typetest.clj (print "What kind of object does Clojure use?\n\n") (defn print-type [title obj] (println title ":" obj "=>\t\t\t" (type obj))) (print-type "integer" 1) (print-type "string" "Hello World!") (print-type "float" 3.14) (print-type "list" '(1 hello 3)) (print-type "symbol" 'hello-world) (print-type "vector" '[1 hello]) (print-type "character" \c)
user=> (doc type) ------------------------- clojure.core/type ([x]) Returns the :type metadata of x, or its Class if none nil user=> (load "typetest") What kind of object does Clojure use? integer : 1 => java.lang.Integer string : Hello World! => java.lang.String float : 3.14 => java.lang.Double list : (1 hello 3) => clojure.lang.PersistentList symbol : hello-world => clojure.lang.Symbol vector : [1 hello] => clojure.lang.PersistentVector character : c => java.lang.Character nil user=>
気づいた事。リストの中身は同じ型じゃ無くて良い。何でも入れられる。ただし、まともなリストしかない。lisp で言う(hello . world) みたいなのは無い。また、例えばリストの実装について調べたい時は zip の中の src/jvm/clojure/lang/PersistentList.java を見れば良い。