- 論壇徽章:
- 2
|
本帖最后由 OwnWaterloo 于 2012-02-28 02:13 編輯
回復 24# 琳琳的小狗
先說我最關(guān)心的,OO與functional的混合。很多語言都沒做好這東西。
許多OO語言是將data(instance)與function(method)綁在了一起。
你的答案其實已經(jīng)將我的問題改了,我的問題是在n個集合上應用n元函數(shù)。
- [[0,1,2].zip([2,1,0]).map {|i| i.reduce(&:+)} # [2,2,2]
復制代碼 map不是一個獨立的函數(shù),而是Array的一個instance method,于是只能先將 [0,1,2], [2,1,0] zip 為一個Array, 然后在此Array上map。
注意此處zip依然只是一個instance method, 比較: (zip '(0 1 2) '(2 1 0)) => ( (0 2) (1 1) (2 0) )。
之后顯然也不是直接在 0 2, 1 1, 2 0 上使用二元函數(shù), 而是再將先前zip得到的 (0 2) (1 1) (2 0) reduce 到一個值。
- [0, 1, 2].zip([[:a, :b], [:c, :d], [:e, :f]]).map(&:flatten) #[[0, :a, :b], [1, :c, :d], [2, :e, :f]]
復制代碼 依然是先zip得到 [0,[:a,:b]], 然后在這個集合上flatten。而不是將0直接加入[:a,:b]。
而且被修改的問題不僅如此, 還包括flatten。 我本意是想問push。
對比:
- (map atan '(0.0 -0.0) '(1 1)) ; => (0.0 -0.0)
- [0.0,-0.0].zip([1,1]).map(&Math.method(:atan2)) # => [0.0, -0.0]
復制代碼 后面那行ruby代碼我都不知道該怎么解釋……
但至少暴露出了一個問題,Ruby沒有first class function,必須用一個Method作為包裝,然后call。這問題暫且放下。
functional與OO的一個矛盾的地方是,因為OO將method與object綁定,所以有些函數(shù)會少一個元。
atan 數(shù)學意義上是一個2元函數(shù) —— 有兩個集合 (a b) (x y), 通過map得到新集合 (list (atan a x) (atan b y))。
cons 數(shù)學意義上也是2元函數(shù) —— 有兩個集合 (a b) (xs ys), 通過map得到新集合 (list (cons a xs) (cons b ys))。
而許多OO語言, 比如ruby:
Math的類方法atan2 本意是一個2元函數(shù), 調(diào)用時也需要傳入2個參數(shù)。
如果類方法其實也是class object(我不知道ruby的術(shù)語怎么說), 也是會傳入一個隱式參數(shù)的話,其實那個隱式參數(shù)沒有被使用, 依然是2元函數(shù)。
Array的實例方法 push ,如果有兩個集合 [ ["x0","x1"] , ["y0","y1"] ] 與 [0,1], 想構(gòu)造一個新的集合 [ ["x0","x1",0] , ["y0","y1",1] ], 就會遇到問題。
[ F(["x0","x1"], 0) , F(["y0","y1"],1) ] —— 怎么表示那個F?
(這里修改了一下, 使用: x1 且中間沒有空格會被認為是表情……)
如果不使用high order function,不將函數(shù)傳入傳出(函數(shù)傳出在ruby里面依然有問題,稍后再說), object.method(arg)只是一個語法問題。
但如果想要傳入一個F, 它可以 F(object,arg), 各種語言就會想出各種方法, C++里是mem_fun, python里面叫unbounded-method, js里面叫indirection call —— 于是將語言弄得很復雜。
而其目的只有一個 —— 將那個隱式的self/this,重新顯式化。 那何不一開始就顯式化?
lua就是這樣做的, 沒有隱式參數(shù), 只有一個語法糖。
- local a = {0.0,-0.0}
- local b = {1,1}
- local c = map(math.atan2 , a , b) # map不是lua的標準庫
復制代碼 假設(shè)lua有一個Array庫,就可以:
- local xs = Array{1}
- Array.push(xs,2) --> 或者
- xs.push(xs,3) --> assert(Array.push == xs.push)
- xs:push(4) --> 使用 : 語法糖, 與上面一行相同
- map(Array.push,{ {"a"}, {"b"}, {"c"},{"d"} },xs) --> 就不需要有unbounded/bounded之分。
復制代碼 如果是非OO的functional語言,就只有data與function(甚至只有function)。
而一旦加入OO,事情就會非常復雜,class/prototype/instance,unbounded/bounded-method, normal/method/indirection/construction call……
這是我反感OO的一個地方, 引入了許多繁瑣的概念, 而且完全沒必要。 |
|