作者contagious (布谷饱吃不堡)
看板Ruby
标题Re: [心得] functional programming
时间Sun Sep 23 01:26:38 2007
後者的扩充版本不用写得这麽可怕吧?用到 metaprogramming 太夸张了
def combine *args
result = []
args.first.size.times do |i|
tmp = 0
args.size.times do |j|
tmp += args[j][i]
end
result << tmp
end
result
end
不过这样的易读性就没有原来没扩充之前高了
BTW 一行的版本可以写成这样
def *args
args.transpose.map.inject(&:+)
end
transpose 是个超有用的 method,很多原本该用 index 或是 Generator 的东西
用了 transpose 就可以轻易的转成 interator 就解决了
回归正题
这里提出的两种方式,一种是使用传统的 Array index ,另一种是 Ruby 的 inner
iterator(也是原 po 说的 functional programming 的方式)
基本上, Array index 的方式效率较高且比较具有扩充性的,而 inner iterator 则
易於理解的。(刚好和原 po 的看法相反?)
用 Array index 的话,随便你要取哪个元素来运算都行,所以基本上扩充性是无限制
的,而用 inner iterator 的话,就有不能平行走过两个阵列这种限制。而且通常用
Array index 的效率会比较好,比如说文中的例子,使用 inner iterator 的那个版
本,要先产生一个 n*m 的新阵列,如果资料量大的时候并不是一个可以接受的作法。
而所谓 inner iterator 易於理解,并不是指每一个人都比较看得懂这种写法,而是指
它的逻辑比较明显。通常看不懂这种写法的,并不是不了解程式的逻辑,而是语法不熟
。这就好像说我们熟悉中文的人,因为英文不好所以觉得用英文写的论文比较难懂。
其实英文这个语文并没有错,甚至英文在逻辑和精确度上都比中文来得好,只是我们不
习惯罢了。
※ 引述《godfat (godfat 真常)》之铭言:
: p 币用完了,来试着赚一点...
: 已经是我第二次用上了这种作法:
: def combine left, right; left.zip(right).map{ |e| e.inject &:+ }; end
: 不过我不禁在想,这样到底是增进了可读性与扩充弹性,
: 抑或是减少可读性与扩充弹性?
: 同样的意思,我想最直接的作法会是:
: def combine left, right
: result = []
: left.size.times{ |i|
: result << left[i] + right[i]
: }
: result
: end
: 相信就算最上面那个看不懂,这个应该是一眼就看得出来了。
: 不过,zip, map, inject (fold), 这些 function 在 functional programming
: 根本就是家常便饭,如果跟 fp 熟一点,我想应该是一眼就能看出是什麽意思(吧?)
: 那麽究竟怎麽写比较好?相信 java programmer 肯定会说下者 XD
: 可是对我来说,两者的畅快感可不能相提并论啊 :p
: 如果说 combine 要扩充更多的 input, 上者很容易,就这样:
: def combine *args; args.shift.zip(*args).map{ |e| e.inject &:+ }; end
: 没改几个字。因为 zip, inject 等操作本身就是模组化的。
: 可是如果要下者扩充的话,我不是很清楚,但第一个想到的是 meta-programming:
: def combine *args
: result = []
: args.first.size.times{ |i|
: values = []
: args.size.times{ |j|
: values << "args[#{j}][i]"
: }
: result << eval(values.join('+'))
: }
: result
: end
: 只是这样做真的有点蠢,而且效能照理说也不会很理想(没测过,有人想测吗?)
: 而且我觉得这样复杂度反而比 zip + map + inject 高很多,
: 像是上面的 args.first.size.times 中的 first 我就差点漏写了。
: any idea?
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.126.48.124
1F:推 godfat:不过这应该不是语法问题 :p 09/23 01:39
2F:→ godfat:我提到效率不好是指 meta-programming 的部份 09/23 01:40
3F:推 LyinZ:用了 ruby.. 就是决定不考虑效率了 A_A 09/23 11:12
4F:→ zusocfc:哈哈.. 用Ruby要是不考虑效率.. 那还真的很惨= = 10/03 07:35