Каковы недостатки системы типов Java / C #? - PullRequest
6 голосов
/ 19 мая 2009

Часто слышно, что у Haskell (который я не знаю) очень интересная система типов ... Я очень хорошо знаком с Java и немного с C #, и иногда случается так, что я борюсь с системой типов так Некоторые конструкции вмещают или работают лучше определенным образом.

Это заставило меня задуматься ...

Какие проблемы возникают из-за недостатков системы типов Java / C #? Как вы справляетесь с ними?

Ответы [ 8 ]

8 голосов
/ 19 мая 2009

Массивы разбиты.

  Object[] foo = new String[1];
  foo[0] = new Integer(4);

Дает вам java.lang.ArrayStoreException

Вы относитесь к ним с осторожностью.

Nullability является еще одной большой проблемой. Исключения NullPointerException появляются везде. Вы действительно ничего не можете с ними сделать, кроме переключения языка или использования соглашений, позволяющих избегать их в максимально возможной степени (правильно инициализировать поля и т. Д.).

В целом, системы типов Java / C # не очень выразительны. Самое важное, что может дать Haskell, - это то, что с его типами вы можете обеспечить, чтобы у функций не было побочных эффектов. Наличие доказательства времени компиляции того, что части программ являются просто выражениями, которые оцениваются, делает программы намного более надежными, компонуемыми и более легкими для рассуждения. (Не обращайте внимания на тот факт, что реализации Haskell позволяют обойти это).

Сравните это с Java, где вызов метода может сделать почти все!

Также на Haskell есть сопоставление с образцом, которое дает вам другой способ создания программ; у вас есть данные о том, какие функции работают, часто рекурсивно. При сопоставлении с образцом вы уничтожаете данные, чтобы увидеть, какого они типа, и ведете себя в соответствии с ними. например У вас есть список, который либо пуст, либо голова и хвост. Если вы хотите вычислить длину, вы определяете функцию, которая говорит: если список пуст, длина = 0, иначе длина = 1 + длина (хвост).

Если вы действительно хотите узнать больше, есть два превосходных онлайн-источника:

Познакомьтесь с Haskell и Real World Haskell

5 голосов
/ 19 мая 2009

Мне не нравится тот факт, что существует различие между примитивными (нативными) типами (int, boolean, double) и их соответствующими классами-обертками (Integer, Boolean, Double) на Java.

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

private static <T> T First(T arg[]) {
    return arg[0];
}

public static void main(String[] args) {        
    int x[] = {1, 2, 3};
    Integer y[] = {3, 4, 5};

    First(x); // Wrong
    First(y); // Fine
}

В .NET таких проблем нет, хотя существуют отдельные значения и ссылочные типы, потому что они строго осознавали, что «все является объектом».

3 голосов
/ 20 мая 2009

этот вопрос о дженериках показывает недостатки выразительности системы типов Java
Дженерики высшего рода в Java

2 голосов
/ 19 мая 2009

Мне не нравится тот факт, что классы не являются первоклассными объектами, и вы не можете делать такие причудливые вещи, как статический метод, являющийся частью интерфейса.

1 голос
/ 17 октября 2012

Принципиальным недостатком системы типов Java / .net является то, что у него нет декларативных средств для определения того, как состояние объекта связано с содержимым его полей ссылочного типа, а также для указания того, какому методу разрешено сохранять ссылочные значения. параметры типа. Хотя в некотором смысле для среды выполнения хорошо иметь возможность использовать поле Foo одного типа ICollection<integer> для обозначения множества разных вещей, система типов не может обеспечить реальную поддержку таких вещей, как неизменяемость, проверка эквивалентности, клонирование или любые другие подобные функции, не зная, представляет ли Foo:

  1. Ссылка только для чтения на коллекцию, которая никогда не будет мутировать; класс может свободно делиться такой ссылкой с внешним кодом, не затрагивая его семантику. Ссылка инкапсулирует только неизменное состояние и, скорее всего, не инкапсулирует идентичность.
  2. Доступная для записи ссылка на коллекцию, тип которой является изменчивым, но который ничего не изменяет; класс может делиться такими ссылками только с кодом, которому можно доверять, чтобы не изменять его. Как указано выше, ссылка инкапсулирует только неизменное состояние и, вероятно, не инкапсулирует идентичность.
  3. Единственная ссылка во вселенной на коллекцию, которую она мутирует. Ссылка инкапсулирует изменяемое состояние, но не инкапсулирует идентичность (замена коллекции на другую, содержащую те же элементы, не изменит состояния включающего объекта).
  4. Ссылка на коллекцию, которую она мутирует, и чье содержимое она считает своей собственной, но к которой внешний код содержит ссылки, которые, как она ожидает, будут присоединены к текущему состоянию `Foo`. Ссылка будет инкапсулировать как идентичность, так и изменяемое состояние.
  5. Ссылка на изменчивую коллекцию, принадлежащую некоторому другому объекту, которую он ожидает присоединить к состоянию этого другого объекта (например, если объект, содержащий `Foo`, должен отображать содержимое некоторой другой коллекции). Эта ссылка инкапсулирует идентичность, но не инкапсулирует изменяемое состояние.

Предположим, что кто-то хочет скопировать состояние объекта, содержащего Foo, в новый отдельный объект. Если Foo представляет # 1 или # 2, в новом объекте можно сохранить либо копию ссылки в Foo, либо ссылку на новый объект, содержащий те же данные; копирование ссылки будет быстрее, но обе операции будут правильными. Если Foo представляет # 3, правильная отделенная копия должна содержать ссылку на новый отделенный объект, состояние которого копируется из оригинала. Если Foo представляет # 5, правильная отдельная копия должна содержать копию исходной ссылки - она ​​должна НЕ содержать ссылку на новый отдельный объект. И если Foo представляет # 4, состояние объекта, содержащего его, не может быть скопировано изолированно; может быть возможно скопировать группу взаимосвязанных объектов, чтобы получить новую группу, состояние которой эквивалентно оригиналу, но было бы невозможно скопировать состояние объектов по отдельности.

Хотя система типов не сможет декларативно указать все возможные отношения, которые могут существовать между объектами, и что следует с ними делать, система и структура типов должны иметь возможность правильно генерировать код для производить семантически правильные тесты эквивалентности, методы клонирования, гладко взаимодействующие изменяемые, неизменяемые и «читаемые» типы и т. д. в большинстве случаев, если известно, какие поля инкапсулируют идентичность, изменяемое состояние, оба или ни одного. Кроме того, должна быть возможность для каркаса минимизировать защитное копирование и перенос в обстоятельствах, когда она может гарантировать, что переданные ссылки не будут переданы чему-либо, что может их изменить.

0 голосов
/ 19 мая 2009

Ни у одного из них нет средств метапрограммирования, как, скажем, у старой чертовой собаки C ++.

Использование дублирования "using" и отсутствие typedef - один из примеров, который нарушает DRY и может даже вызывать пользовательские ошибки 'aliasing' и другие. «Шаблоны» Java даже не стоит упоминать ..

0 голосов
/ 19 мая 2009

Это незначительно, но для текущих версий Java и C # объявление объектов нарушает принцип DRY :

Object foo = new Object; 
Int x = new Int; 
0 голосов
/ 19 мая 2009

(в частности, Re: C #)

Я бы хотел помеченных союзов .

То же самое на первоклассных объектах для классов, методов, свойств и т. Д.

Хотя я никогда не использовал их, в Python есть классы типов , которые в основном являются типами, представляющими классы и их поведение.

Необнуляемые ссылочные типы, поэтому проверки на нуль не нужны. Первоначально он рассматривался для C #, но был отброшен. (В этом вопросе переполнение стека ).

Ковариация , поэтому я могу разыграть List<string> до List<object>.

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