構造タイピングの(不)利点


15

私はちょうどダニエル・シュピーワクによるこの講演を見ました。そこで彼は、Scalaのans Javaの名目上の型付けと比較した構造型付けの利点について話しています。この違いの1つの例は、次のJavaコードです

public interface Foo {
  public int length();
}
public interface Bar {
  public int length();
}

Foo f = ...;
Bar b = f;

もちろんその間タイプの互換性ため、コンパイルされないだろうFooとは、Bar名前によって決定されます。

一方、構造型システムでは、両方の型が等しいか互換性があると宣言できるため、とりわけ、チェックされたアヒルの型付けが可能になります。

今、私は構造型システムの利点のほとんどを理解していると思いますが、次のような例から型安全性を無効にしないのではないかと思います

class Foo {
  class Bar { /* ... */ }
  def takeBar(b: Bar) = { /* ... */ }
  def getBar: Bar = new Bar
}

val foo1 = new Foo
val foo2 = new Foo
foo1.takeBar(foo1.getBar) // should compile
foo1.takeBar(foo2.getBar) // should not compile

構造型システムでは最後の行もコンパイルされ、もしそうなら、これは型の安全性に関して不利ではないという私の理解は正しいですか?


3
最後の行がコンパイルされない理由を説明できますか?型の非互換性は見当たりません。
サムゴールドバーグ

2
Scalaのパス依存型です。
デビルスキー

実際、私はこれをScala型システムの観点から議論したかったのです。講演で与えられた1つの例がJavaであったことがたまたま起こりました。
デビルスキー

回答:


12

実際、パス依存型は、構造型と名義型に直交しています。単純な構造的に型付けされた言語のコンテキストで、内部クラスが何を意味するのかは本当に明確ではありません。ただし、これを定義することは非常に可能です。構造的に型付けされたコンテキストで内部クラスを定義する場合、リストしたようなケースが拒否されることを確認する必要があります(Scalaが拒否するのとまったく同じ理由で)。

このような場合は、Scalaと同じことを行うことで拒否します。パス依存型を実存型としてモデル化します。オブジェクトアクセスを囲む同じパック/アンパック手順が保持され、結果はScalaが行うこととほとんど同じに見えます。結果は名目上の型の平等のように見えるかもしれませんが、型の互換性の問題は名前ではなくインターフェイスで決定されるため、構造型システムのままです。

構造型付けには多くの意味がありますが、(おそらく驚くべきことに)名目型システムで私たちが知っている、愛する同じ概念のほとんどが構造型に引き継がれます。構造型付けは、型の互換性を定義する別の方法にすぎません。


0

構造型付けにより、汎用ライブラリコードを簡単に記述できます。Javaエコシステムが肥大化する一番の理由は、小さなライブラリを簡単に作成することが難しいためです。Javaが構造的に型付けされている場合、別の話であり、はるかに良い状況になると思います。

構造型付けに関して考えられる唯一の欠点は、コンパイルが遅くなる可能性です。構造言語のコンパイルが一般的にノミネート言語よりも遅いかどうかはわかりませんが、たとえばGolangは構造的に型付けされており、コンパイルが非常に高速です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.