http://www.igda.jp/modules/xeblog/?action_xeblog_details=1&blog_id=505
を見てて思い出したので書く。
Python のすばらしいものの一つとして generator があるとおもう。
中略。
で、たとえば、
pos_ary = ary.select do |x| x > 0 end
とかで正の数だけ抽出する時と
pos_sum = ary.select do |x| x > 0 end.inject do |r, v| r + v end
正の数だけ summation する時で、前者は Array が帰ってきて後者は generator チックに動作する Enumerable が自動的に選択されたらステキだなぁと。
もっと言うとこう select と inject が別スレッドで走ってくれたらそれは嬉しいなぁと。っていうか Erlang とかが微妙に流行ってるのとか Alef とか Limbo とかのチャンネルってこういう意味での並列だよねと。 CPU でいうところのパイプライン並列化というか。
で CPU でいうところのもう一個の並列化だけど、
ary.each do |x| f(x) end
みたいなループで(fに副作用が無い時)並列化させる、ってのはこう、 ary が少ない時はいらんし、ものすごい多い時は別マシンで走らせればいいじゃんって気がする。 ary が適度に大きい時、ってのは私はマルチメディア処理くらいしか思いつかないのだけど、まぁそれはマルチコアじゃなくて SIMD とかでやればいいじゃんって気がする。
でも select と inject が別スレッドで走るのはまぁ普通に嬉しいと思っていて、ループの中で a って変換と b って変換と c って変換をしたい時に、
ary.map do |x| x = a(x) x = b(x) x = c(x) end
とか書いてたとして、単一 CPU だと a と b と c を微妙に展開して a の計算途中のデータを b でも使ったりすると速くなったりとかするケースが結構あって、そいうことすると効率とコードの綺麗さが敵対関係になっちゃったりする。でも、
ary.map(:a).map(:b).map(:c)
って書くと (Symbol#to_proc あればこう書けるんだっけ) 3 つの map が適当に別スレッドで動いてくれる、っていうなら当然みんな a と b と c を分けて書くわけで、効率と綺麗さが仲良くできていいよなぁと。
あとなんか ary.map(:a) はこう、最初はなんかよくわからん Enumerator が帰ってて、時が満ちるか Array としての動作が必要になると Array になる(Array としての動作が必要になった場合は map の終了を待つ)、とかだと面白いよなぁと。
メッセージベースのオブジェクト指向言語ってこう、レシーバがなんだろうとインターフェイスさえ正しけりゃ問題ないわけで、いったんなんかのクラスだったオブジェクトが突然別クラスのオブジェクトに変わってくれたりしてもまぁ問題ないんじゃないかなぁ、って思う。
このあたり Io の Concurrency が面白かったと思うのでまた今度。
なんかよくわからんのでまとめると、まとめる気が起きない。
近況はイルブリードが面白い。と言ってもニコニコで見てるだけだけど。