Почему вывод типа непрактичен для объектно-ориентированных языков?

В настоящее время я изучаю идеи для нового языка программирования, где в идеале я хотел бы, чтобы язык смешивал некоторые функциональные и процедурные (объектно-ориентированные) концепции.

Одна из вещей, которые я действительно увлекаю такими языками, как Haskell, - это то, что она статически типизирована, но вам не нужно вводить аннотации типов (волшебство благодаря Hindley-Milner!).

Мне бы очень понравилось это для моего языка, однако после чтения по этому вопросу кажется, что большинство согласны с тем, что вывод типа непрактичен/невозможно с подтипированием/ориентацией объектов, однако я не понял, почему это так. Я не знаю F #, но я понимаю, что он использует Hindley-Milner AND объектно-ориентированный.

Мне бы очень хотелось пояснить это и, желательно, примеры в сценариях, где вывод типа невозможно для объектно-ориентированных языков.

Ответ 1

При использовании стандартного набора текста (это система ввода, где два класса, члены которых имеют одинаковое имя и одинаковые типы, не являются взаимозаменяемыми), было бы много возможных типов для метода, подобного следующему:

let f(obj) =
    obj.x + obj.y

Любой класс, который имеет как член x, так и член y (типов, поддерживающих оператор +), будет квалифицироваться как возможный тип для obj, и алгоритм вывода типа не будет иметь никакого способа зная, какой из них вам нужен.

В F # приведенный выше код потребует аннотации типа. Таким образом, F # имеет ориентацию объекта и тип вывода, но не в одно и то же время (за исключением локального типа вывода (let myVar = expressionWhoseTypeIKNow), который всегда работает).

Ответ 2

Чтобы добавить к ответу seppk: со структурными типами объектов проблема, которую он описывает, действительно исчезает (f может быть задан полиморфным типом типа & forall; A & leq; {x: Int, y: Int}. A → Int или даже просто {x: Int, y: Int} → Int). Однако вывод типа все еще проблематичен.

Основная причина заключается в следующем: на языке без подтипирования правила набора текста налагают ограничения равенства на типы. С ними очень приятно иметь дело во время проверки типов, потому что их обычно можно упростить с помощью унификации по типам. Однако при подтипировании эти ограничения обобщаются на ограничения неравенства. Вы больше не можете использовать унификацию, которая имеет как минимум три неприятных последствия:

  • Число и сложность ограничений взрываются комбинаторно.
  • Информация, которую вы должны отображать пользователю в случае ошибок, непонятна.
  • Некоторые формы количественной оценки могут быстро стать неразрешимыми.

Таким образом, вывод типа для подтипинга не является невозможным (в 90-х годах было много статей по этому вопросу), но это не очень практично.

В OCaml используется гораздо более простая альтернатива, в которой вместо подтипирования используется так называемый полиморфизм строк. Это действительно сносно.