還記得我們在新手村裡學會這幾句話嗎:
而隨著愈來愈多人寫程式,在歷史發展中,有些高手開始發現一些不太妙的事:
(下面這些話,要用電影旁白的語氣讀,配上遠遠的大風景慢鏡頭… 🌊 )
在那些古老的日子裡(半世紀前),程式是一大團不加以區分的程式碼及資料。控制的流可能自任意處開始,也可能在任何地方結束。不管在哪都可以隨便存取資料…
然而人們發現了一件難堪的事:「寫下的程式,不僅僅會被執行,也可能會被拿來修改。」而那些四處奔竄的控制流,自我修改的程式碼及被隨意存取的資料,執行起來還算美好,之後想修改時就相當駭人了。
於是人們踏上了那條漫長而曲折,尋找計算模型的道路,希望讓此處的修改,不至引起彼方非預料中的錯誤。
-- Kent Beck, Kent Beck 的實作模式
人們對於怎麼修改有各式各樣的意見,於是開始出現了幾種不一樣的程式世界觀,我們把這些不同的世界觀稱為範式 (paradigm)。
比較知名的有三派:
指令式編程(Imperative Programming):
這派認為程式應該就是對機器下命令,一步步告訴電腦要做什麼。
物件導向編程 (Object oriented Programming, OOP):
這派認為程式應該先定義資料的樣子,再把可以這樣動的邏輯綁在這種資料上。這樣就可以像現實世界一樣來設計程式,說「車子都能前進、剎車跟加油」,所以「汽車」、「巴士」跟「坦克」都能這樣做。
函數式編程 (Functional Programming, FP)
這派認為程式跟數學非常類似,可以像工廠的輸送帶,往一關關的機器(販賣機)運送那樣,每一步都把資料轉換成下一階段的樣子。因此可以用比較抽象的方式,來看待邏輯運作的方式。
而現代新的程式語言,常常是混合幾種不同的範式,依你的喜好來使用。
語言 | 物件導向 (OOP) | 函數式 (FP) | 指令式 (Imperative) | 主要範式 |
---|---|---|---|---|
Python | ⭐️⭐️ | ⭐️ | ⭐️⭐️⭐️ | 多範式,偏指令式 |
JavaScript | ⭐️ | ⭐️⭐️ | ⭐️⭐️ | 多範式,FP 特色愈來愈多 |
Elixir | 0️⃣ | ⭐️⭐️⭐️ | ⭐️ | 純函數式 |
Ruby | ⭐️⭐️⭐️ | ⭐️ | ⭐️⭐️ | 物件導向為主 |
Kotlin | ⭐️⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️ | 多範式,OOP+FP |
Swift | ⭐️⭐️ | ⭐️⭐️ | ⭐️⭐️ | 多範式,OOP+FP |
我們在線上玩具商店買了一些玩具,這個玩具商店有這些規則:
接著我們就用不同的範式及語言來示範這個購物車算錢的程式
def calc_total(items):
total = 0
for item in items:
if item['quantity'] > 2 or item['category'] == '布偶'
discount = 0.9
else
discount = 1.0
total += item['price'] * item['quantity'] * discount
return total * 0.8 if total > 1000 else total
# 使用範例
items = [
{'price': 100, 'quantity': 3, 'category': '玩具車'},
{'price': 200, 'quantity': 1, 'category': '布偶'},
]
print(calc_total(items)) # 270 + 180 = 450
class Item
def initialize(price, quantity, category)
@price, @quantity, @category = price, quantity, category
end
def subtotal
@price * @quantity * (@quantity > 2 || @category == '布偶' ? 0.9 : 1.0)
end
end
class Cart
def initialize(items) = @items = items
def total = (s = @items.sum(&:subtotal)) > 1000 ? s * 0.8 : s
end
# 使用範例
items = [
Item.new(100, 3, '玩具車'),
Item.new(200, 1, '布偶')
]
puts Cart.new(items).total # 450.0
defmodule Cart do
def total(items) do
items
|> Enum.map(&item_subtotal/1)
|> Enum.sum()
|> apply_bulk_discount()
end
defp item_subtotal(%{price: p, quantity: q, category: c}) do
p * q * item_discount(q, c)
end
defp item_discount(q, c) when q > 2 or c == "布偶", do: 0.9
defp item_discount(_, _), do: 1.0
defp apply_bulk_discount(subtotal) when subtotal > 1000, do: subtotal * 0.8
defp apply_bulk_discount(subtotal), do: subtotal
end
# 使用範例
items = [
%{price: 100, quantity: 3, category: "玩具車"},
%{price: 200, quantity: 1, category: "布偶"}
]
IO.puts Cart.total(items) # 450.0
對於程式初學者,還是建議在 Python 跟 JavaScript 中選一個來開始,畢竟 AI 最熟悉的程式語言就是這兩種。但是在已經習慣怎麼寫出軟體功能後,會建議偶爾學習一下其它範式的程式語言。這樣可以用更寬廣的眼界思考事物,讓你的能力與觀點進化到更高的層次。