ToDo:
http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1146611996
via http://twitter.com/kmizu/status/24476568147
見てて、あれ、俺 duck typing が嬉しいと思ったことあったっけ… と思った。 なんかやたらと元質問者に同意するんだよね。
はて…
色々考えた結果、 interface を書かなくていいという type 数節約よりも、 interface のドキュメントとしての価値の方が重く見てるんだろうなぁと思った。 それと同時に、 duck typing は別にメリットとか無くて、 動的型だからしょうがなくやってるだけなんじゃないかと思えてきた。
あと静的型なのに duck typing な OCaml の OO はゴミなんじゃないかとも。 使ったこともないのに失礼なヤツだな…
(23:49)
前 | 2010年 9月 |
次 | ||||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 |
全てリンクフリーです。 コード片は自由に使用していただいて構いません。 その他のものはGPL扱いであればあらゆる使用に関して文句は言いません。 なにかあれば下記メールアドレスへ。
duck typing って、クラス作る人が (ユーザに責任押し付けることで) クラス設計を楽するためのものだと思ってます。クラス作らない人にはメリットないかも。
例えば StringIO みたいなのを自分で作る場合、duck typing がないと、StringIO と IO に共通の interface を持たせる必要がある。けれど IO は自分の管理下じゃないので変えられない (or めんどい) 。でも StringIO < IO とするには抵抗がある (IO だとファイルディスクリプタとか持つことになるので) 。とか悩まなくて済みます。
一方で IO を作る人も、「将来 StringIO みたいなのを作るときのために、抽象クラスや interface が必要だろうか」とか気にしなくて済みます。そもそも将来の問題をそこまで予測するのがとても大変。
というように、クラス設計時に深く悩まないでいいのが duck typing の強みだと思います。最終的に世に出た IO と StringIO を使うだけのユーザにしてみれば、「同じ interface にしてくれよ」と思うかもしれませんが。
ちなみに StringIO 以外にも、Matrix と Numeric とか、Tempfile と File とか、微妙な関係はちらほらあります。
いやいやクラス設計は十分検討しなきゃダメだろう、という人もいそうですが、実際の Java の運用ポリシーも、「とりあえずいっぱい interface 作っとこう (Java API 設計者)」または「必要になったら interface 足せばいいや (Java ユーザ)」になってる気がします。
後者は (静的型検査できる利点を除けば) めんどうなだけですし、前者は大量のクラスや interface を生み出し、それはユーザにとって不親切になることすらあると思っています。
Enumearble (each できる) 、Readable (read できる) 、Writable (write できる) 、Positionable (pos できる) 、Indexible ([] できる) 、Sizable (size/length できる) 、Addable (<< できる) 、Inspectable (inspect できる) 、Convertable (to_s/to_str/to_i できる、それぞれに interface 作るべきか?) 、……
本文より長いコメントでした。
duck typingできても、メソッド名と引数の内容合わせなければいけないので、duck typingできたとしてもクラス設計は十分検討しなきゃダメだろうとおもうんですが。
あと疑問に思うんですが、あるダックタイピングをしてるメソッドにオブジェクトを引数として渡す場合、そのオブジェクトが必要なメソッドをすべて実装しているかどうか簡単に調べる方法があるでしょうか?ソースを読まないとわからない?
OCamlの場合、必要なメソッドを実装したオブジェクトしか渡せないので十分有効だと思います。Scalaでも似たようなことできますし。
> duck typingできても、メソッド名と引数の内容合わせなければいけないので、duck typingできたとしてもクラス設計は十分検討しなきゃダメだろうとおもうんですが。
メソッド名と引数の内容を合わせるってどういう意味ですか? そんな難しいことですか?
もちろん全くクラス設計しなくていいわけではないですが、だいぶ楽になるという話です。
> あと疑問に思うんですが、あるダックタイピングをしてるメソッドにオブジェクトを引数として渡す場合、そのオブジェクトが必要なメソッドをすべて実装しているかどうか簡単に調べる方法があるでしょうか?
Ruby の場合の話ですよね? Ruby の場合はできないです。そのかわり、慣習として、あんまり複雑な duck typing は使われません。
つまり、「あれとこれとそれと……のメソッドを持つ」みたいな duck typing は普通使わなくて、せいぜい「each メソッドを持つ」とかです。
なので、それほど苦労を感じたことはありません。
使われないことで有名な OCaml の O に慣習とかあるのか分かりませんが、必要なメソッドをすべて実装しているか不安になるほど複雑な duck typing を使うものなんですか?
lablgtk の doc をちらっと見てみましたが、そんな激しい型は見つかりませんでした。個人的にもそういう API はあまり使いたくないです (型検査があろうがなかろうが) 。慣れの問題かもしれませんが。
ちなみに、メソッドをチェックする静的型検査自体はいいものだと思います。duck typing 単体と静的型検査のどっちがいいかと聞かれたらぼくは後者と答えます。
matz の考えは知りませんが個人的には、Ruby は duck typing のためだけに静的型検査をしないのではなく、eval とか open class とかインタプリタ実装の容易さとかなど色々勘案した上で静的型検査しない道を選んだんだと思っています。
「とりあえずいっぱいinterface作っとこう」は、Haskellの型クラスみたいなinterfaceを後付けできる機構さえあれば解決するような。寡聞にして実際にその機構がある言語を知りませんが、無いですかね。簡単にできるような……。
あとOCamlのOOはファーストクラスオブジェクトでやるもので、多相レコードのアレは単に実験的に付けられた誰も使ってない機能では……と思ってしまう私は変でしょうか。
うわあああファーストクラスモジュールの間違いです。
AspectJ の declare parents とか。> 後付け
>必要なメソッドをすべて実装しているか不安になるほど複雑な duck typing を使うものなんですか?
いや、別に複雑じゃなくても、渡すオブジェクトが何を実装していなくちゃならないのかが簡単にわからないのでは、困りませんか?
たとえば、「each メソッドを持つ」必要があるというのを知るのはどうやればいいのでしょう?ソースを見る必要があるんでしょうか?
ドキュメントやサンプルコードを見ます。
はじめまして。
>あと疑問に思うんですが、あるダックタイピングをしてるメソッドにオブジェクトを引数として渡す場合、そのオブジェクトが必要なメソッドをすべて実装しているかどうか簡単に調べる方法があるでしょうか?
Object#respond_to? ではだめでしょうか。