ClojureCLR
ClojureCLRは、windowsの.net環境向けに作られたClojure実行環境です。
現在は、Clojureのgithubアカウントに統合されて、開発が進んでいます。
https://github.com/clojure/clojure-clr/wiki
githubのコミット履歴を確認すると、jvm向けのコミットに対応したポートを作成しつつ、CLR独自の対応を進めていることが分かります。
最新版は、Clojure 1.5.1に対応してます。
また、徐々にですがMono環境への対応も進めています。
以下、Mono環境での話を進めていきます。
基本コマンド
REPLの実行は、mono Clojure.Main.exe
です。 java -cp clojure-1.5.1.jar clojure.main
にあたります。
コンパイルの実行は、mono Clojure.Compile.exe
です。
hoge.clj ファイルから hoge.clj.dllファイルが作成されます。
nsにgen-classの指定がある場合は、exeファイル(.net環境の実行ファイル)が作成されます。
ライブラリ
ライブラリが、clojureの関数のみに依存している場合は、そのまま利用できますが、
JVMに依存しているライブラリは置き換えが必要です。
coreライブラリ
coreライブラリ中のclojure.javaネームスペースについては、clojure.clrに置き換えてあります。
- clojure.clr.io (clojure.java.io)
- clojure.clr.shell (clojure.java.shell)
contributeライブラリ
clojure のgithubには、下記の8つが登録されています。
- clr.data.json
- clr.data.generators
- clr.test.generative
- clr.tools.nrepl
- clr.tools.namespace
- clr.tools.analyzer
- clr.tools.logging
- clr.tools.trace
contributeライブラリでは管理者が別になるため、同じネームスペースでは管理せずに、
java APIに依存したライブラリを移植して、clrを先頭に付けたライブラリを用意しています。
その他
- cljclr.tools.cli (clojure.tools.cli)
contributeに登録されていないライブラリです。
ネームスペースは、現在のところclrではなくcljclrを使っているようです。
nuget
nugetには、7つのパッケージが登録されています。
http://www.nuget.org/packages?q=clojureclr
-
Clojure By: dmiller kocubinski aaronc
-
ClojureClrEx By: kocubinski aaronc
-
clojure.data.json By: dmiller
-
clojure.tools.namespace By: dmiller
-
clojure.data.generators By: dmiller
-
clojure.test.generative By: dmiller
-
cljclr.tools.cli By: rippinrobr
ClojureCLRをビルドするときにtest関連プロジェクトで必要なため、nugetで管理しています。
lein-clr
Clojure.Main.exeは、Windowsのコマンドプロンプトを前提に設計されており、うまく使えない状況のため、MonoからREPLを操作するには、nrepl経由の操作が必要になります。
javaでleinプロジェクトを作成することになりますが、
手軽に試せるので、こちらを紹介して記事を終わりにしたいと思います。
事前準備
monoとleiningenは、別途用意してください。
OSXの場合、
monoは、XamarinStudioと一緒または、公式ページからMonoのRuntimeを入れることができます。
leiningenは、homebrewから$ brew install leiningen
で、インストールできます。
プロジェクト作成
プロジェクトを作成します。
$ lein new lein-clr hello
$ cd hello
ClojureCLRのダウンロード
ダウンロードします。
$ wget http://jaist.dl.sourceforge.net/project/clojureclr/clojure-clr-1.5.0-Release-4.0.zip
$ unzip clojure-clr-1.5.0-Release-4.0.zip
設定
project.clj内で、CLJCLR14_40環境変数にClojureCLRが存在する前提になっているので、今回はそのまま設定します。
$ export CLJCLR14_40 = `pwd`/Release
REPL実行
nrepl経由で、REPLを実行します。
$ lein clr repl
user=> *clojure-version*
{:major 1, :minor 5, :incremental 0, :qualifier ""}
となります。
メイン関数実行
main関数を実行します。
$ lein clr run -m hello.core x y z
true
Received args: x y z
で、src/hello/core.clj
のコマンドライン引数を表示する-main関数が実行されました。
コンパイル
バイトコードにコンパイルします。
$ lein clr compile :all
Compiling hello.core to /Users/kyusa/Works/test/hello/target/clr/bin -- 122 milliseconds.
Compiling hello.core-test to /Users/kyusa/Works/test/hello/target/clr/bin -- 80 milliseconds.
exeファイル作成
src/hello/core.clj
に(:gen-class)
を追加してコンパイルします。
(ns hello.core
(:gen-class))
$ lein clr compile :all
Compiling hello.core to /Users/kyusa/Works/test/hello/target/clr/bin -- 149 milliseconds.
Compiling hello.core-test to /Users/kyusa/Works/test/hello/target/clr/bin -- 77 milliseconds.
$ ls target/clr/bin
hello.core.clj.dll hello.core.exe hello.core_test.clj.dll
今度は、exeファイルが作成されました。
exeの実行
それでは、exeファイルを実行します。
$ MONO_PATH=$CLJCLR14_40 mono target/clr/bin/hello.core.exe x y z
Received args: x y z
monoで参照するdllファイル(アセンブリファイル)のパス(javaの-cpにあたります)は、MONO_PATH環境変数で指定できます。
参考サイト(MONO_PATH)
http://kakurasan.ehoh.net/summary/lib.exec.mono.html
http://www.mono-project.com/Best_Practices
AOT
事前コンパイルして、起動時間を短縮できます。
mono --aot Release/*.dll
mono --aot target/clr/bin/*.dll
今回、エラーが出てしまい、うまくAOTコンパイル出来ませんでした。
下記は、別途用意したClojureCLRで確認した結果です。
AOT前
$ MONO_PATH=$CLJCLR14_40 time mono target/clr/bin/hello.core.exe x y z
Received args: x y z
1.56 real 1.52 user 0.04 sys
AOT後
$ MONO_PATH=$CLJCLR14_40 time mono target/clr/bin/hello.core.exe x y z
Received args: x y z
0.68 real 0.66 user 0.02 sys
JITおよびAOTの利点と欠点は、下記のサイトなどを参考にしてください。
http://www.ibm.com/developerworks/jp/java/library/j-rtj2/
LLVMバックエンド
また、monoではVMにllvmが利用できますので試してみましょう。
OSXの場合、libmono-llvm.bundle(soのかたまり)ファイルを参照するため、LD_LIBRARY_PATH環境変数の指定が必要です。
LD_LIBRARY_PATH=/Library/Frameworks/Mono.framework/Versions/Current/lib MONO_PATH=$CLJCLR14_40 time mono --llvm target/clr/bin/hello.core.exe x y z
Received args: x y z
5.69 real 5.63 user 0.04 sys
初期化の実行に時間がかかるため、単純な場合はあまり意味がありませんが、
科学計算などでは効果があるようです。
以上で終わりです。