Help us understand the problem. What is going on with this article?

JavaScript、森でClojureに出会う

More than 5 years have passed since last update.

Moriというライブラリを見つけた。

どうやら、Clojure永続データ構造 (persistent data structure)をJavaScript環境に提供するモノらしい。ライブラリ自体はClojureScriptで書かれていて、それがJavaScriptやCoffeeScriptから使えるようになっている。

永続データ構造は「不変オブジェクト(immutable object)」とも呼ばれるが、要は作成後に値が変更できないデータ。C++のconst指定された変数やJavaのString Classのインスタンスがそれに当たる。Clojureでは基本的にデータはimmutableで、オブジェクトに操作が加わる度に新しいオブジェクトができる。

「それって非効率!」って思うがそれ相当の利点もある。例えば、JavaScriptで以下の操作を考える。

var a = [1,2,3];
var b = a;
b.push(4);
console.log(b); // --> [1,2,3,4]  (bに4が追加された)
console.log(a); // --> [1,2,3,4]  (aも変わっちゃった!)

aとbは同じオブジェクトを参照しているので当たり前の結果だが、こういった参照コピーを繰り返すと思わぬところでの変更が他に波及したりする。まぁ、それが起きないように設計するのが筋なのだが、bだけに変更を加えるにはコピーしてから使うか、Array.concat()の様に元のデータに影響を与えないメソッドを使うしかない。

で、Clojureが取っているのは後者のアプローチ。つまりデータを直接いじるメソッドは無い。代わりにデータを受け取り、変更して返す関数を色々と取り揃えている。

効率に関しても、元データがimmutableであることが保証されるとコピーの際も元のデータを参照した上で変更分だけ記録なんてことができるのでそれほどおかしな事にはならない。

そしてMoriはそれをJavascriptの世界に持ってきた。

以下はnode.jsで使う場合だが、まずインストールはいつもの様にnpmで。

$ npm install mori

そして上記の例はこうなる。

var mori = require("mori");

var a = mori.vector(1,2,3);
var b = mori.conj(a, 4);
console.log(b); // --> [1,2,3,4] (bに4が追加された)
console.log(a); // --> [1,2,3] (aの値は不変)

さらにfunctional programming 風にこんなことも。

var mori = require("mori");

var inc = function(n) {
  return n+1;
};
var sum = function(a, b) {
  return a + b;
};

var a = mori.list(1,2,3,4,5);
var b = mori.map(inc, a);
var c = mori.reduce(sum, b);

console.log(a); // --> (1 2 3 4 5) (もちろんaの値は不変)
console.log(b); // --> (2 3 4 5 6) (それぞれの値に1が足されている)
console.log(c); // --> 20 (bの値の総和)

当然CoffeeScriptでも使えて、上記例を思いっきり短くするとこうなる。

mori = require "mori"

inc = (n)-> n+1
sum = (a, b)-> a+b

c = mori.reduce sum, mori.map inc, mori.list 1,2,3,4,5
console.log c # --> 20

さすがにここまでカッコを省略すると判りにくいか ...

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away