Clojure

Clojure (クロージャーと発音) は、関数型プログラミング言語であり、LISPの方言の一つです。この言語は、関数型プログラミングのスタイルでのインタラクティブな開発を支援し、マルチスレッドプログラムの開発を容易にすることを目的とした汎用言語として設計されました。ClojureのプログラムはJava仮想マシン(JVM)上で動作しますが、.NET環境で動作するClojureCLRも存在します。

設計思想


Clojureは、リッチ・ヒッキーによって設計されました。その目的は、既存のJavaプラットフォーム上で動作し、並行コンピューティングを可能にする関数型のLISP言語を作ることでした。Clojureの並行処理は、状態の不変性という概念に基づいています。状態が変更されないため、複数の操作を並列で実行でき、並列処理の問題は状態遷移の管理へと変換されます。このため、Clojureには状態遷移を明確に定義する可変な参照型が用意されています。

文法


ClojureのプログラムはS式で記述されます。コードはコンパイル前にリーダーによって解析され、内部データ構造に変換されます。Clojureのリーダーは、リストだけでなく、配列ハッシュテーブル集合もリテラル表現として扱えます。ClojureはLisp-1であり、関数名と変数名は同一の名前空間に存在します。しかし、他のLISP系言語との互換性は考慮されていません。

マクロ


Clojureのマクロ機構は、Common Lispに似ていますが、シンタックス・クオートを使用する際、個々の記号がローカル名前空間で区別される点が異なります。これにより、マクロ展開時の変数のキャプチャを回避できます。変数のキャプチャを強制することも可能ですが、明示的に行う必要があります。また、別の名前空間の大域変数を現在の名前空間で変更することはできません。

言語の特徴



対話型開発: REPLによる動的な開発が可能です。
関数: 第一級オブジェクトとして扱われ、副作用に依存しない再帰呼び出しが基本です。
遅延シーケンス: 必要になるまで評価を遅らせる遅延シーケンスをサポートします。
イミュータブルなデータ構造: 変更不可能なデータ構造を使用します。
並行処理: ソフトウェアトランザクショナルメモリ(STM)、エージェントシステム、動的varシステムなどを使用して並行処理をサポートします。
コンパイル: Java仮想マシンのバイトコードを生成するコンパイラ言語です。
マルチメソッド: 複数の引数の型に基づいて実行される処理を切り替えることができます。
Javaとの統合: Javaの既存のシステムを活用しやすく、APIの呼び出しも簡単です。Clojureのデータ構造はJavaの標準インターフェースを実装しており、JavaからClojureのプログラムを呼び出すのも容易です。



Hello World (CUI版):

clojure
(println "Hello, World!")


Hello World (GUI版):
clojure
(import '(javax.swing JFrame JLabel))
(defn hello-world []
(let [frame (JFrame. "Hello")
label (JLabel. "Hello, World!")]
(.add (.getContentPane frame) label)
(.setSize frame 300 200)
(.setVisible frame true)))
(hello-world)


スレッドセーフな生成器:
clojure
(def counter (atom 0))
(defn next-id [] (swap! counter inc))


無名クラス、マクロ:
clojure
(defmacro with-silent-output [& body]
`(let [out# (java.io.Writer.)]
(binding [out out#]
~@body)))

(with-silent-output (println "This will not be printed"))


ソフトウェアトランザクショナルメモリ (STM):
clojure
(def vectors (vec (repeatedly 100 #(ref (vec (range 10))))))
(defn swap-elements [v1-idx v2-idx]
(dosync
(let [v1 @(nth vectors v1-idx)
v2 @(nth vectors v2-idx)
idx1 (rand-int (count v1))
idx2 (rand-int (count v2))
temp (nth v1 idx1)]
(alter (nth vectors v1-idx) assoc idx1 (nth v2 idx2))
(alter (nth vectors v2-idx) assoc idx2 temp))))

(dotimes [_ 300000]
(let [v1-idx (rand-int 100)
v2-idx (rand-int 100)]
(swap-elements v1-idx v2-idx)))


外部リンク



Clojure言語 公式ウェブサイト
Clojure言語 GitHub コード・リポジトリ
Clojure言語の総合解説
Full Disclojure - Screencast
developerWorks JapanのClojure言語解説記事(日本語)
Clojure conj 開発者会議

もう一度検索

【記事の利用について】

タイトルと記事文章は、記事のあるページにリンクを張っていただければ、無料で利用できます。
※画像は、利用できませんのでご注意ください。

【リンクついて】

リンクフリーです。