web-dev-qa-db-ja.com

静的型システムは、プロトタイプベースの言語の設計にどのように影響しますか?

プロトタイプベースの言語に関するウィキペディアの記事 には、次の段落が含まれています。

ほとんどすべてのプロトタイプベースのシステムは、インタープリター型の動的型付け言語に基づいています。ただし、静的型付け言語に基づくシステムは技術的に実現可能です。

静的型システムはどのような方法でプロトタイプベースの言語に制限を課したり、複雑さを導入したりしますか?なぜ動的に型付けされたプロトタイプ言語があるのですか?

15
Joe

基本タイプとオブジェクトの境界はぼやけており、しばしば人為的に導入されます。たとえば、Cでは、構造体は単なるレコードの集まりであり、派生した非オブジェクト型です。 C++では、構造体はすべてのフィールドがパブリックであるオブジェクトであるクラスです。それでも、C++はCとほぼ完全に下位互換性があります...境界線はここでは本当に柔らかくなっています。

プロトタイプベースのプログラミングの場合、実行時にオブジェクトを変更可能にする必要があります。実行時にそれぞれが変化し、ある種類のクラスが別の種類に変化するため、それらはソフトタイプ化されなければなりません-そのタイプが変化します。

ただし、基本および派生した非オブジェクト型を静的に保つことができます。しかし、これは奇妙な格差をもたらし、オブジェクトはソフトタイプであり、非オブジェクトはスタティックタイプであり、2つの間にハードバリアを確立する必要があります。構造をモーフィングできますか?文字列? Numberはクラス、基本タイプ、または基本タイプのセット、int/float/bignum/etcにする必要がありますか?

このユニフォームを使用すると、学習、使用、書き込みがより自然で簡単になり、すべての型が変更可能になるか、実行時に変更可能な型がなくなります。 1つのタイプ(オブジェクト)のみが変更可能であると宣言すると、両方の世界で頭痛と問題が発生します。

静的型付けは次のとおりです。

  • 実装が簡単
  • より速く/より効率的
  • より安全
  • 抽象化により、大きなシステムの保守/ドキュメント化が容易になります。

動的型付けは次のとおりです。

  • 書き込みが速く、
  • より簡潔な
  • 学びやすい言語
  • 設計エラーに対してより寛容です。

2つをブレンドすることで、多くを犠牲にします。

  • 前の2つのいずれよりも実装が困難になります。
  • 速度は、ソフトタイプを使用するかどうかによって異なります...使用する場合は低速です。使用しない場合は、なぜ言語を選択するのですか?
  • タイプセーフは、すべてのオブジェクトタイプのウィンドウの外にあります。
  • あるタイプが別のタイプにモーフィングする方法をたどることは、かなり難しい作業です。文書化-非常に難しい。
  • あなたはまだ基本的なタイプですべての簿記をする必要があります、それは簡潔さと執筆速度を殺します
  • 言語の複雑さは、「特定の」言語のどれよりも高い(学ぶのが難しい)、
  • 動的型付けの「寛容」は、属性型の不一致で非常にトリッキーなエラーが発生する傾向に置き換わります。
6
SF.

難しさは簡単にわかります。オブジェクトのビューをメソッドのディクショナリとして、またはメッセージに応答するものとして、一般的な静的型付けされたOO言語について、以下の点に注意してください。

  • すべてのディクショナリキー/メッセージは、静的に宣言された識別子を使用して、通常事前に宣言されます。

  • メッセージの特定のセットは事前に宣言されており、オブジェクトはこれらのセットに関連付けられて、どのメッセージに応答するかを決定します。

  • 別のサブセットであるメッセージの1つのセットの包含関係は、静的かつ明示的に宣言されます。宣言されていませんが、論理サブセットは無効です。

  • 型チェックは、すべてのメッセージがそれらに応答するオブジェクトにのみ送信されることを確認しようとします。

これらはすべて、プロトタイプベースのシステムとある程度競合します。

  • メッセージ名は、「アトム」またはインターンされた文字列などの形式で事前に宣言できますが、それ以外はほとんどありません。オブジェクトの可塑性は、メソッドへの型の割り当てが厄介であることを意味します。

  • プロトタイプベースのシステムの重要な機能は、メッセージのセットがオブジェクトの応答によって定義されることであり、その逆ではありません。コンパイル時にエイリアスを特定の組み合わせに割り当てることは妥当ですが、実行時に決定されるメッセージセットが可能でなければなりません。

  • 上記の2つの実際の影響は、明示的な宣言が完全に機能しない包含関係に帰着します。静的な名目上のサブタイプの意味での継承は、プロトタイプベースのシステムとは正反対です。

これで、最終的にポイントが決まります。つまり、実際には変更したくないです。メッセージがそれらに応答するオブジェクトにのみ送信されることを確認したいのですが。しかしながら:

  • どのメッセージがグループ化されているかを静的に知ることはできません。
  • どのグループが他のグループのサブセットであるかはわかりません。
  • どのグループが可能かわかりません。
  • 単一のメッセージと共に送信される引数の種類を指定することもできません。
  • 基本的に、完全に一般的なケースでは、ほとんど何も指定できないことがわかりました。

では、どうすればこれを回避できますか?どういうわけか完全な一般性を制限する(これは不愉快であり、最初にプロトタイプベースのシステムを使用する利点をすぐに失う可能性があります)、または型システムをより流動的にして制約ではなく正確なタイプ

制約ベースの型システムはすぐに 構造サブタイプ の概念につながります。これは、非常に大まかに言えば、「ダックタイピング」の静的な同等物と考えることができます。ここでの最大の障害は、そのようなシステムは型チェックがはるかに複雑であり、あまり知られていないことです(つまり、以前に研究する必要がほとんどありません)。

要約すると、それは可能であり、名目上の静的型システムまたはランタイムメタデータに基づく動的システムのどちらよりも行うのが難しいため、ほとんどの人が気にする必要はありません。

3
C. A. McCann

静的に型付けされたプロトタイプベースの言語を実現する方法は、テンプレートとコンセプトに基づいて言語をベースにすることだと思います。

コンセプトはかつてC++ 0xで計画されていた機能でした。 C++テンプレートの一般的なコードは、すでにde facto「静的にアヒル型付け」されています。概念のアイデアは、その関係の基礎となるクラス継承モデルを要求または暗示することなく、必要なメンバーおよび型の特性についていくつかのことを言えるようにすることです(すでに「静的にアヒル型付けされた」既存のテンプレートコードで動作する必要があるため) )。

テンプレートとコンセプトに根本から基づいた言語では、プロトタイプベースのコンセプトであり、テンプレートは、値のタイプの実装に使用される場合と使用されない場合のあるクラスモデルを気にする必要がなくなります。

段階的コンパイルを使用して言語を独自のメタ言語にするためのトリックを除いて、これらの概念のプロトタイプ的な派生は、作成後は不変になります。ただし、プロトタイプベースではないという異論は、レッドニシンです。それは単に関数型言語でしょう。 dynamicプロトタイプベース言語であり、機能的でもある 少なくとも試行された

1
Dennis Ferron