robot
最新文章(10)
Mqskit 和其它相關工具
CPython 的 GC 二、三事
寫 Mecurial Extension 是件快樂的事!
Mozilla 台灣辨公室徵人啟事
關於 Apple 的兩項專利
core dump 之前的 frame
怎麼發出 beep 聲?
先承認你要找的是奴才吧!
程式碼要清的多乾淨?
FreeBSD 的 Thread-Local Storage 實作
首頁
新編
最新留言
Entries RSS
重要關鍵字(10)
coding (122)
Python (93)
FreeBSD (71)
WEB (61)
URL (48)
hardware (46)
javascript (36)
Linux (34)
blog (30)
C++ (16)
所有關鍵字
新增 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: