LoginSignup
15
14

More than 5 years have passed since last update.

ClojureCLRあれこれ

Last updated at Posted at 2013-12-09

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)を追加してコンパイルします。

src/hello/core.clj
(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

初期化の実行に時間がかかるため、単純な場合はあまり意味がありませんが、
科学計算などでは効果があるようです。

以上で終わりです。

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14