Skip to content

第 N 次學習 Functional Programming Language 就上手。

不論是上古神獸 Lisp,Haskell,或是現代一點的 Scala,如果你跟我一樣嘗試過學習 Functional Programming Language,但是都沒有成功,那麼 Elixir 是你最好的選擇。

Pipe Operation - 括號終結者

我朋友 ypcat 推我入 Elixir 的坑的時候,舉出了一個 Elixir 的優點,那就是 Elixir 的語法很簡單,很像 Ruby,所以學習起來很容易,最重要的是可讀性很高,沒有一堆括號()。

比如說我們要把字串的前後空白去掉,再轉成大寫,然後把 WORLD 換成 Gary,如果用 Python 寫的話,會是這樣:

astr = " Hello world! "
astr.strip().upper().replace("WORLD", "Gary")

這邊可以看到由於 Python 支援 object ,所以字串有 strip, upper, replace 這些 method 可以用,而且這些 method 都會回傳一個新的字串,所以可以一直串起來用。

再來看一下 Elixir 的寫法:

astr = " Hello world! "
String.trim(String.replace(String.upcase(astr), "WORLD", "Gary"))

巢狀的括號看起來是不是很難懂? 這時候就可以用到 Pipe Operation 來改寫:

astr = " Hello world! "
astr |> String.trim() |> String.upcase() |> String.replace("WORLD", "Gary")

背後的原則是,我們可以把這樣的 expression g(f(x)) 改寫成 x |> f() | > g() ,這樣看起來是不是清爽多了?

Thinking Elixir 入門課程

初次學習 Elixir 的朋友, 推薦從這邊開始,有兩堂入門的課程: ThinkingElixir

如果你還沒有 Elixir 的環境,建議可以從 Livebook 開始,Livebook 是一個可以在瀏覽器上執行 Elixir 程式的環境,可以很快的上手 Elixir 的語法。

Elixir 的資料結構

先來比較一下 python 跟 Elixir 的資料結構,特別注意 Elixir 是 functional programming language,所以資料結構都是 immutable 的, 而且沒有 object method,不管是 List 或是 Map 存取都是用 function。

List

Elixir 的 List 跟 Python 的 List 很像,但是同樣的 Elixir 的 List 是 immutable 的,如果修改 List 內的值,會得到新的 List 。 另外 Elixir 的 List 不像是 Array,不能直接存取第 n 個元素。一般 List 的用途是要搭配Pattern,例如 [head | tail] ,之後再說明。

Tuple

Python 的 Tuple 跟 Elixir 的 Tuple 很像,但是 Elixir 的 Tuple 是 immutable 的。

# Python
data = (1, 2, "GO") # Python
data[0] # 1
data[2] # "GO"

# Elixir
data = {1, 2, "GO"}
elem(data, 0) # 1
elem(data, 2) # "GO"
put_elem(t, 2, "foo") # 修改第二個值會傳回一個新的 tuple {1, 2, "foo"}

Map

Elixir 的 Map 跟 Python 的 Dictionary 很像,但是同樣的 Elixir 的 Map 是 immutable 的,如果修改 Map 內的值,會得到新的 Map 。

Python: Dictionary

data = { "name" : "gary" , "age": 99 }

Elixir: Map

產生 Map

data = %{ name: "gary", age: 99, city: "Tokyo" }

注意這裡的 name 是一個 atom (:name)

讀取 Map

data[:name]

寫入 Map

Map.put(data, :name, "bob")

更新 Map

%{data | age: 31, city: "Taipei"}