この投稿は
Elixir Advent Calendar 2014の1日目の記事です。
今年後半になってようやくElixirを触り始めました。初心者の踏んだ罠や、良さを感じたところなどを紹介したいと思います。Elixir v1.0になってから触った日本人初心者というのもあまり多くはないはずなので、これから誰かに勧めたい人・あるいはこれから始めたい人の参考になれば。
モチベーション
何故Elixirを触りたくなったかというと、特に突飛な理由はなく…
この2点です。メモリ回収がプロセス単位GC+参照カウントバイナリなErlang VM、圧倒的な稼働実績を誇るOTP、どちらも代替になるものがないので。普通にErlang書けよと言われればまあそうなのですが、どうせなら変わったものを使ってみようという好奇心ですね。
◎良かった点
文字列の扱いが楽
iex(28)> str = "hogehige"
"hogehige"
iex(29)> str <> "123"
"hogehige123"
iex(30)> "hoge" <> s = str
"hogehige"
iex(31)> s
"hige"
- 文字列に値を埋め込みたいときは、だいたいinspectでOK
iex(34)> "value: " <> inspect xs
"value: [1, 2, 3, 4, 5, 4, 3, 2, 1, 4]"
iex(35)> "value: #{inspect xs}"
"value: [1, 2, 3, 4, 5, 4, 3, 2, 1, 4]"
iex(36)> "value: #{inspect xs |> Enum.take 2}"
"value: [1, 2]"
ただ、全部Unicodeで処理してくれるElixirのライブラリは、Erlangにあるものとは別の枯れていないライブラリなので、性能とか信頼性とかは若干怪しげです。先日、「\n\rが1文字にカウントされる」という謎のバグを踏んで、ちょっとビビってました。
既に修正が入っているようですが。
REPL (iex) が使いやすい
組み込みのプロジェクト管理
mix で作ったプロジェクト、その中で作ったモジュールがコマンドラインで簡単に読み込んで試せる(という機構がデフォルトでついてくる)のが楽でした。
iex -S mix
これで起動するとプロジェクト中のMyModule.hogeなどを試せる。l(MyModule)でリロード。ちゃんとしたテストのフレームワークも揃っていますが、色々よくわかっていない段階では、テストとしてメンテすべき単位よりも小さい単位でずんどこコケますので…。ここ
Valueじゃなくて
[Value]が返ってきてたのかー、みたいな。
Erlangのerlと比べると、再代入出来たり行末に記号が必要なかったりという仕様はREPLとの相性がよく、ヒストリから使い回すのも簡単。触っているときの快適さはかなり違います。
パイプライン演算子 |>
F#のステキアイテム、パイプライン演算子。
iex(11)> Enum.take(xs, 5)
[1, 2, 3, 4, 5]
iex(12)> xs |> Enum.take 5
[1, 2, 3, 4, 5]
iex(13)> xs |> Enum.take(5) |> Enum.map &(&1 * 2)
[2, 4, 6, 8, 10]
Erlangっぽく
{:ok, xxx}で返ってくる関数が困るのですが、それについては
去年のAdvent Calendarにあるmururuさんの説明が詳しいのでそちらを。末尾に ! のついた関数(Dicr.fetch!など)を使うと、
:ok のタプルではなくて直接結果が返ってくるものがあるので組み合わせやすいですが、それで全体を例外処理で囲んじゃう方法が良いのかどうかは、ちょっとまだわからない…。
△はまった点
わかってみれば大したことではないけれども、多分みんな通る(ような気がする)部分もいくつか。
整数のリストを表示しようとしてびびる
iex(43)> now_hp = [64, 57, 67, 83, 49, 33]
'@9CS1!'
ファッ!?
これはErlangで、文字列と整数のリストの区別がないからですね…。
inspectのオプションに
:char_listsがあるのですが、触り始めたら早い時期に踏む仕様なのに、初心者がそこまで自力でたどり着くのはなかなか厳しいのでは。もし今後初心者向けの紹介を書く人がいたら、これには一言触れておいて欲しいところ…
iex(44)> [-1 | now_hp]
[-1, 64, 57, 67, 83, 49, 33]
とりあえず仮で表示するだけの場合は、ASCII文字っぽく見えないようにするWorkaroundで回避しています。
mapはどこ?
Listに対してmap処理をしようとしたら
ListにMapはありませんでした。
Enumの方にまとめられているんですね。List.foldlはあるがList.mapはない!List.tailはどこにもない?なかなか覚えられなくて、いまだにEnumのドキュメントは開きっぱなしでコーディングしています orz
総括
生のErlangと比べるとだいぶ初心者にやさしい言語ですね!
なんとかErlangのプロジェクトを、最初は部分的にでも乗っ取る感じで使えたらいいなーと目論んでおります。
この投稿は
Elixir Advent Calendar 2014の1日目の記事でした。
次は
niku さんです →
2014/12/02/Extwitterでtwitter streamingを眺めてあそぶ - ヽ(´・肉・`)ノログ