ダックタイピングとポリモーフィズム

コンパイル時ダックタイピング - みねこあ にて、過去のわたしは

ダックタイピングは

  • ad-hoc polymorphism
  • subtype polymorphism
  • parametric polymorphism

のどれにあたるか?

コンパイル時ダックタイピング - みねこあ

という点で悩んで、混乱していました。

その点について、英語版のWikipedia Duck typingAd-hoc polymorphism がわかりやすかったので気持ち翻訳してみました。


* * *


まずは、Duck typing - Wikipedia から。

Structural type systems

Duck typing is similar to but distinct from structural typing. Structural typing is a static typing system that determines type compatibility and equivalence by a type’s structure, whereas duck typing is dynamic and determines type compatibility by only that part of a type’s structure that is accessed during run time.

ダックタイピングは structural typing に似ているが、異なったものである。Structual typing は静的型システムで、型のの互換性と同値性を 型の構造から判断する。それに対して ダックタイピングは動的で、型の互換性と同値性を ランタイムにアクセスした部分のみで判断する。

The Objective Caml and Scala languages use structural type systems.

OCamlScala が structural type システムを使っている。

Interfaces

Interfaces can provide some of the benefits of duck typing but duck typing is distinct in that no explicit interface is defined. For example, if a third party Java library implements a class you are not allowed to modify, you cannot use an instance of the class in place of an interface you have defined yourself, whereas duck typing would allow this. Again, all of an interface must be satisfied for compatibility.

インターフェイスは幾つかのダックタイピングの利点を提供するが、ダックタイピングは明白なインターフェイスの定義が無いという違いがある。例えば、もしサードパーティ Java ライブラリが あなたが変更できないクラスを実装してた場合、あなたは自分で定義したインターフェイスの代わりに、そのクラスのインスタンスを使うことができないのに対し、ダックタイピングではそれが出来る。また、あるインターフェイスはその全てについて互換性を満たさなければならない。

Templates or generic types

Template, or generic functions or methods apply the duck test in a static typing context; this brings all the advantages and disadvantages of static versus dynamic type checking in general. Duck typing can also be more flexible in that only the methods actually called at run time need to be implemented, while templates require implementation of all methods that cannot be proven unreachable at compile time.

テンプレート、または 総称関数またはメソッドは、ダックテストを 静的型付けコンテキストの中で行う。これは一般に 静的型チェックに対しての動的型チェックのすべての利点と欠点をもたらす。テンプレートはコンパイル時にアンリーチャブルでないと証明されたすべてのメソッドの実装が必要だが、ダックタイピングは実際にメソッドがランタイムに呼ばれる時に実装が必要であるだけ、よりフレキシブルであることができる。(??翻訳に自信なし)ダックタイピングにおいては実行時に実際に呼ばれたメソッドのみが実装されていればよく、一方でテンプレートではコンパイル時にアンリーチャブルであると証明できなかった全てのメソッドを実装する必要があるため、ここでもダックタイピングはよりフレキシブルとなれる。

Examples include the languages C++ and D with templates, which developed from Ada generics.

Duck typing - Wikipedia

次は Ad-hoc polymorphism - Wikipedia。アーリーバインディングの例として overload を紹介したあと、それに対となる レイトバインディングでの Ad-hock polymorphism を紹介しているのですが、なんというか、Smalltalk愛に満ち満ちていて(?)、感動しました。

Late binding

The previous section notwithstanding, there are other ways in which ad-hoc polymorphism can work out. Consider for example the Smalltalk language. In Smalltalk, the overloading is done at run time because the methods (“function implementation”) for each overloaded message (“overloaded function”) are resolved when they are about to be executed. This happens at run time, after the program is compiled. Therefore, polymorphism is given by subtyping polymorphism as in other languages, and it is also extended in functionality by ad-hoc polymorphism at run time.

前項にも関わらず、アドホックポリモーフィズムが働く別の方法もある。Smalltalk言語を例に考えてみる。Smalltalkでは、overload された メッセージ(“overloaded function”) の為のメソッド(”function implementation”)は、execute 時に決定される為、overload は ランタイムで実行される。これらはプログラムがコンパイルされた後の、ランタイムに起こる。それゆえに、ポリモーフィズムは 他の言語のように subtyping polymorphism よりもたらされ、また、ランタイム時の ad-hoc polymorphism によっても機能拡張される。

A closer look will also reveal that Smalltalk provides a slightly different variety of ad-hoc polymorphism. Since Smalltalk has a late bound execution model, and since it provides objects the ability to handle messages which are not understood, it is possible to go ahead and implement functionality using polymorphism without explicitly overloading a particular message. This may not be generally recommended practice for everyday programming, but it can be quite useful when implementing proxies.

しかし、よく見れば明らかなのは、Smalltalkは は アドホックポリモーフィズムのわずかに違うバラエティを提供する。Smalltalkは レイトバインディング実行モデルを持っているので、それがオブジェクトに未知のメッセージをハンドルする能力を提供しており、それが前進して、特定のメッセージの明確なオーバーロードなしにポリモーフィズムを使用して機能を実装すること可能にする。これは日々プログラミングにといて通常のプラクティスとして推奨されないが、プロキシを実装するとき、とても便利だ。

Also, while in general terms common class method and constructor overloading is not considered polymorphism, there are more uniform languages in which classes are regular objects. In Smalltalk, for instance, classes are regular objects. In turn, this means messages sent to classes can be overloaded, and it is also possible to create objects that behave like classes without their classes inheriting from the hierarchy of classes. These are effective techniques which can be used to take advantage of Smalltalk’s powerful reflection capabilities. Similar arrangements are also possible in languages such as Self and Newspeak.

また、一般的な terms における 共通クラスメソッド や コンストラクタのオーバーロードポリモーフィズムとは考えられないが、クラスが通常のオブジェクトであるようなもっと均一な言語もある。Smalltalk では、 インスタンスもクラスも 通常のオブジェクトである。In turn 、これが意味するのは クラスへのメッセージ送信はオーバーロード可能で、クラス階層から継承することなしに、クラスのように振舞いでオブジェクト生成を可能にすることが出来る(???)。さらにこの結果、クラスに送られたメッセージもオーバーロードでき、加えてそのクラスがクラスの階層から継承することなくクラスのように振るまうオブジェクトの作成も可能である。これらは Smalltalk のパワフルなreflection 機能を活用するための効果的なテクニックです。よく似た処理 Selfや Newspeak といった言語でも可能である。

Ad hoc polymorphism - Wikipedia


翻訳はかなり怪しいので、ごめんなさい。

結論は、ダックタイピングはダックタイピングということ。dack-typing は structural-subtyping に似ていますが、二人は似て異なる物。

Wikipedia の Ad-hoc polymorphism をみると、強いて言えば実行時 ad-hoc polymorphism といえなくない、すなわち overload の レイトバインディング版と捉えるのが良いのかな?、と思うのですが、これも似て非なるモノっぽいというか。難しいですにゃ〜。


* * *


上記 Wikipedia の記事もわかりやすかったのですが、もっと素晴らしいのは いげ太さんここのエントリーだと思います。

http://igeta.cocolog-nifty.com/blog/2008/05/subtyping.html

必ず読まなければいけないと思います。人として。

あまりに素敵だったので、勢いで「実践 F# 関数型プログラミング入門 」をアマポチしてしまいました。届くのが楽しみです。