Elixir の関数は、関数を返すことができて、その関数は元の環境を覚えている。だからこないだのエントリでは「クロージャだ」と書いた。
だけど、今日になって違うんじゃないかと思うようになった。というのは、返ってきた関数は確かに元の環境を覚えているけど変更はできないみたいだからだ。
例えば、JavaScript で典型的なクロージャを書いてみよう。下の make_counter
関数の返す関数は、呼び出されるごとに 1 ずつ大きな数を返す。
function make_counter(init) { var count = init; return function() { count = count + 1; return count } } var counter = make_counter(0); console.log(counter()); console.log(counter()); console.log(counter());
^o^ > node counter.js 1 2 3
Elixir で同じように書いてみよう。
defmodule Counter do def make(init) do count = init fn -> count = count + 1 count end end end counter = Counter.make(0) IO.puts counter.() IO.puts counter.() IO.puts counter.()
見てわかるように、JavaScript のコードをほぼそのまま Elixir で書き直したものだ。ところが、これを実行してみると:
^o^ > elixir counter.exs 1 1 1
このとおり、関数を何度呼び出しても数が増えていかない。
これって、やっぱりクロージャとは言わないんじゃ?それとも何か間違ってる?