6

私はしばらくSOを検索しましたが、明確で一般的な答えを見つけることができず、矛盾した特定の意見しか見つかりませんでした. [1]

ダックタイピングとジェネリックプログラミングの関係は何ですか?(DT < GP、DT == GP、DT > GP) . ジェネリック プログラミングでは、特に C++ テンプレートまたは Java ジェネリックを参照しますが、可能であれば、概念に関連する一般的な回答を歓迎します。

一般的なプログラミングはコンパイル時に処理され、ダックタイピングは実行時に処理されることはわかっていますが、その一部を配置する方法がわかりません。

最後に、私は議論を始めたくないので、理由、反対の理由のような回答を希望します.

[1] C++ テンプレートとダック タイピングの関係は?

4

4 に答える 4

8

「ダックタイピング」の 2 つの異なる定義に遭遇しました。どちらかが「正しい」で、もう一方が「正しくない」と言う人がいるに違いありません。どちらも「正しい」とは言いませんが、個人的には、より広い意味で間違っているとは思いません。

1) 実行時のみの型付け。型は変数ではなくオブジェクトのプロパティであるため、必然的にオブジェクトのメソッドを呼び出すとき、またはオブジェクトがその型によって持つプロパティを使用するとき、そのメソッドの有無は実行時に発見されます[* ]。したがって、「アヒルのように見え、アヒルのように鳴く」場合 (つまり、quack()機能があることが判明した場合)、それは「アヒル」です (とにかく、アヒルのように扱うことができます)。もちろん、この定義により、C++ テンプレートは最初のハードルに落ちます。静的型付けを使用します。

2)アヒルのように見え、アヒルのように鳴く場合、それはアヒルであるという原則に対してより一般的に使用される名前。プロデューサーによって明示的にアドバタイズされているインターフェースよりも(インターフェースを実装するものは何でも)。この定義によると、C++ テンプレートは一種のダックタイピングを使用しますが、何かが「アヒルのように見える」かどうかは、動的な型ではなく静的な型に基づいて、実行時ではなくコンパイル時に決定されます。「コンパイル時にチェックしてください。この変数の静的型はクワックできますか?」ではなく、「実行時にチェックします。このオブジェクトはクワックできますか?」。

この論争は、Python がこの用語を「所有」しており、Python のような型システムだけをダックタイピングと呼ぶことができるかどうか、または他の人がこの用語を別のコンテキストで同様の概念を意味するように自由に流用できるかどうかに関するものであるように私には思えます。 . あなたがそれが意味するべきだと思うものは何でも、「冗談」の用語を使用して、誰もがそれから同じ正式な定義を理解することを要求するのは無責任に思えます. SO は、「あるべき」という用語が何を意味するかを説明するのに適したフォーラムではありません。ただし、辞書やそれを正式に定義している学術論文など、質問している信頼できる情報源がない限りはそうです。それが実際に何を意味していたのかを教えてくれると思います。

「汎用プログラミング」は、正確な詳細に応じて、ダックタイピングを利用することもしないこともできます。C++ の一般的なコンテナーは、「タイプ 2」のダックタイピングを使用します。これは、C++ の一般的な型の場合、コピー、比較、ハッシュ値の取得などを実行できることが保証されていないためです。Java の一般的なコンテナーはそうではなく、Object既に十分なメソッドがありますハッシュ可能にするなど。

逆に、ダックタイピングを使用するものはすべて、「ジェネリックプログラミング」と呼ぶのが妥当だと思います。したがって、あなたが求めた用語では、そのダックタイピング(定義のいずれか)の GP > DT は、「ジェネリック」と呼ぶことができる膨大な範囲のものの厳密なサブセットであると思います。

[*] 場合によっては、動的言語に何らかの方法でケースを証明する静的分析が含まれる場合がありますが、言語では、静的分析で最終的に判断できない場合に実行時までこのチェックを延期する機能が要求されます。

于 2012-09-17T12:59:01.757 に答える
6

これは本当に語彙の問題です。最も一般的な意味では、ジェネリック プログラミングはコンパイル時と実行時の問題とは無関係です。つまり、ジェネリック プログラミングは一般的な問題の解決策です。ジェネリック プログラミングがランタイムである良い例は Python ですが、ランタイム ジェネリック プログラミングを C++ で実装することもできます (実行時間にかなりのコストがかかります)。

ダックタイピングは直交概念であり、通常はランタイムタイピングを意味するために使用されます。繰り返しになりますが、最も頻繁に引用される最新の例は Python ですが、Lisp に始まる非常に多くの言語が過去に Python を使用しています。原則として、C++ と Java の両方がダック タイピングをサポートしないことを明示的に選択しています。これはトレードオフです: 安全性と柔軟性 (またはコンパイル時エラーと実行時エラー)。

于 2012-09-17T10:25:11.827 に答える
2

Javaは、その言語でのダックタイピングをサポートしていません。それは同じことを達成できる反射をサポートします。私が見る限り、Javaのジェネリックスとは何の関係もありません。実際、Javaのジェネリックスを一緒に動作させるのは本当に苦痛です。

于 2012-09-17T10:10:11.410 に答える
1

私にとって、「ダックタイピング」とは、明示的な適合関係がないことを意味します。アヒルのように歩き、アヒルのように話すものは、アヒルのように扱うことができ、アヒルであることを明示的に宣言する必要はありません。C++ の用語では、Duck ベース クラスから継承する必要はありません。継承とは、あるクラスが別のクラスのインターフェイスに明示的に準拠していることを宣言する方法です。

この概念は、型チェックが実行時またはコンパイル時に行われるかどうかとは直交しています。Smalltalk のような言語は、実行時に発生するダックタイピングを提供します (また、継承は、インターフェースの適合性を宣言するためではなく、実装を再利用するために使用されます)。C++ テンプレートは、コンパイル時に発生するダックタイピングの一種です。

そして、その最後の文が質問への答えです。

于 2012-09-17T15:11:04.490 に答える