2009年4月29日水曜日

Clojureのlistとvector初見

Clojureは便利な組み込みのデータ型を備えている。
これらはぜんぶが全部immutable、変更不可能になっている。
でも参照を扱う仕組みが別にあって、参照先が変更可能なので、
ErlangやHaskellより命令的に破壊的な操作?を書ける。
そこはSTMと絡んでくるので後回し。

Clojureは動的型で、Pythonの組み込み関数typeと同じように
型について調べる事ができる。
user> (type 1)
java.lang.Integer

整数や文字列などはJavaのクラスがそのまま使われているようだ。
JavaのVMの仕組みはわからないけれど、
Javaは静的型なので、こういったインスタンスやクラスの情報は
なんらかの形でラップされて扱われているんだろうと思われる。
型もふつうのオブジェクトのようで、比較ができる。
user> (= (type 1) (type 3))
true
user> (= (type 1) (type 30000000000000000000000))
false

typeのtype、Pythonだとメタクラスになるところだが、
おなじようなものだろう。
user> (type (type 1))
java.lang.Class
user> (type (type (type 1)))
java.lang.Class

文字列や、大きい整数もこんな具合。
user> (type "abc")
java.lang.String
user> (type 10000000000000)
java.lang.Long
user> (type 100000000000000000000000000)
java.math.BigInteger

コンテナ型は、Clojure独自に定義されている。
immutableということで、PersistentHoge
という名前が付けられている。
user> (type [])
clojure.lang.PersistentVector

これはPersistentVector。単にvectorと呼ばれることの方が多い。
IPersistentVectorというのは明らかにインターフェースと思われるが
MultiMethodsと関係してくるのだろうか?今は不明。

user> (type ())
clojure.lang.PersistentList$EmptyList

こっちはPersistentList。EmptyListとついているのが気になる。
これがうわさのMetadataか?
listとvectorが別にある。vectorの方が可変長配列でlistはリンクリスト
ってことだろうか。
listは当然だがvectorにもリテラルが用意されている。
user> [1 2 3 4]
[1 2 3 4]
user> [1, 2, 3, 4]
[1 2 3 4]

カンマは、あっても無くても同じ。
好き嫌いが分かれそうだが、僕は嫌いじゃない。
関数で生成することもできる。
user> (vector 1 2 3 4)
[1 2 3 4]
user> (vector)
[]

listのほうはこんなかんじ。
user> '(1 2 3 4)
(1 2 3 4)
user> '(1, 2, 3, 4)
(1 2 3 4)
user> (list 1 2 3 4)
(1 2 3 4)

Lispですね。

0 件のコメント:

コメントを投稿