Существуют ли какие-либо языки, которые _хорошо_ реализуют дженерики?

StackOverflow https://stackoverflow.com/questions/50983

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

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

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

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

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

Это было полезно?

Решение

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

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

Глянь сюда: Дженерики высшего типа

Другие советы

Я думаю, что дженерики в 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, вероятно, облегчат вам эту задачу, хотя их сообщения об ошибках также могут сбивать с толку.

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

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

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

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

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

For Each Car in Cars
...
Next

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top