Elixir 一個月深入使用感想

原本不太打算寫這篇, 因為深感自己太嫩, 分享技術無觀眾, 不要誤人子弟, 不過想想還是寫了.

Elixir 是一個基於 Erlang VM 上的新語言.
Elixir 有許多優點包含 syntax, marco, DSL, 等等 以及來自 Erlang 的一切.

對於 rubiest 來說要上手 Elixir 應該頗快.
語法本身相似, 連 template engine 都很像.

不像的部分

簡略介紹幾個 ( 直接以 code 呈現 ) :

#ruby 
[0..10].times.each{|i| xxx }
# elixir
for i <- 0..10 do  
   xxx
end  

a=[1,2,3,4,5]  
#ruby
a.each{|i| xxx }  
#elixir 
Enum.map(a, fn(i)->  xxx  end)  

由上面可知, 基本差異就是 oo 跟 functional 的差別.
Elixir 本身沒有物件, 所以沒有辦法用 oo 的想法在那邊 . 來 . 去, 串接每個 function.
以下例來看, 在 ruby 裏寫很輕鬆, 在 elixir 就有點麻煩.

#ruby   
a={:dog=>{:bark=>"not bark yet"}}  
a[:dog][:bark]="bark bark"

#elixir
a=%{:dog=>{:bark=>"not bark yet",:walk=>{:speed=>10}}}  
a=Map.put(a,:dog, (Map.put(a[:dog], :bark, "bark bark")) )  

可想而知, 如果疊上去就很可怕.
當然也許會有其他解法, 但至少我目前還不知道, 所以我就自己寫了個 lib 可以用比較不噁心的方式出裡 :

a=Map.put(a, :dog, :bark, "bark bark")  
a=Map.put(a, :dog, :walk, :speed, 30)  

值得注意的是最上面的程式沒有提到, Elixir 中的變數都是區塊變數, 所以 fn 裡做任何事不會改變 fn 外的變數,
如果要強迫值改變, 則要透過回傳, 如下 :

a=[1,2,3]  
Enum.map(a, fn(i) -> i = i+1 end)  #=> [2,3,4]  
a #=> [1,2,3]

List.replace_at(a, 1, 10) #=> [1,10,3]  
a #=> [1,2,3]

a=List.replace_at(a, 1, 10) #=> [1,10,3]  
a #=> [1,10,3]

a=for i <- a do  
    i+1
end  #=>[2,11,4]

a #=> [2,11,4]  

另一個最大的差異應該是 patten match.
在 elixir ( erlang 也是 ) 裡, 幾乎所有東西都是 patten match.
舉例 :

{integer,_}=Integer.parse("1")
{:ok, value}=Some.function()

例子中可以看到我們 parse 整數, 然後回傳需要用 patten match, _ 代表忽略.
不過當 Integer 無法 parse, 會回傳 :error, 此時如果沒有任何 patten 去 match, 就會報錯.
所以完整的寫法應該類似 :

case Integer.parse("1") do  
    {integer,_} ->  do something
    :error -> do something
    _ -> do something for rest conditions
end  

其他不像的部分大概就是一些型別, 判斷式.
這部分就不贅述.

像的部分

簡略舉例 :

#ruby 
Module Dog  
    def bark do
       puts "bark"
    end
end  
#elixir 
defmodule Dog do  
    def bark do 
       IO.puts "bark"
    end
end

#ruby - console
$> irb
$> rake
$> rake 
$> rails new
$> gem install xxx
#elixir - console
$> iex
$> mix
$> mix phoenix.new
$> mix deps.get


#ruby - erb
<%=@hi%>  
<%if a==1 do%>  
    something here
<%end%>  
#elixir - eex
<%=@hi%>  
<%= if a==1 do %>  
    something here
<% end %>  

優點

優點當然就是速度快, 有 VM 及 OTP 加持, 而且業界驗證過.
比起 Go, Scala 這些更年輕的語言, 光是 OTP 被 n 間公司驗證過 n 年就很值得信任了.
速度這個優點單純是依照比較的對象.
如果跟 ruby 比, 快 n 倍.
如果跟 Go 比, 也許就慢了點.
當然, 這裏沒有要比較, 因為比不完, 只是單純個人感想.

另一個優點是 compile 會自動報錯, 幫你 debug.
這對粗心的我非常有用, 我常常打錯字, 漏一個 ( 還啥的.

而 Elixir (Erlang) 最強大的莫過於 Concurrency & Fault Tolerance
學完 Elixir / Erlang & OTP 你就可以完全了解為何他會被如此推崇.
這部分直到目前還是很領先的.
不信的話可以 Google 什麼 Scala vs Erlang vs Go vs 叭啦叭啦
最好笑 & 經典的大概是這段話了 :

I’ve been using both Erlang and Scala for years. About the time to learn Erlang, it’s a big big mistake to say that Scala is easier to learn than Erlang. You can learn Erlang in just a day or two, but it takes you weeks or months to study Scala. Erlang is much much simpler. You can learn 90% of Erlang in a weekend just by reading and doing exercise from this site: Learn you some Erlang
Philosophically, Erlang will change the way you think about programming. Scala will hardly change you anything. My advice is you take courage to learn Erlang first, then Scala later. – from Is Erlang a good language choice for performance critical systems when compared to Scala and Go

社群也非常的熱心, 在 irc 上問問題通常都會有人馬上回答, 慢的話大概一小時內.
當然有時候是別人沒看到, 大部份的人在上面都很熱心的.
而且 lib 成長之快速令我驚訝, 幾乎我原本在 ruby 裡使用的 gem, elixir 都有類似的.
比如 (相同或類似名字的就不再重複)
rails -> phoenix
pusher
oauth
redis
beanstalkd
memcached
ssdb
postgres
httpi -> httpoison
json
erb -> eex

真的太多了…
可以去這裡看看 : Awesome Elixir Libs 或到 hex.pm 上查詢

缺點

語言本身缺點其實沒有, 要真的講, 大概就是每次 compile 要等.
尤其是開發 web, 改幾行 code 就要 compile 一次, 有點煩.
當然這是雙面刃, compile 可以 check error, 速度也快, 所以嚴格說來是沒有缺點的.

也許有人會說 Erlang 速度不像 Go & Scala 那麼好.
但我會說他的 Concurrency & Fault Tolerance 應該還是最好, 尤其當你把學習時間算進去時.
許多時候, availability, concurrency 遠比 performance 重要, 當 performance 是可以被接受的時候.
這也是我為何這麼喜歡 Riak 的原因.

如果不是語言本身, 那麼也許是台灣沒什麼人討論吧, 總有點孤單.

如果不擅長英文, 那麼也許有缺點, 就是學習資源會少些.
不過台灣雖然沒有甚麼人討論, 但對岸非常多資源.
看得懂 & 不介意簡體字的, 可以到對岸找找.

其他

這篇只是感想, 不是教學.
如果有人有興趣, 我再來打打以 ruby 角度的教學.
如果是一般傳統的教學, 去對岸或官網看就可以.
官網的 Getting Start 看完, 就幾乎可以掌握初步面貌了.
認真讀的話大概從中午開始看到半夜就可以讀完.

有興趣討論 or 一起學習的也可以 follow 我

原本不太打算寫這篇, 因為深感自己太嫩, 分享技術無觀眾, 不要誤人子弟, 不過想想還是寫了.

Elixir 是一個基於 Erlang VM 上的新語言.
Elixir 有許多優點包含 syntax, marco, DSL, 等等 以及來自 Erlang 的一切.

對於 rubiest 來說要上手 Elixir 應該頗快.
語法本身相似, 連 template engine 都很像.

不像的部分

簡略介紹幾個 ( 直接以 code 呈現 ) :

#ruby 
[0..10].times.each{|i| xxx }
# elixir
for i <- 0..10 do  
   xxx
end  

a=[1,2,3,4,5]  
#ruby
a.each{|i| xxx }  
#elixir 
Enum.map(a, fn(i)->  xxx  end)  

由上面可知, 基本差異就是 oo 跟 functional 的差別.
Elixir 本身沒有物件, 所以沒有辦法用 oo 的想法在那邊 . 來 . 去, 串接每個 function.
以下例來看, 在 ruby 裏寫很輕鬆, 在 elixir 就有點麻煩.

#ruby   
a={:dog=>{:bark=>"not bark yet"}}  
a[:dog][:bark]="bark bark"

#elixir
a=%{:dog=>{:bark=>"not bark yet",:walk=>{:speed=>10}}}  
a=Map.put(a,:dog, (Map.put(a[:dog], :bark, "bark bark")) )  

可想而知, 如果疊上去就很可怕.
當然也許會有其他解法, 但至少我目前還不知道, 所以我就自己寫了個 lib 可以用比較不噁心的方式出裡 :

a=Map.put(a, :dog, :bark, "bark bark")  
a=Map.put(a, :dog, :walk, :speed, 30)  

值得注意的是最上面的程式沒有提到, Elixir 中的變數都是區塊變數, 所以 fn 裡做任何事不會改變 fn 外的變數,
如果要強迫值改變, 則要透過回傳, 如下 :

a=[1,2,3]  
Enum.map(a, fn(i) -> i = i+1 end)  #=> [2,3,4]  
a #=> [1,2,3]

List.replace_at(a, 1, 10) #=> [1,10,3]  
a #=> [1,2,3]

a=List.replace_at(a, 1, 10) #=> [1,10,3]  
a #=> [1,10,3]

a=for i <- a do  
    i+1
end  #=>[2,11,4]

a #=> [2,11,4]  

另一個最大的差異應該是 patten match.
在 elixir ( erlang 也是 ) 裡, 幾乎所有東西都是 patten match.
舉例 :

{integer,_}=Integer.parse("1")
{:ok, value}=Some.function()

例子中可以看到我們 parse 整數, 然後回傳需要用 patten match, _ 代表忽略.
不過當 Integer 無法 parse, 會回傳 :error, 此時如果沒有任何 patten 去 match, 就會報錯.
所以完整的寫法應該類似 :

case Integer.parse("1") do  
    {integer,_} ->  do something
    :error -> do something
    _ -> do something for rest conditions
end  

其他不像的部分大概就是一些型別, 判斷式.
這部分就不贅述.

像的部分

簡略舉例 :

#ruby 
Module Dog  
    def bark do
       puts "bark"
    end
end  
#elixir 
defmodule Dog do  
    def bark do 
       IO.puts "bark"
    end
end

#ruby - console
$> irb
$> rake
$> rake 
$> rails new
$> gem install xxx
#elixir - console
$> iex
$> mix
$> mix phoenix.new
$> mix deps.get


#ruby - erb
<%=@hi%>  
<%if a==1 do%>  
    something here
<%end%>  
#elixir - eex
<%=@hi%>  
<%= if a==1 do %>  
    something here
<% end %>  

優點

優點當然就是速度快, 有 VM 及 OTP 加持, 而且業界驗證過.
比起 Go, Scala 這些更年輕的語言, 光是 OTP 被 n 間公司驗證過 n 年就很值得信任了.
速度這個優點單純是依照比較的對象.
如果跟 ruby 比, 快 n 倍.
如果跟 Go 比, 也許就慢了點.
當然, 這裏沒有要比較, 因為比不完, 只是單純個人感想.

另一個優點是 compile 會自動報錯, 幫你 debug.
這對粗心的我非常有用, 我常常打錯字, 漏一個 ( 還啥的.

而 Elixir (Erlang) 最強大的莫過於 Concurrency & Fault Tolerance
學完 Elixir / Erlang & OTP 你就可以完全了解為何他會被如此推崇.
這部分直到目前還是很領先的.
不信的話可以 Google 什麼 Scala vs Erlang vs Go vs 叭啦叭啦
最好笑 & 經典的大概是這段話了 :

I’ve been using both Erlang and Scala for years. About the time to learn Erlang, it’s a big big mistake to say that Scala is easier to learn than Erlang. You can learn Erlang in just a day or two, but it takes you weeks or months to study Scala. Erlang is much much simpler. You can learn 90% of Erlang in a weekend just by reading and doing exercise from this site: Learn you some Erlang
Philosophically, Erlang will change the way you think about programming. Scala will hardly change you anything. My advice is you take courage to learn Erlang first, then Scala later. – from Is Erlang a good language choice for performance critical systems when compared to Scala and Go

社群也非常的熱心, 在 irc 上問問題通常都會有人馬上回答, 慢的話大概一小時內.
當然有時候是別人沒看到, 大部份的人在上面都很熱心的.
而且 lib 成長之快速令我驚訝, 幾乎我原本在 ruby 裡使用的 gem, elixir 都有類似的.
比如 (相同或類似名字的就不再重複)
rails -> phoenix
pusher
oauth
redis
beanstalkd
memcached
ssdb
postgres
httpi -> httpoison
json
erb -> eex

真的太多了…
可以去這裡看看 : Awesome Elixir Libs 或到 hex.pm 上查詢

缺點

語言本身缺點其實沒有, 要真的講, 大概就是每次 compile 要等.
尤其是開發 web, 改幾行 code 就要 compile 一次, 有點煩.
當然這是雙面刃, compile 可以 check error, 速度也快, 所以嚴格說來是沒有缺點的.

也許有人會說 Erlang 速度不像 Go & Scala 那麼好.
但我會說他的 Concurrency & Fault Tolerance 應該還是最好, 尤其當你把學習時間算進去時.
許多時候, availability, concurrency 遠比 performance 重要, 當 performance 是可以被接受的時候.
這也是我為何這麼喜歡 Riak 的原因.

如果不是語言本身, 那麼也許是台灣沒什麼人討論吧, 總有點孤單.

如果不擅長英文, 那麼也許有缺點, 就是學習資源會少些.
不過台灣雖然沒有甚麼人討論, 但對岸非常多資源.
看得懂 & 不介意簡體字的, 可以到對岸找找.

其他

這篇只是感想, 不是教學.
如果有人有興趣, 我再來打打以 ruby 角度的教學.
如果是一般傳統的教學, 去對岸或官網看就可以.
官網的 Getting Start 看完, 就幾乎可以掌握初步面貌了.
認真讀的話大概從中午開始看到半夜就可以讀完.

有興趣討論 or 一起學習的也可以 follow 我