robot
最新文章(10)
這並不是一個創新
Tossug 2/9 SVG 加 XBL 分享
SVG and XBL No Widget
OpenSource 與嵌入式系統
Internet 的工人智慧
GCC Spec Files
Android Native code 的繪圖方法
Android Native code 不用 NDK
基於隱私的一種 DRM
Build Android SDK on FreeBSD
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (120)
Python (93)
FreeBSD (71)
WEB (61)
雜記 (48)
URL (48)
hardware (46)
javascript (36)
Linux (31)
blog (30)
所有關鍵字
新增 URL
Functional VS Imperative - 2006/11/17 update
by thinker
2 Columns
關鍵字:
雜記
coding
Python
「駭客與畫家」中文翻譯本出書後,引起許多的討論。在 sayya 的某個人板和某 ruby 板,也有許多對於 functional programming 的看法。許多人可以就 functional language 和 imperative language 提供的不同功能和 style,提出精細的看法。而我只將思考工具上的差異點出,分辨 functional 和 imperative 之間的差別。 == 比較 == 我們用 $Python$ implement binary search 為例,以 imperative programming 的 code 如下: {{{ def binary_search(target, values): i = 0 j = len(values) - 1 while(i < j): k = (i + j) / 2 if values[k] == target: return k elif values[k] > target: j = k - 1 else: i = k + 1 return None }}} 而 functional programming 就可能如下: {{{ def if_else(cond, t_stmt, f_stmt): return (cond() and t_stmt) or f_stmt def cmp(v1, v2, lt=-1, eq=0, gt=1): return if_else((lambda: v1 < v2), lt, if_else((lambda: v1 == v2), eq, gt)) def binary_search(target, values): mid = lambda i, j: (i + j) / 2 mvalue = lambda i, j: values[mid(i, j)] check_n_search = lambda i, j: cmp(i, j, search_part, search_part, (lambda i, j: None))(i, j) left = lambda i, j: check_n_search(i, mid(i, j) - 1) right = lambda i, j: check_n_search(mid(i, j) + 1, j) search_part = lambda i, j: cmp(target, mvalue(i, j), left, mid, right)(i, j) return search_part(0, len(values) - 1) }}} 這我們共不比較兩者程式碼的長度,因為和 $coding$ style、$keyword$ 有關,會隨著style 和語言而有差異。就兩者觀念相比較之後,functional programming 可將每個動作,依功能 (aspects or concerns)獨立切割的比較清楚,而 imperative programming 則容易將單一功能,分散在流程的各處,和其它功能混雜在一起。 == 邏輯集中、分散 == (2006/11/17 update) 程式撰寫時,最重要的是功能切割清楚。分割的目標,是將系統依其功能性做分離,降低模組間的偶合。但就 function 的層級來看,通常一個 function 的流程,會包含數個層面 (concern)。若不將不同層面的問題抽離獨立處理,將使的同功能程式碼,因結構上需求而重複出現。重複的結果,除了程式碼變長,閱讀時,大腦也需處理更多邏輯判斷。以一般 imperative programming 的風格而言,易如上例般,出現許多 if-else 。在功能較簡單的 function 裡,因為其範圍小,使用 imperative 甚至比 functional programming 易於了解。一旦 function 變的複雜,if-else block 的 size 變大,使各判斷式之間的距離加大,使邏輯分散而變的難以理解。這違反人類思考的方式。 通常我們對一件事的理解,是停留在某個層面和層級,以少數抽像的符號加以理解,漸次了解各層面和層級。但 imperative programming 的 style ,易使我們將不同層面和層級的問題,攪成一團長長的程式碼。這並不是 imperative language 無法做到如 functional programming,但其預設(暗示)的 style 卻易引導我們這麼做。 == 變數 == Imperative programming 需要透過變數傳遞資訊和控制流程。以 imperative binary search 為例,讀者必需透過追蹤 i、j 和 k 值,以了解程式的流程。而 functional style 的 code,變數的使用都在 local,不用穿越大量程式,追蹤變數內容變化。Functional programming 少了這些 side-effect,有效的降低或去除流程和變數交錯的複雜度。 {{{ boo = 0 for c in a_list: boo = boo / c + c ................ foo = .... ............... return boo * foo }}} 前面程式如果以 functional 的方式 $coding$ 就會如下: {{{ return reduce((lambda x, y: x / y + y), a_list) * foo() }}} Imperative programming 讓定用處和使用處分開,使的閱讀時,不時要回頭去看定義處。然而進行 functional programming 卻能選擇在使用處直接定義(in place),而非分開在不同地方。這行程式,直接告叫你,有一部分如結果就是加總 a_list 的內容。當然你可依需要而另外定義,使程式更流暢。然而,functional programming 的陳述方式更有彈性,更有機會明白表示程式碼的企圖。 == 控制 == Functional programming 將流程定義成抽象概念,使程式碼的讀者望文生義,快速的瀏灠程式的內容。Imperative programming 透過流程控制,完成抽象概念,並無法明確指出流程的抽象意涵。有些人可以透過切割成細小 function,而達成意涵的陳述。但因為沒有 first-class function,而無法達到更高階的抽象。Functional programming 透過傳遞 function 的方式,可將特定的控制結構抽象化,而成為抽象化概念。如果你能在 imperative language 裡做到 function 傳遞,某種層度上,你已經開始在做 functional programming。 下例就不是 imperative programming 的專長了: {{{ def count(data, is_interest): return if_else(lambda: is_interest(data[0]), 1, 0) + if_else(lambda: len(data) > 1, lambda: how_many_interest(data[1:], is_interest), lambda: 0)() count([1, 20, 19, 36, 77, 59], lambda x: (x % 2) == 1) }}} 簡單的計算符合條件的個數,functional programming 可以抽象化後重複使用。而 imperative programming 卻必需每次都 copy & paste 這段程式碼。 == 結語 == 有人會質疑 imperative language 也可做到這些 functional language 的功能,事實上也真的可以。有些 imperative 語言也可傳遞 function,而 OOL,像是 Java,也可以使用 function object。但是,當你做到這些時,你其實是在使用 imperative language 進行 functional programming。這沒什麼不可以,只是不是那麼的方便。 == REFERENCEs == * http://gnosis.cx/publish/tech_index_cp.html
最後更新時間: 2006-11-17 10:59:15 CST |
引用
查詢:
COMMENTS: