Я только что посмотрел этот доклад Даниэля Спевака, в котором он рассказывает о преимуществах структурной типизации по сравнению с номинальной типизацией Scala и Java . Одним из примеров этого различия будет следующий код 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
Верно ли мое понимание того, что в системе структурных типов последняя строка будет компилироваться, и если это так, не будет ли это недостатком в отношении безопасности типов?
источник
Ответы:
На самом деле, зависимые от пути типы ортогональны структурной или номинальной типизации. Не совсем понятно, что означает внутренний класс в контексте простого языка структурной типизации. Однако это очень возможно определить . Если бы вы определяли внутренние классы в структурно типизированном контексте, вам нужно было бы гарантировать, что такие случаи, как тот, который вы перечислили, будут отклонены (по тем же причинам, по которым Scala их отклоняет).
Вы бы отклонили такие случаи, выполнив то же самое, что и Scala: смоделируйте зависимый от пути тип как экзистенциальный тип. Та же самая процедура упаковки / распаковки, связанная с доступом к объектам, будет иметь место, и результаты будут выглядеть почти идентично тому, что делает Scala. Результаты могут показаться номинальным равенством типов, но это все равно будет структурная система типов, поскольку вопрос совместимости типов будет по-прежнему решаться на интерфейсе, а не на имени.
Структурная типизация действительно имеет много последствий, но (возможно, что удивительно) большинство тех же самых понятий, которые мы все знаем и любим из систем номинального типа, переносятся на структурные. Структурная типизация - не что иное, как другой способ определения совместимости типов.
источник
Структурная типизация облегчает написание универсального библиотечного кода. Причина № 1, почему экосистема Java настолько раздутая, заключается в том, что трудно легко писать небольшие библиотеки. Если бы Java был структурно типизирован, я думаю, это была бы другая история и намного лучшая ситуация.
Единственный недостаток, который я могу придумать для структурной типизации, - это возможность более медленной компиляции. Я не уверен, что структурные языки обычно компилируются медленнее, чем номинативные, или нет, но, например, Golang структурно типизирован и очень быстро компилируется.
источник