[elixir][erlang] erlang/OTP-R17とelixir

やっとerlang/OTP-R17がリリースされました。UTF-8の全面採用、mapsデータ型の(実験的)サポート、名前つき無名関数など盛りだくさん。

Maps -- Records are dead, long live maps!

いわゆるperlでのハッシュがやっと実装された。これまではproplistモジュールやETSなどで同様のことを行ってきたが、言語そのものに実装されたのはやはり大きい。

> M = #{a => 1, b => 2}.
#{a=>1, b=> 2}
> #{b := N} = M.
#{a=>1, b=> 2}
> N.
2

こんな感じで使う。'=>'は新しいキーの割当で':='は既存のキーに対する操作なので、間違えるとエラーになる親切設計。というかimmutableな言語なので当然。

> M = #{a => 1, b => 2}.
#{a=>1, b=> 2}
> #{c := N2} = M.
** exception error: no match of right hand side value #{a => 1,b => 2}
> #{b => N3} = M.
* 1: illegal pattern

このようにエラーもきちんと出る。

elixirでは %{}という記法で記述可能。

> a = %{:a => 1, :b => 2}
%{a: 1, b: 2}
> %{a | b: 3}
%{a: 1, b: 3}
> %{b: c} = a
%{a: 1, b: 2}
> c
2

既存のmapsの更新がちょっと気持ち悪いけどまぁいい感じに使えそう。

named fun

名前つきの無名関数とは意味不明だが、lispでいうlabelsに相当するもので、無名関数中で自分自身を参照できるというのがプリティなところ。

> F = fun Fib(0) -> 0;
                Fib(1) -> 1;
                Fib(N) -> Fib(N-1) + Fib(N-2) end.
#Fun<erl_eval.30.106461118>
> F(30).
832040

こんな感じで、fun 名前 (引数) -> 本体 という形で使う。本体中では名前を参照できる。
elixir-v0.12.5ではまだサポートされていない模様。