はじめてのClojureソースコードリーディング[その1 準備編]

## 前書き

Clojureのソースコードを読んでいく過程を書いていきたいと思います。

2014年9月10日のmasterブランチから読み進めていきます。
https://github.com/clojure/clojure

追加された変更に関しては余裕があったら見ていきたいと思っています。

## 環境の準備

ひとまず、現状のコードをローカルにcloneする。
トップレベルのディレクトリにpom.xmlがあるので、ディレクトリ構造的にはmavenのプロジェクトに準じているようだ。

ディレクトリ構造はおおまかに以下のような感じになっている。

```
├── pom.xml
├── src
│   ├── clj
│   │   └── clojure
│   │       ├── core
│   │       ├── java
│   │       ├── pprint
│   │       ├── reflect
│   │       └── test
│   ├── jvm
│   │   └── clojure
│   │       ├── asm
│   │       │   └── commons
│   │       ├── java
│   │       │   └── api
│   │       └── lang
│   ├── resources
│   └── script
└── test
    ├── clojure
    │   └── test_clojure
    └── java
        ├── clojure
        └── compilationd
```

Javaの中核となるコードは`src/jvm/clojure/lang`にあるようなので、まずはここから読み始めた方が良さそう。
リポジトリのファイル内に`.idea`ディレクトリがあることや`.gitignore`に.ipr、.iwsが含まれることから開発にはIntelliJ IDEAが使われているようだ。

Community Editionをダウンロードしてインストールした。
http://www.jetbrains.com/idea/

インストール直後だとClojureのコードがシンタックスハイライトされないので、pluginのCursive Clojureをインストール。
https://cursiveclojure.com/

ひとまず、コードを読む環境は整ったと思う。

build.xmlもあるのでantでのビルドにも対応しているのだろうか。

## clojure.langを読み込む

```bash
$ cd clojure/src/jvm/clojure/lang
$ ls -1 | wc -l
     124
```

clojure.langパッケージ内にはファイルが124ある。
まずはどこから読めば良いか、分類し、確認していく。

それぞれのファイルのコード量がどの程度か見てみる。

```bash
$ find . -type f | xargs wc -l | sort                                                                                         
      13 ./Sequential.java
      14 ./IRecord.java
      14 ./IType.java
      15 ./IPending.java
      16 ./Fn.java
      16 ./IPersistentList.java
      16 ./IndexedSeq.java
      17 ./IBlockingDeref.java
      17 ./IDeref.java
      17 ./IEditableCollection.java
      17 ./IHashEq.java
      17 ./IKeywordLookup.java
      17 ./IMeta.java
      17 ./MapEquivalence.java
      17 ./Reversible.java
      17 ./Seqable.java
      18 ./Counted.java
      18 ./IObj.java
      18 ./IReference.java
      18 ./ITransientAssociative.java
      18 ./Settable.java
      19 ./Associative.java
      19 ./ILookup.java
      19 ./ILookupSite.java
      19 ./ILookupThunk.java
      19 ./IMapEntry.java
      19 ./IPersistentSet.java
      19 ./IPersistentStack.java
      19 ./IReduce.java
      19 ./ITransientSet.java
      19 ./Indexed.java
      19 ./Named.java
      20 ./IChunk.java
      20 ./IExceptionInfo.java
      20 ./IPersistentVector.java
      20 ./ITransientCollection.java
      20 ./ITransientVector.java
      21 ./IProxy.java
      21 ./package.html
      22 ./Box.java
      22 ./ITransientMap.java
      22 ./Repl.java
      22 ./Script.java
      22 ./WarnBoxedMath.java
      23 ./IChunkedSeq.java
      23 ./IPersistentCollection.java
      23 ./IPersistentMap.java
      23 ./Reduced.java
      25 ./Sorted.java
      26 ./Binding.java
      27 ./IRef.java
      29 ./ISeq.java
      29 ./Volatile.java
      32 ./ArityException.java
      33 ./SeqEnumeration.java
      34 ./LazilyPersistentVector.java
      35 ./Obj.java
      37 ./ChunkBuffer.java
      40 ./AReference.java
      40 ./MapEntry.java
      42 ./ExceptionInfo.java
      53 ./Delay.java
      54 ./ATransientSet.java
      54 ./StringSeq.java
      55 ./Cons.java
      55 ./SeqIterator.java
      57 ./KeywordLookupSite.java
      59 ./AFunction.java
      64 ./Range.java
      67 ./ChunkedCons.java
      69 ./ArrayChunk.java
      72 ./ProxyHandler.java
      75 ./FnLoaderThunk.java
      75 ./IteratorSeq.java
      76 ./DynamicClassLoader.java
      78 ./Compile.java
      78 ./EnumerationSeq.java
      78 ./Ratio.java
      85 ./ARef.java
      86 ./ATransientMap.java
      88 ./MethodImplCache.java
      89 ./XMLHandler.java
      90 ./PersistentTreeSet.java
      95 ./LineNumberingPushbackReader.java
     104 ./Atom.java
     128 ./PersistentHashSet.java
     136 ./Intrinsics.java
     136 ./Symbol.java
     149 ./AMapEntry.java
     151 ./Murmur3.java
     176 ./APersistentSet.java
     181 ./TransactionalHashMap.java
     182 ./BigInt.java
     233 ./PersistentStructMap.java
     242 ./LazySeq.java
     243 ./Namespace.java
     248 ./Util.java
     258 ./Keyword.java
     262 ./ASeq.java
     278 ./ArrayIter.java
     287 ./Agent.java
     309 ./PersistentQueue.java
     316 ./PersistentList.java
     351 ./LazyTransformer.java
     369 ./Ref.java
     406 ./APersistentMap.java
     431 ./AFn.java
     450 ./PersistentArrayMap.java
     455 ./IFn.java
     529 ./Reflector.java
     586 ./MultiFn.java
     597 ./APersistentVector.java
     653 ./LockingTransaction.java
     702 ./ArraySeq.java
     715 ./Var.java
     737 ./EdnReader.java
     821 ./PersistentVector.java
    1029 ./PersistentTreeMap.java
    1180 ./PersistentHashMap.java
    1281 ./LispReader.java
    2295 ./RT.java
    4104 ./RestFn.java
    4131 ./Numbers.java
    8563 ./Compiler.java
   37385 total
```

LispReader、EdnReader、Compilerあたりがそれっぽい。
~~RTはおそらくリテラル。~~
RTはRuntimeクラス。（Practical Clojure参照 P.149 Clojureはインタプリタ持っていないとか重要なことが書いてあった。）
I〜がインターフェースでA〜が抽象クラスという命名規則かと思ったら、一部違ったりしている。

全体像がまだよくわからないのでjavadocを生成してみる。

```bash
$ mvn clean
$ mvn javadoc:javadoc
$ cd target/site/apidocs
$ open index.html
```

jarの生成は以下で問題なくできた。

```bash
$ mvn clean
$ mvn package
```

生成したjarの実行は以下のようになる。

```bash
$ java -cp ./target/clojure-1.7.0-master-SNAPSHOT.jar clojure.main
```