Elixirについて調べてみた

http://elixir-lang.org/getting-started/introduction.html
あくまでざっくりと。
↑のチュートリアルが素晴らしい。

## Macにインストール
```brew install elixir```

バージョンを確認してみる  

```
$> elixir -v  
Elixir 1.0.2
```

### vimプラギン
https://github.com/elixir-lang/vim-elixir


## 実行
* elixirシェル  

	```
	$> iex
	...
	Interactive Elixir (1.0.2) - press Ctrl+C to exit ...
	iex(1)>
	```
* elixirスクリプト

	```$> elixir hogehoge.exs```
	
* beamにコンパイル

	```$> elixirc hogehoge.ex```


## Elixirとは何なんのか
* Erlang VM上で動く、Rubyライクなシンタックスの言語
	+ Erlangのライブラリとかそのまま呼び出せる
	+ もちろんErlang/OTPの恩恵にもあずかることができる

いまのところ、ErlangおよびErlang/OTPぽいものがポップに書けるよ！
というための言語という認識

## どういうときに使いたいっぽいか
Erlangと同じだと思うけど、  

* リクエストばんばん受けまくるようなサーバーの書きたいとき
* 水平スケールさせる前提のサーバー書きたいとき
* ダウンタイムなしでコードの更新を行えるようなサーバーを書きたいとき
	+ ホットコードスワップ
* OTPの恩恵にあずかりたいとき


## Syntax
* rubyっぽいノリ

	```
	iex> 1          # integer
	iex> 0x1F       # integer
	iex> 1.0        # float
	iex> true       # boolean
	iex> :atom      # atom / symbol
	iex> "elixir"   # string
	iex> [1, 2, 3]  # list
	iex> {1, 2, 3}  # tuple
	```
	
	```
	iex> [1,2,3] ++ [4,5,6]
	[1,2,3,4,5,6]
	iex> [1,2,3] -- [2]
	[1,3]
	iex> "foo" <> "bar"
	"foobar"
	```
	
	```elixir
	defmodule Math do
     def sum(a, b) do
       do_sum(a, b)
     end
	
     defp do_sum(a, b) do
       a + b
     end
     
     def double_each([h|t]) do
       [h * 2|double_each(t)]
     end
     def double_each([]) do
       []
     end
     
     def triple_each([h|t]), do: [h * 3|triple_each(t)]
     def triple_each([]), do: []
    end
    ```
    
    ```
    iex> x = 1
	1
	iex> ^x = 2
	** (MatchError) no match of right hand side value: 2
	iex> {x, ^x} = {2, 1}
	{2, 1}
	iex> x
	2
	```
    
    ```
    iex> case {1, 2, 3} do
	...>   {4, 5, 6} ->
	...>     "This clause won't match"
	...>   {1, x, 3} ->
	...>     "This clause will match and bind x to 2"
	...>   _ ->
	...>     "This clause would match any value"
	...> end
	```
	
	```
	iex> 1..100_000 |> Enum.map(&(&1 * 3)) |> Enum.filter(odd?) |> Enum.sum
	7500000000
	```
	
	```
	iex> stream = Stream.cycle([1, 2, 3])
	#Function<47.29647706/2 in Stream.unfold/2>
	iex> Enum.take(stream, 10)
	[1, 2, 3, 1, 2, 3, 1, 2, 3, 1]
	```
	
	```
	iex> Enum.map [1, 2, 3], &(&1 + 1)
	[2, 3, 4]
	iex> :"Elixir.Enum".map [1, 2, 3], &(&1 + 1)
	[2, 3, 4]
	iex> :lists.map(&(&1 + 1), [1,2,3])
	[2, 3, 4]
	```
	
	```elixir
	defmacro unless(clause, options) do
	  quote do
	    if(!unquote(clause), do: unquote(options))
	  end
	end
	```
	
	+ def, do, end的な
	+ 文字列連結演算子...
	+ Erlangと同様、パターンマッチがいけてる
	+ Erlangは変数を再束縛できないになってるがElixirはできるようになってる
		- 一度束縛した変数をマッチング用に使いたいときは```^```をつける
	+ Erlangは変数は大文字始まりだけどElixirだと小文字始まり
		- Elixirだと大文字始まりはElixirのmodule名を表すぽい
			+  ```Enum```は```:"Elixir.Enum"```のalias
			+  ちなみに```:lists```のような感じでErlangのモジュール呼べる
	+ Erlangと同様、listをパイプでバゴっと扱える
	+ パイプオペレータがけっこう便利
		- パイプ左側のexprの結果が、右側のexprの第一引数に入る
			+ マクロで実装されてて、なんかソースがおもしろい
			+ https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/macro.ex
	+ lazyリスト
	+ マクロが強力

## Message passing
Erlangと同じノリ

```elixir
parent = self()

spawn fn -> send(parent, {:hello, self()}) end

receive do
  {:hello, msg} -> IO.puts("got message => #{inspect msg}")
after
  1_000 -> "nothing after 1s"
end
```
関係ないけど、なぜか数字の間にアンスコを入れられる
 
## Mix
アプリケーションの作成はmixというツールがなんかいい感じにやってくれるっぽい。
railsでいうrake的な。

```$> mix new kv --module kv```

## exrm
https://github.com/bitwalker/exrm  
リリースマネージャ
地味だけどよい

## 感想
* なんか楽しい
* SIPサーバはnodeじゃなくてこれ使うべきだった
* 見た目rubyっぽいわりに別にOOじゃないので一瞬混乱する
* Erlang/OTPの仕組みがやはりすごい