- 论坛徽章:
- 2
|
本帖最后由 OwnWaterloo 于 2012-02-28 02:13 编辑
回复 24# 琳琳的小狗
先说我最关心的,OO与functional的混合。很多语言都没做好这东西。
许多OO语言是将data(instance)与function(method)绑在了一起。
你的答案其实已经将我的问题改了,我的问题是在n个集合上应用n元函数。
- [[0,1,2].zip([2,1,0]).map {|i| i.reduce(&:+)} # [2,2,2]
复制代码 map不是一个独立的函数,而是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 上使用二元函数, 而是再将先前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绑定,所以有些函数会少一个元。
atan 数学意义上是一个2元函数 —— 有两个集合 (a b) (x y), 通过map得到新集合 (list (atan a x) (atan b y))。
cons 数学意义上也是2元函数 —— 有两个集合 (a b) (xs ys), 通过map得到新集合 (list (cons a xs) (cons b ys))。
而许多OO语言, 比如ruby:
Math的类方法atan2 本意是一个2元函数, 调用时也需要传入2个参数。
如果类方法其实也是class object(我不知道ruby的术语怎么说), 也是会传入一个隐式参数的话,其实那个隐式参数没有被使用, 依然是2元函数。
Array的实例方法 push ,如果有两个集合 [ ["x0","x1"] , ["y0","y1"] ] 与 [0,1], 想构造一个新的集合 [ ["x0","x1",0] , ["y0","y1",1] ], 就会遇到问题。
[ F(["x0","x1"], 0) , F(["y0","y1"],1) ] —— 怎么表示那个F?
(这里修改了一下, 使用: x1 且中间没有空格会被认为是表情……)
如果不使用high order function,不将函数传入传出(函数传出在ruby里面依然有问题,稍后再说), object.method(arg)只是一个语法问题。
但如果想要传入一个F, 它可以 F(object,arg), 各种语言就会想出各种方法, C++里是mem_fun, python里面叫unbounded-method, js里面叫indirection call —— 于是将语言弄得很复杂。
而其目的只有一个 —— 将那个隐式的self/this,重新显式化。 那何不一开始就显式化?
lua就是这样做的, 没有隐式参数, 只有一个语法糖。
- local a = {0.0,-0.0}
- local b = {1,1}
- local c = map(math.atan2 , a , b) # map不是lua的标准库
复制代码 假设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的一个地方, 引入了许多繁琐的概念, 而且完全没必要。 |
|