Rubyの特異メソッドとCLOSのeql specializer ― 2007年01月13日 00時43分29秒
ASAHIネット(http://www.asahi-net.or.jp)のjouwa/salonからホットコーナー(http://www.asahi-net.or.jp/~ki4s-nkmr/ )に転載したものから。
---
http://blog.livedoor.jp/dankogai/archives/50689356.html
オブジェクトは難しくない。難しいのはクラス
で話題にしてあるRubyの特異メソッドは、Common LispのCLOS(Common Lisp
Object System, クロスやシーロスと読む) では、defmethodのeql specializerで実現できる。
というか、Common Lispのeql specilizerをRubyで実装したのが、特異メソ
ッドだと思う。
CLOSのeql specializerの例を
http://www.asahi-net.or.jp/~ki4s-nkmr/singleton-method/singleton-method.lisp
に置いたので、みてください。
defmethodの説明は、
http://www.lispworks.com/documentation/HyperSpec/Front/index.htm
Common Lisp HyperSpec
の
http://www.lispworks.com/documentation/HyperSpec/Body/m_defmet.htm
defmethod
をどうぞ。その説明にあるeql-specializer-formが、Rubyでいう特異メソッド
です。
先に進む前にちょっと疑問。上記で参照されている
http://blog.livedoor.jp/dankogai/archives/50666398.html
perl - Object::PrototypeでPOMを実装
のドンペンの例は、特異メソッドの例になってるの? 単にメソッドのオーバ
ーライドの例にしかみえないんだけど。
では、先に進むが、以下、Lispと書いたらCommon Lispのことと思ってくだ
さい。Lispの2大標準のもう一方であるSchemeは、この場合、含まれないので。
CLOSの場合、他のオブジェクト指向言語と大いに違うのは、メソッドはクラ
スに縛られていないこと。クラスには属していないのだ。
これが、オプジェクト指向といえば、クラスにメソッドが属するものだと思
い込んでいる人には、驚きだろう。CLOSは、クラスにメソッドが属しているオ
ブジェクト指向の一般化になっているのである。
昔、電脳騒乱節で、ヒューイット先生のアクターモデルを知ると、
Smalltalk(そしてほとんどのオブジェクト指向言語)の継承は、メッセージを
誰が処理するかを、クラスの先祖をたどる方向に固定したものなのがわかるな
んてことを書いた記憶がある。
弾さんがいうように、
Too Many Ways to Implement Object Systems
は、その通り。
だから、あんまり思考に枠をはめずに考えるほうがいい。
果たしてそんな頭をほぐすのに役立つかどうかわからないが、簡単にCLOSの
モデルを説明してみよう。
CLOSでは、メソッドはクラスに属していないと書いた。
だから、Lispでは、クラスがなくてもメソッドは定義できるし、メソッドに
クラスのインスタンスではなく、通常のLispオブジェクトを渡して処理するこ
ともできる。
逆に、通常の関数でクラスのインスタンスを受け取って処理することもでき
る。
メソッドの呼び出しと通常の関数の呼び出しは構文上も区別がつかない。
CLOSは、非常にシームレスに従来のLisp上に作られていることがわかる。
したがって、
Perl5最大の欠点:Object Systemが後付けなこと。
Perl5最大の利点:Object Systemが後付けなこと。
というのは、Lispも同じ。ただ、それがマクロで作られているところがLispの
すごさ。そして、標準化されているところがPerlとの大きな違い。
さて、メソッドは、何に属しているかというと、総称関数(generic
function)と呼ばれるものに属している。
そして、いつ、メソッドがクラスと結びつくかといえば、実行時に動的に結
びつく。
パラメータとしてメソッドに渡されたオブジェクトをみて、一番ふさわしい
メソッドが呼ばれる。
当然、パラメータは複数でもよく、それら全部を調べて、最適なメソッドを
選んで実行する。
1個のパラメータだけで選ぶと、Smalltalk, Java, Rubyなんでもいいけど、
よくあるオブジェクト指向言語の、レシーバになる1つのオブジェクトにメッ
セージを投げるメッセージ伝達型のオブジェクト指向になる。
つまり、CLOSは、通常のオブジェクト指向言語より一般化されたメカニズム
で動いているわけだ。
Lisp屋は一般化が好きで、徹底的にやりたがる連中が多いが、それが出た感
じ。数学でいえば、n = 1の場合だけじゃなくて、n = 2, 3や、n が無限大で
どうなるかを考えるような感じ。
先の弾さんのブログだと、Rubyの特異メソッドが絶賛されているそうだが、
個人的には、Lispの世界で、eql specializerを使った特異メソッドがそんな
にうれしいかといえば、あまりうれしい気がしない。
何度もいうようだが、CLOSだとメソッドはクラスに縛られていないし、通常
の関数はクラスのインスタンスを受け付けるし、特異メソッドがなければない
で、実務的には通常の関数で処理して大して困らないと思う。
逆にいえば、Smalltalk, Java, Rubyなど他のオブジェクト指向言語みたい
に、メソッドがクラスに縛られている言語では、特定のインスタンスに作用す
る特異メソッドのような一種の抜け道が必要で、そこがありがたがられるので
はないかと思う。
でも、Lisp屋にいわせれば、そんなところで苦肉の策を弄さないといけない
言語設計が腐っているというかもね。\(^O^)/
実際、Common Lispの解説でCLOSの解説の部分でも、eql spepcializerにつ
いては、触れられていないか、軽い扱いだから、そんなに重要視されてないの
ではないか。
おれは仕事でLispを使ってないし、Lisp屋とはいえないけど、Lisp屋も同じ
思いじゃないか。
おれなんか、eql specializerがあるなんて、すっかり忘れていた。
だから、Rubyの特異メソッドが絶賛されていると聞いて、一体、なぜ、絶賛
するんだろうと、かえって考えてしまって、いま、これを書いているわけ。勉
強になったし、初めて、eql-specializerを使った例まで書いちゃって、これ
でおれもいっぱしのLisp屋かな(爆)。
おれの場合、初めてCLOSを見たとき、「よーやるわ、こいつら」と思ったの
は、メソッドがクラスに縛られないこと、マルチメソッドによるディスパッチ、
メソッド結合によるメソッドの修飾などのアイデアの数々だった。
たしかに、通常の関数だと、eql specializerの例で示したように、誤って
do-foo-singletonにfoo-normalを渡してもエラーにならないけど、そんなとこ
ろで間違って渡すようだと、プロのプログラマとしてやってけないと思うけど
ね。
あ、そう。じゃ、お前、クビだね。\(^O^)/
CLOSは何でもできると思っていたが、個人的にはそんなにありがたい気がし
ないし、滅多に使われないであろうeql specializerによる特異メソッドもあ
ったのには、ちょっと驚いた。
Lisp屋が、Flavorsなど、CLOSの前身になるようなオブジェクト指向のシス
テムをLisp上に作り始めたが1970年代の後半から1980年代だと思うが、いろい
ろ実験して、CLOSの仕様が定まって、正式にANSI Common Lispに入ったのが、
1994年だったはずだから、今回改めて、CLOSの先進性を感じた次第。
CLOSがANSI Common Lispに入っているということは、ANSI準拠のCommon
Lisp処理系ならCLOSが使えるということ。だから、Lispではオブジェクト指向
もできる。
CLOSだけでもフツーは十分だろうが、さらに加えて、CLOSの挙動を自在に再
定義するMOP(Meta Object Protocol, モップと読む)もある。この辺が、いろ
んなことが変幻自在になってないと気がすまないいかにもLisp屋の発想だなと
思う。
こっちは、まだ公式には標準化されてないけれど、事実上の標準としてAMOP
(A Meta Object Protocol)があって、いまのCLOSの実装は、大体、これに準拠
しているそうだから、かなり互換性はあると思う。
Common Lispの入門情報やCLOSの入門情報をまとめたものは、別の機会にし
ます。
余談だが、
http://www.amazon.co.jp/exec/obidos/ASIN/4894714337/showshotcorne-22/ref=nosim
ポールグレアム著, 久野雅樹, 須賀哲夫訳「ANSI Common Lisp」
では、Smalltalk的というかJava的というかRuby的というか、他のオプジェク
ト指向言語的というか、クラスにメソッドが属して、かつ単純継承のオブジェ
クト指向システムの基本部分を、従来のCommon Lisp(つまり、CLOSではない伝
統的な部分だけ)を使って、たったの8行で作っている。
なぜ、そんなトリックができるのか。それはLispがそれだけのものをすでに
備えていて、8行でやったのは、その外観を加えただけなのだという話。
この8行でやったことを効率化していくと、85行くらいになっている。
http://www.paulgraham.com/lispcode.html
の
http://lib.store.yahoo.net/lib/paulgraham/acl2.lisp
ANSI Common Lisp Code
; *** ob ***
の行からが、それ。
同じ著者で、中級上級者用の
http://www.amazon.co.jp/exec/obidos/ASIN/0130305529/showshotcorne-22/ref=nosim
Paul Graham著「On Lisp」(Prentice Hall)
のほうにも、形を変えてこの話が出てくるが、それは自分で探してください。
Paul Grahamのウェブサイトでは、電子版を無料で配っている。
http://www.paulgraham.com/onlisp.html
Paul Graham著「On Lisp」(Prentice Hall)
をどうぞ。
そして、この翻訳版を野田開さんが、高校生のころから翻訳をはじめて、逐
次ウェブ・サイトで配っていたのが、
http://user.ecc.u-tokyo.ac.jp/~t50473/
野田 開のウェブ・サイト
にある。
何度も書くが、翻訳本が出る出るといわれて、いまだ出ず。どうなっておる
のだ。
野田さん、高校でLisp知ってたんだもんね。すごいね。
東大行かずに世界で最初?にCommon Lispの実装を公開したKyoto Common
Lisp(いまのGNU Common Lispの元)の京大数理解析研究所に行けばよかったの
に。\(^O^)/
あ、高校生からいきなり京大数理解析研究所は入学できないか。\(^O^)/
一度、Franz社の小俣さんが野田さんを連れてきてくれたときがあって、一
緒に昼飯食いましたが、野田さん、一流物理学者になるのが夢というんだから、
いいよなあ。
おれなんか物理学者になれないから、いまは、国際宇宙ステーションまで歩
いて上るのが夢だってんだからね。\(^O^)/
おい、違うだろ、それは。
あ、そうだった。国際宇宙ステーションまで、自転車で行くのが夢。\(^O^)/
---
http://blog.livedoor.jp/dankogai/archives/50689356.html
オブジェクトは難しくない。難しいのはクラス
で話題にしてあるRubyの特異メソッドは、Common LispのCLOS(Common Lisp
Object System, クロスやシーロスと読む) では、defmethodのeql specializerで実現できる。
というか、Common Lispのeql specilizerをRubyで実装したのが、特異メソ
ッドだと思う。
CLOSのeql specializerの例を
http://www.asahi-net.or.jp/~ki4s-nkmr/singleton-method/singleton-method.lisp
に置いたので、みてください。
defmethodの説明は、
http://www.lispworks.com/documentation/HyperSpec/Front/index.htm
Common Lisp HyperSpec
の
http://www.lispworks.com/documentation/HyperSpec/Body/m_defmet.htm
defmethod
をどうぞ。その説明にあるeql-specializer-formが、Rubyでいう特異メソッド
です。
先に進む前にちょっと疑問。上記で参照されている
http://blog.livedoor.jp/dankogai/archives/50666398.html
perl - Object::PrototypeでPOMを実装
のドンペンの例は、特異メソッドの例になってるの? 単にメソッドのオーバ
ーライドの例にしかみえないんだけど。
では、先に進むが、以下、Lispと書いたらCommon Lispのことと思ってくだ
さい。Lispの2大標準のもう一方であるSchemeは、この場合、含まれないので。
CLOSの場合、他のオブジェクト指向言語と大いに違うのは、メソッドはクラ
スに縛られていないこと。クラスには属していないのだ。
これが、オプジェクト指向といえば、クラスにメソッドが属するものだと思
い込んでいる人には、驚きだろう。CLOSは、クラスにメソッドが属しているオ
ブジェクト指向の一般化になっているのである。
昔、電脳騒乱節で、ヒューイット先生のアクターモデルを知ると、
Smalltalk(そしてほとんどのオブジェクト指向言語)の継承は、メッセージを
誰が処理するかを、クラスの先祖をたどる方向に固定したものなのがわかるな
んてことを書いた記憶がある。
弾さんがいうように、
Too Many Ways to Implement Object Systems
は、その通り。
だから、あんまり思考に枠をはめずに考えるほうがいい。
果たしてそんな頭をほぐすのに役立つかどうかわからないが、簡単にCLOSの
モデルを説明してみよう。
CLOSでは、メソッドはクラスに属していないと書いた。
だから、Lispでは、クラスがなくてもメソッドは定義できるし、メソッドに
クラスのインスタンスではなく、通常のLispオブジェクトを渡して処理するこ
ともできる。
逆に、通常の関数でクラスのインスタンスを受け取って処理することもでき
る。
メソッドの呼び出しと通常の関数の呼び出しは構文上も区別がつかない。
CLOSは、非常にシームレスに従来のLisp上に作られていることがわかる。
したがって、
Perl5最大の欠点:Object Systemが後付けなこと。
Perl5最大の利点:Object Systemが後付けなこと。
というのは、Lispも同じ。ただ、それがマクロで作られているところがLispの
すごさ。そして、標準化されているところがPerlとの大きな違い。
さて、メソッドは、何に属しているかというと、総称関数(generic
function)と呼ばれるものに属している。
そして、いつ、メソッドがクラスと結びつくかといえば、実行時に動的に結
びつく。
パラメータとしてメソッドに渡されたオブジェクトをみて、一番ふさわしい
メソッドが呼ばれる。
当然、パラメータは複数でもよく、それら全部を調べて、最適なメソッドを
選んで実行する。
1個のパラメータだけで選ぶと、Smalltalk, Java, Rubyなんでもいいけど、
よくあるオブジェクト指向言語の、レシーバになる1つのオブジェクトにメッ
セージを投げるメッセージ伝達型のオブジェクト指向になる。
つまり、CLOSは、通常のオブジェクト指向言語より一般化されたメカニズム
で動いているわけだ。
Lisp屋は一般化が好きで、徹底的にやりたがる連中が多いが、それが出た感
じ。数学でいえば、n = 1の場合だけじゃなくて、n = 2, 3や、n が無限大で
どうなるかを考えるような感じ。
先の弾さんのブログだと、Rubyの特異メソッドが絶賛されているそうだが、
個人的には、Lispの世界で、eql specializerを使った特異メソッドがそんな
にうれしいかといえば、あまりうれしい気がしない。
何度もいうようだが、CLOSだとメソッドはクラスに縛られていないし、通常
の関数はクラスのインスタンスを受け付けるし、特異メソッドがなければない
で、実務的には通常の関数で処理して大して困らないと思う。
逆にいえば、Smalltalk, Java, Rubyなど他のオブジェクト指向言語みたい
に、メソッドがクラスに縛られている言語では、特定のインスタンスに作用す
る特異メソッドのような一種の抜け道が必要で、そこがありがたがられるので
はないかと思う。
でも、Lisp屋にいわせれば、そんなところで苦肉の策を弄さないといけない
言語設計が腐っているというかもね。\(^O^)/
実際、Common Lispの解説でCLOSの解説の部分でも、eql spepcializerにつ
いては、触れられていないか、軽い扱いだから、そんなに重要視されてないの
ではないか。
おれは仕事でLispを使ってないし、Lisp屋とはいえないけど、Lisp屋も同じ
思いじゃないか。
おれなんか、eql specializerがあるなんて、すっかり忘れていた。
だから、Rubyの特異メソッドが絶賛されていると聞いて、一体、なぜ、絶賛
するんだろうと、かえって考えてしまって、いま、これを書いているわけ。勉
強になったし、初めて、eql-specializerを使った例まで書いちゃって、これ
でおれもいっぱしのLisp屋かな(爆)。
おれの場合、初めてCLOSを見たとき、「よーやるわ、こいつら」と思ったの
は、メソッドがクラスに縛られないこと、マルチメソッドによるディスパッチ、
メソッド結合によるメソッドの修飾などのアイデアの数々だった。
たしかに、通常の関数だと、eql specializerの例で示したように、誤って
do-foo-singletonにfoo-normalを渡してもエラーにならないけど、そんなとこ
ろで間違って渡すようだと、プロのプログラマとしてやってけないと思うけど
ね。
あ、そう。じゃ、お前、クビだね。\(^O^)/
CLOSは何でもできると思っていたが、個人的にはそんなにありがたい気がし
ないし、滅多に使われないであろうeql specializerによる特異メソッドもあ
ったのには、ちょっと驚いた。
Lisp屋が、Flavorsなど、CLOSの前身になるようなオブジェクト指向のシス
テムをLisp上に作り始めたが1970年代の後半から1980年代だと思うが、いろい
ろ実験して、CLOSの仕様が定まって、正式にANSI Common Lispに入ったのが、
1994年だったはずだから、今回改めて、CLOSの先進性を感じた次第。
CLOSがANSI Common Lispに入っているということは、ANSI準拠のCommon
Lisp処理系ならCLOSが使えるということ。だから、Lispではオブジェクト指向
もできる。
CLOSだけでもフツーは十分だろうが、さらに加えて、CLOSの挙動を自在に再
定義するMOP(Meta Object Protocol, モップと読む)もある。この辺が、いろ
んなことが変幻自在になってないと気がすまないいかにもLisp屋の発想だなと
思う。
こっちは、まだ公式には標準化されてないけれど、事実上の標準としてAMOP
(A Meta Object Protocol)があって、いまのCLOSの実装は、大体、これに準拠
しているそうだから、かなり互換性はあると思う。
Common Lispの入門情報やCLOSの入門情報をまとめたものは、別の機会にし
ます。
余談だが、
http://www.amazon.co.jp/exec/obidos/ASIN/4894714337/showshotcorne-22/ref=nosim
ポールグレアム著, 久野雅樹, 須賀哲夫訳「ANSI Common Lisp」
では、Smalltalk的というかJava的というかRuby的というか、他のオプジェク
ト指向言語的というか、クラスにメソッドが属して、かつ単純継承のオブジェ
クト指向システムの基本部分を、従来のCommon Lisp(つまり、CLOSではない伝
統的な部分だけ)を使って、たったの8行で作っている。
なぜ、そんなトリックができるのか。それはLispがそれだけのものをすでに
備えていて、8行でやったのは、その外観を加えただけなのだという話。
この8行でやったことを効率化していくと、85行くらいになっている。
http://www.paulgraham.com/lispcode.html
の
http://lib.store.yahoo.net/lib/paulgraham/acl2.lisp
ANSI Common Lisp Code
; *** ob ***
の行からが、それ。
同じ著者で、中級上級者用の
http://www.amazon.co.jp/exec/obidos/ASIN/0130305529/showshotcorne-22/ref=nosim
Paul Graham著「On Lisp」(Prentice Hall)
のほうにも、形を変えてこの話が出てくるが、それは自分で探してください。
Paul Grahamのウェブサイトでは、電子版を無料で配っている。
http://www.paulgraham.com/onlisp.html
Paul Graham著「On Lisp」(Prentice Hall)
をどうぞ。
そして、この翻訳版を野田開さんが、高校生のころから翻訳をはじめて、逐
次ウェブ・サイトで配っていたのが、
http://user.ecc.u-tokyo.ac.jp/~t50473/
野田 開のウェブ・サイト
にある。
何度も書くが、翻訳本が出る出るといわれて、いまだ出ず。どうなっておる
のだ。
野田さん、高校でLisp知ってたんだもんね。すごいね。
東大行かずに世界で最初?にCommon Lispの実装を公開したKyoto Common
Lisp(いまのGNU Common Lispの元)の京大数理解析研究所に行けばよかったの
に。\(^O^)/
あ、高校生からいきなり京大数理解析研究所は入学できないか。\(^O^)/
一度、Franz社の小俣さんが野田さんを連れてきてくれたときがあって、一
緒に昼飯食いましたが、野田さん、一流物理学者になるのが夢というんだから、
いいよなあ。
おれなんか物理学者になれないから、いまは、国際宇宙ステーションまで歩
いて上るのが夢だってんだからね。\(^O^)/
おい、違うだろ、それは。
あ、そうだった。国際宇宙ステーションまで、自転車で行くのが夢。\(^O^)/
コメント
_ 穴山 ― 2007年01月13日 13時36分16秒
※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。
※なお、送られたコメントはブログの管理者が確認するまで公開されません。
※投稿には管理者が設定した質問に答える必要があります。
トラックバック
_ ホットコーナーの舞台裏 - 2007年01月14日 03時15分24秒
ASAHIネット(http://www.asahi-net.or.jp)のjouwa/salonからホットコーナー(http://www.asahi-net.or.jp/~ki4s-nkmr/ )に転載したものから。
---
http://iiyu.asablo.jp/blog/2007/01/13/1109447
Rubyの特異メソッドとCLOSのeql spe
---
http://iiyu.asablo.jp/blog/2007/01/13/1109447
Rubyの特異メソッドとCLOSのeql spe
_ ホットコーナーの舞台裏 - 2015年08月12日 10時45分23秒
ASAHIネット(http://asahi-net.jp )のjouwa/salonからホットコーナー(http://www.asahi-net.or.jp/~ki4s-nkmr/ )に転載したものから。
---
出版社のManningから、お前、これ、MEAPが始まったから、買ってくれと
---
出版社のManningから、お前、これ、MEAPが始まったから、買ってくれと
The Art of Metaobject Protocol
http://www.amazon.co.jp/exec/obidos/ASIN/0262610744
のことだと思いますが…