Есть ли языки, которые реализуют дженерики _well_? - PullRequest
7 голосов
/ 09 сентября 2008

Мне понравилась дискуссия на Различия в обобщениях , и мне было интересно, есть ли языки, которые использовали эту функцию особенно хорошо.

Мне действительно не нравится List<? extends Foo> в Java для List вещей, которые можно заменить на Лисков Foo. Почему List<Foo> не может это покрыть?

И, честно говоря, Comparable<? super Bar>?

Я также не могу вспомнить на всю жизнь, почему вы никогда не должны возвращать массив генериков:

public T[] getAll<T>() { ... }

Мне никогда не нравились шаблоны в C ++, но это было главным образом потому, что ни один из компиляторов никогда не мог выдать за них удаленно значимое сообщение об ошибке. Однажды я действительно make realclean && make 17 раз делал что-то для компиляции; Я так и не понял, почему 17-й раз был обаянием.

Итак, кому на самом деле нравится , использующим дженерики на родном языке?

Ответы [ 6 ]

14 голосов
/ 09 сентября 2008

Haskell довольно хорошо реализует параметризацию конструктора типов (обобщение или параметрический полиморфизм). Так же как и в Scala (хотя иногда требуется немного подержать).

Оба этих языка имеют типы более высокого класса (например, конструкторы абстрактных типов, или полиморфизм конструкторов типов, или полиморфизм высшего порядка).

См. Здесь: Обобщение высшего рода

7 голосов
/ 09 сентября 2008

Я думаю, что дженерики в Java на самом деле довольно хороши. Причина, по которой List<Foo> отличается от List<? extends Foo>, заключается в том, что когда Foo является подтипом Bar, List<Foo> не является подтипом List<Bar>. Если бы вы могли обрабатывать объект List<Foo> как List<Bar>, то вы могли бы добавить к нему Bar объекты, которые могли бы сломать вещи. Любая разумная система типов потребует этого. Java позволяет вам трактовать Foo[] как подтип Bar[], но это вызывает проверки во время выполнения, снижая производительность. Когда вы возвращаете такой массив, это затрудняет компилятору знать, нужно ли выполнять проверку во время выполнения.

Мне никогда не приходилось использовать нижние границы (List<? super Foo>), но я думаю, что они могут быть полезны для возврата общих значений. См. ковариация и контравариантность .

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

7 голосов
/ 09 сентября 2008

Черт, английский даже не очень хорошо реализует дженерики. :)

Мой уклон для C #. В основном потому, что это то, что я сейчас использую, и я использовал их для хорошего эффекта.

3 голосов
/ 09 сентября 2008

Я добавлю OCaml в список, в котором действительно универсальный универсальный шаблон. Я согласен, что классы типов в Haskell действительно хорошо сделаны, но немного отличается тем, что в Haskell нет семантики OO, но OCaml поддерживает OO.

1 голос
/ 09 сентября 2008

Я использую .Net (VB.Net), и у меня не было проблем с использованием дженериков. Это в основном безболезненно.

Dim Cars as List(Of Car)
Dim Car as Car

For Each Car in Cars
...
Next

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

0 голосов
/ 09 сентября 2008

Я думаю, что C # и VB.NET хорошо справляются с генериками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...