まつもと ゆきひろです In message "[ruby-list:6073] Re: Ruby連載 第3回" on 98/01/28, hisanori / sitc.toshiba.co.jp <hisanori / sitc.toshiba.co.jp> writes: |松尾です。 |> もちろんRubyではこういうことはしようと思ってもできないわけですが、 イテレー |> タを使うのに比べて面倒ですね。これは、 | |この辺を読んで、でも、それなら、と疑問を持ってしまいました。Rubyでは出 |来ない、のならなんで出来るようにしなかったんだろう、ということです。 | |別にイテレータなんて(僕には)あまり馴染みの無い概念より、関数には関数 |(或いは関数ポインタ?、関数の参照?、ラムダ関数?、無名関数?、引数の取れ |るブロック?)も引数として渡せますよ、という考え方及び実装の方が理解しや |すいと思うのですが如何でしょう。 まず,Rubyに関数ポインタがないのはSmalltalk的とでもいうよう な古典的オブジェクト指向モデルを採用しているからです.この辺 は関数ポインタをベースにしているオブジェクト指向モデルの Pythonとは大きく違うところです.どっちが良いかと言うのは主観 ですが. そういうモデルなので,単純には「関数ポインタを渡せば良いや」 で済まなかったのが,第1の理由です.なんらかの方法で関数ポイ ンタに当たるものを生成できないといけないわけです. で,Smalltalkでは「ブロックオブジェクトを引数にする」という 方法を選び,Rubyでは「イテレータブロックを暗黙の引数にする」 という方法を選んだわけです. では,なぜブロックを直接の引数にする方法を選ばず,イテレータ ブロックを選んだかというと * forが実装しやすい とっつきやすさのためfor文が欲しかったのですが,ブロック を渡すというセマンティックスではちょっと意味的に??な部 分が出て来ます. * この仕様を設計した時点では「制御構造を実装する手段」とし てイテレータを考えていて,その目的のためにはブロックを引 数にとるような foo(arg, lambda{ ... }) よりも,イテレータブロックを暗黙の引数として渡す foo(arg) { ... } の方が表現したいものを直接表現している気がした. # この「表現したいものを直接表現する」という点はRubyの言語 # 仕様でわりと重視されています.いろんなしがらみでうまくいっ # てない部分もあるみたいですけど. * 昔Actorという言語があってそれなりに影響を受けたのですが, その言語ではブロックを明示的な引数として渡すという仕様だっ たのですが,ブロック生成の括弧 { } と引数の括弧 ( ) が混 在して結構美しくない印象があった.SmalltalkやLispならと もかく,「通常」言語風の外見を持つ言語と明示的なブロック 引数は似合わない気がした(完全に個人的な意見ですが). たとえば,Array#sortの場合 ary.sort{|a,b| a<=>b} の方が ary.sort(lambda{|a,b| a<=>b}) よりもストレートで良いと思いました. その後,lambda{}(あるいはProc.new{})を使ってクロージャを生成 できるようになったので,やりたければ引数としてクロージャを渡 せるし,それ以上いろいろする気がなかったというのも正直なとこ ろです. まつもと ゆきひろ /:|)