Какие пять вещей ты ненавидишь в своем любимом языке? [закрыто]


403

В последнее время на Stack Overflow была куча Perl-ненависти, поэтому я решил перенести вопрос « Пять вещей, которые ты ненавидишь за свой любимый язык » в Stack Overflow. Возьми свой любимый язык и скажи мне пять вещей, которые ты ненавидишь в этом. Это могут быть вещи, которые вас просто раздражают, допущенные недостатки дизайна, признанные проблемы с производительностью или любая другая категория. Вы просто должны ненавидеть это, и это должен быть ваш любимый язык.

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

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

Мне все равно, какой язык вы используете. Не хотите использовать определенный язык? Тогда не надо. Вы проходите тщательную проверку, чтобы сделать осознанный выбор, и все еще не используете его? Хорошо. Иногда правильный ответ звучит так: «У вас сильная команда программистов с хорошими практиками и большим опытом работы в Bar. Переход на Foo будет глупым».


Это хороший вопрос и для обзоров кода. Люди, которые действительно знают кодовую базу, будут иметь всевозможные предложения для этого, и те, кто не знает это так хорошо, имеют неконкретные жалобы. Я спрашиваю: «Если бы вы могли начать этот проект заново, что бы вы сделали по-другому?» В этой фэнтезийной стране пользователи и программисты могут жаловаться на все, что им не нравится. «Мне нужен лучший интерфейс», «Я хочу отделить модель от представления», «Я бы использовал этот модуль вместо этого», «Я бы переименовал этот набор методов», или что бы они ни делали не нравится о текущей ситуации. Вот как я понимаю, что конкретный разработчик знает о кодовой базе. Это также подсказка о том, сколько программиста

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


11
Это действительно хороший ответ на старый вопрос «ваш любимый язык». Хорошее обоснование.
Том Лейс

14
Мне интересно, что, несмотря на то, что SO имеет большую аудиторию .NET, на момент написания этой статьи было 24 ответа, из которых только один (мой) касается .NET или языка .NET. Я понятия не имею, что это говорит о SO или .NET, но это интересно ...
Джон Скит

22
Первые 15 лет программирования на C / C ++ я ненавидел (в алфавитном порядке): 1. Указатели 2. Указатели 3. Указатели 4. Указатели 5. Указатели
ileon

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

3
Это фантастический вопрос. Если вам интересно, на что похож какой-то язык, прочитав 3 различных ответа об этом на этой странице, вы без труда сможете найти лучшую полезную информацию за потраченное время. Также отличный способ измерить уровень опыта (и смирения) программиста, если вы уже знаете язык.
j_random_hacker

Ответы:


182

Пять вещей, которые я ненавижу в Java:

  • Нет первоклассных функций.
  • Нет вывода типа.
  • Отсутствие нормальных значений по умолчанию, например, графики.
  • NullPointerException не содержит больше информации о том, что является нулем.
  • Распространение бессмысленно «настраиваемых» сред / интерфейсов поставщиков услуг / фабричных классов / систем внедрения зависимостей. Конфигурируемость почти никогда не используется, DRY грубо нарушается, а размер кода увеличивается в четыре раза, а разборчивость уменьшается вдвое.

Я знаю, я должен проверить Скала.


7
@both: NPE отображается в первой строке транса стека. Он содержит (в большинстве случаев) класс, имя файла Java и номер строки, например: «at your.faulty.code.Instance (Intance.java:1234)». Затем вы просто открываете этот файл, переходите к этой строке и там переменная, которой ничего не присвоено.
OscarRyz

35
@ Оскар Рейес - Э-э, мы это знаем. Но в этой строке может быть несколько переменных, и сообщение об исключении не говорит мне, какая из них пуста.
Зарконнен

10
У Скалы тоже есть бородавки. Тем не менее, он великолепно лучше, чем Java.
Wheaties

10
+1 за распространение фреймворков и т. Д.
Эрих Кицмюллер

6
@Valentin, просто представьте, как забавно, когда NullPointerException находится в гигантском лог-файле после ночного пробега, и вам нужно выяснить, что произошло ... Отладка - не вариант.
Торбьерн Равн Андерсен

216

Вау, я удивлен, что SQL еще не дошел до этого. Думаю, это означает, что никто не любит это :)

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

... и несколько бонусов, чтобы ненавидеть это, без дополнительной оплаты

  • предложение WHERE идет последним, что облегчает преждевременное выполнение UPDATE или DELETE, уничтожая всю таблицу. Вместо этого ГДЕ должно идти куда-то впереди.
  • Трудно реализовать реляционное деление.
  • Я могу установить значение NULL, но я не могу проверить его на равенство с NULL. Я могу проверить IS NULL, но это только усложняет код - без необходимости, на мой взгляд.
  • Почему нам нужно полностью переопределить формулу для столбца GROUPed, а не устанавливать псевдоним для столбца, а затем псевдоним GROUP BY (или индекс столбца, как при SORT)?

7
Возможно, никто не может научиться любить это, пока они не перестанут думать об этом как о языке. :)
Алан Мур

4
+1 за все. И все же люди задаются вопросом, почему я смирюсь с головными болями ORM ...
Джеймс Шек

2
@ Алан М ... разве это не то, что означает Л? :)
Кев

29
Я не могу понять, почему синтаксис INSERT так сильно отличается от UPDATE. И MERGE непостижимо.
LaJmOn

3
Необходимость IS NULL должна быть понятна, если вы считаете, что NULL - это третий возможный результат, сразу после TRUE и FALSE. Поскольку его значение «неизвестно», вы не можете сказать, соответствует ли что-то неизвестное другой вещи, которая тоже неизвестна. Другой пример: если NULL равен NULL, это будет означать, что вся концепция создания JOIN будет невозможной, поскольку любое значение NULL может быть сопоставлено с другим значением NULL. Если вы понимаете это (что также называется троичной логикой), вы можете понять причину введения оператора «IS» для тестирования на NULL.
Алекс

159

JavaScript :

  1. Все самые крутые вещи безумно сложны, но тогда вся крутость также обернута таким небольшим количеством кода, что вы чувствуете себя глупо, пытаясь следовать ему

  2. '+' - абсурдный выбор оператора для конкатенации в слабо типизированном языке. Они пытались отпугнуть новичков?

  3. Это минное поле совместимости с разными браузерами (неважно, включено оно или нет)

  4. Как правило, это ненадежно - связано с разборками, такими как блокировка кнопки «назад», всплывающие окна, которые никогда не умирают, и т. Д.

  5. Отладка практически невозможна, потому что есть только несколько разных сообщений об ошибках и несколько разных типов (Number, String, Object и т. Д.)

Если бы не JQuery, я бы все равно ненавидел его так же, как раньше :)


15
Я согласен с Mausch. ECMAscript сам по себе является красивым и мощным языком. Это надоедливые браузеры (: cough: IE) запутывают свое имя.
TJ L

32
@Mausch: где живет javascript в подавляющем большинстве случаев? Вы говорите, что это эквивалентно «автомобили не способствуют глобальному потеплению, а управляют машинами, которые делают это» - правда, конечно, но упускают суть - что еще вы делаете с машиной?
jTresidder

20
@Chris: Да, «+» - хороший оператор для конкатенации в строго типизированном языке (например, Python). В слабо типизированном языке (например, Javascript или C) это ужасно; он решает (молча!), что «сумма:» + 2 + 3 - это не «сумма: 5», а «сумма: 23». Кто-то с большим опытом Javascript может привести лучшие примеры.
ShreevatsaR

5
Да, C слабо типизирован по сравнению, скажем, с Python (например, вы можете присваивать целые числа chars, приводить что угодно к чему-либо с помощью указателей void * и т. Д.) Он статически типизирован вместо динамически типизированного, а также требует явной типизации вместо вывод типа, но они не связаны с сильной v / s слабой типизацией. [Случайные примеры: Python имеет неявную динамическую строгую типизацию, Haskell имеет (необязательно явную) статическую строгую типизацию, Java имеет явную (в основном статическую) строгую типизацию, C имеет явную статическую (относительно слабую) типизацию.] "Строго типизированный" и "слабо типизированный "на самом деле не четко определены.
ShreevatsaR

5
@ShreevatsaR The clasical примера: '3'+'2'='32', '3'-'2'=1.
Томас Але

148

PHP:

1) Заставляет меня делать ненужные переменные:

$parts = explode('|', $string);
$first = $parts[0];

2) Реализация lambdas, настолько хромая, что примерно эквивалентна использованию eval()и настолько ужасно неправильна, что я никогда не использовал ее (см. Http://www.php.net/create_function ).

3) Система try / catch, которая может отлавливать только около 80% возможных ошибок.

4) Поддержка Regex такая же хромая, как и лямбда-поддержка, потому что она должна быть написана внутри обычных строк, что делает один из самых сложных в освоении инструментов программирования примерно в три раза сложнее. И PHP должен быть «простым» языком?!?!?

5) Нет способа безопасно извлечь что-то из $ _POST, не написав его дважды, не создав собственную функцию или не используя оператор '@':

$x = isset($_POST['foo']['bar']) ? $_POST['foo']['bar'] : null;

6) Бонусный ответ: «@». Если вы не можете быть обеспокоены написанием своего кода правильно, просто добавьте '@', и это слишком плохо для тех, кому позже придется отлаживать ваш код.


44
как насчет list ($ first) = explode ('|', $ string); ?
Мларсен

44
В идеале я хотел бы использовать some_function (explode ('|', $ string) [0]);
слишком много php

8
Что за странная переменная область видимости? Хорошая идея - иметь все локальное и заставлять вас объявлять, когда вы хотите использовать глобальную переменную, она не позволяет нубам создавать функции, которые просто используют глобальные переменные, а не используют аргументы и возвращаемые значения, как они должны это делать.
Scragar

24
вы забыли о функциях с произвольным изменением порядка параметров
dusoft

39
Вы забыли о verbNoun, verb_noun, noun_verb, nounverb, verbnoun, nounVerb и т. Д.> _>
Warty

135

C ++

  • Слишком легко случайным образом повредить память и создать почти невозможные для поиска ошибки (хотя, Valgrind проходит долгий путь к исправлению этой ошибки ).
  • Шаблон сообщений об ошибках.
  • При использовании шаблонов легко в конечном итоге включить все в один файл, а затем получить глупые времена компиляции.
  • Стандартная библиотека - шутка в современную эпоху (по-прежнему нет потоков или сети по умолчанию?)
  • Множество неприятных маленьких кусочков C, проходящих через (в частности, все преобразования между short / int / unsigned / etc ..)

13
Я согласен с STL, но я скажу , что это есть очень хорошо.
Бернард

22
юникода. Я уважаю простоту Асии, но ради всего святого, мы сейчас в 21-м веке.
Вильгельмтель

29
@Kieveli const правильность - это одна из вещей, которые мне больше всего не хватает при программировании на других языках. особенно динамически типизированные. raii - большая особенность, которую я тоже часто скучаю.
Вильгельмтелл

6
Большинство проблем C ++ связано с тем, что они являются стандартом ISO и заблокированы на 10 лет.
graham.reeds

7
+1 "Шаблон сообщений об ошибках."
Жоао Портела

129

C # / .NET:

  • Классы должны быть запечатаны по умолчанию
  • Не должно быть никаких lockутверждений - вместо этого у вас должны быть определенные блокирующие объекты, и должны быть такие методы, Acquireкоторые возвращают одноразовые маркеры блокировки. Следствие: не должно быть монитора для каждого объекта.
  • GetHashCode()и Equals()не должно быть System.Object- не все подходит для хеширования. Вместо этого, иметь IdentityComparerкоторый делает то же самое, и держать IComparer<T>, IComparable<T>, IEqualityComparer<T>и IEquatable<T>интерфейсы для пользовательских сравнений.
  • Слабая поддержка неизменности
  • Плохой способ обнаружения методов расширения - это должно быть гораздо более осознанное решение, чем просто тот факт, что я использую пространство имен.

Это было с моей головы - спросите меня завтра, и я приду к другому 5 :)


22
Запечатано по умолчанию: наследование должно быть либо спроектировано как класс (который требует времени и ограничивает будущие возможности), либо запрещено. hashCode / equals: это плохо и в Java. Однажды я напишу длинный пост в блоге об этом. Прочитайте Эффективную Java для подробностей о том, почему равно сложно в цепочках наследования.
Джон Скит

88
Запечатывание по умолчанию означает, что вы подумали о любой возможной причине, по которой кто-то захочет унаследовать от вашего класса, и вы не думаете, что какая-либо из них имеет смысл. Извините, но никто из нас не такой умный.
Эд С.

69
В этом случае я не достаточно умен, чтобы вы могли извлечь из моего кода: потому что я не могу предсказать, какие будущие изменения, которые я мог бы внести, могут испортить ваш код. Это очень серьезная проблема, ИМО. Запечатывание кода является более ограничительным, но приводит к большей свободе реализации и надежности.
Джон Скит

11
Я не могу поверить, что никто не упомянул синтаксис "goto case", я его ненавижу!
Aistina

20
Хорошо, что Джон Скит не проектировал C #, или мой список выглядел бы так: «1. классы запечатаны по умолчанию; 2. блокировка слишком сложна; 3. большинство объектов не являются хэшируемыми»!
Гейб

113

С

  • манипуляции со строками

Необходимость иметь дело с строковыми буферами вручную является склонной к ошибкам болью. Поскольку большое количество вычислений действительно перемещает и модифицирует строки (компьютеры не так часто используются для обработки больших чисел, как люди думали, что они когда-то вернутся назад), очень приятно иметь возможность использовать управляемые языки или строку C ++ объекты для борьбы с этим. Когда я должен сделать это в прямом C, это похоже на плавание в зыбучих песках.


50
Согласовано. Манипулирование
строками

1
Просто используйте безопасную библиотеку строк DJB или что-то в этом роде. Манипулирование XML сложно в большинстве языков, и многие программы делают XML-манипуляции, но вы не видите много постов, говорящих: «Perl полностью сломан, потому что он не поддерживает DOM-узлы как примитивный тип данных». Они используют библиотеку.
Стив Джессоп

5
Манипулирование C-строкой - отстой, но что касается языковых проблем, то это не самое страшное.
Крис Латс

3
strcat для объединения, но подождите ... места назначения достаточно ... хорошо, нужно вставить оператор if для проверки ... но подождите, что если моя строка находится в куче? Хорошо, нужно хранить переменную, чтобы отслеживать размер ... И это может продолжаться и продолжаться ...
blwy10

4
Нам нужна тема для пяти вещей, которые мы не ненавидим в C ...
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

94

Как насчет пяти вещей, которые я ненавижу в списках «Вещи, которые я ненавижу в каком-то языке»? : D

5 - Оранжевый красный не делает его яблоком.

Когда проектируется язык, дизайнеры обычно имеют в виду, для чего он нужен. Использование этого для чего-то совершенно другого может работать, но жаловаться, когда это не так, просто глупо. Возьми Питона. Я уверен, что или кто-то имеет, или кто-то когда-нибудь сделает утилиту для создания exe-файлов из кода Python. Почему на земле Бога вы хотите это сделать? Это было бы аккуратно - не поймите меня неправильно - но это бесполезно. Так что перестаньте жаловаться на это!

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

4- Вы стоите на деревянных ногах?

Платформа может оказать большое влияние на то, что может сделать язык. В настоящее время сборщики мусора, или даже ранняя попытка «сбора мусора» в паскалях, могут помочь в исчезновении памяти (может быть, malloc больше оперативной памяти ??). Компьютеры работают быстрее и, конечно, мы ожидаем большего от наших языков. И, честно говоря, мы, вероятно, должны. Однако за удобство компилятора приходится платить огромную цену за создание хеш-таблиц или строк, а также за множество других концепций. Эти вещи не могут наследоваться той платформе, на которой они используются. Сказать, что их легко включить в язык, просто говорит мне, что у вас может не быть ноги, на которой можно стоять.

3- Кто виноват, это правда?

Ошибок. Знаешь. Я люблю жуков. Почему я люблю жуков. Потому что это значит, что я могу сохранить свою работу. Без ошибок было бы много закрытых пиццерий. Однако пользователи ненавидят ошибки. Но вот небольшой всплеск холодной воды. Каждая ошибка - ошибка программистов. Не язык. Язык с таким строгим синтаксисом, который значительно уменьшил бы количество возможных ошибок, был бы совершенно бесполезным языком. Его способности, вероятно, можно посчитать с одной стороны. Вы хотите гибкости или власти? У вас есть ошибки. Почему? Потому что ты не идеален, и ты совершаешь ошибки. Возьмите действительно идентифицируемый пример в C:

int a[10];
for (int idx = 0; idx < 15; idx++) a[idx] = 10;

Мы все знаем, что будем делать. Однако, возможно, некоторые из нас не осознают, что ... функциональность может быть очень полезной. В зависимости от того, что вы делаете. Переполнение буфера - это стоимость этой функциональности. Этот код выше. Если бы я действительно выпустил это для публики. Это опять .. скажи это со мной .. "Моя вина". Не С за то, что позволил мне это сделать.

2- Разве мы не должны положить это в корзину?

Очень просто указать на функцию на языке, который мы не понимаем, потому что мы не используем его часто и называем его глупым. Пожаловаться, что он есть и т. Д. Гото всегда развлекает меня. Люди всегда жалуются на то, что Гото говорит на языке. Тем не менее, держу пари, что ваша последняя программа включала в себя тип goto. Если вы когда-либо использовали перерыв или продолжение, вы использовали goto. Это и есть. Конечно, это «безопасный» переход, но это то, что есть. У Гото есть свое применение. Используются ли «неявные» gotos, такие как continue или break, или явные gotos (с использованием фактического ключевого слова «goto» для любого языка). Не то, чтобы разработчики языка были безупречны, но обычно ... если функциональность существовала с незапамятных времен (для этого языка). Вероятно, этот аспект является определяющим качеством этого языка. Смысл .. это ' s используется и, вероятно, не зависает из-за обратной совместимости. Это используется сегодня. Как и 5 минут назад. И используется правильно. Ну ... возможно, кто-то использует его ненадлежащим образом, но это относится к # 3 в моем списке.

1. - Все является объектом.

Хорошо ... это действительно подмножество # 2. Но это самая раздражающая жалоба, которую я вижу в списках ненависти. Не все это объект. Существует множество концепций, которые не принадлежат или не должны быть объектами. Размещать вещи там, где они не принадлежат, просто безобразно и может снизить эффективность программы. Конечно. Может быть, не так много, в зависимости от языка. Это также относится к № 5. Это значит ... да. Глобал в порядке. Функции в отличие от статических методов в порядке. Объединение ОО-программирования с глобальными функциями - это нормально. Теперь ... это не значит, что мы все должны выйти и "освободить" наш код от его объектных моделей. При разработке раздела кода или целого проекта то, что происходит за кулисами, должноследует учитывать при составлении его вместе. Мало того, где живет эта концепция и многие другие факторы. Зачем заключать глобальные функции в классы или концепции пространства имен, если это не имеет смысла? Возьмите статические переменные-члены. Это очень забавляет меня, потому что .. хорошо .. В зависимости от языка и реализации, конечно, но в целом вы только что объявили глобальным. Да, есть несколько причин, чтобы обернуть эти не-OO-концепции в OO-оболочки. Одним из них является самодокументированный код. Это может иметь смысл. Так .. как я и говорю. Не выходите и «освободите» свой код. Но любой хороший современный язык будет иметь глобальную концепцию вне ОО-моделирования. Да, я специально хочу указать, что язык программирования ОО без глобальной концепции, скорее всего, имеет серьезный недостаток в дизайне. Опять же, хотя .. зависит от намерения и дизайна языка, поэтому я не пытаюсь выбрать какой-то конкретный язык, и здесь слишком много, чтобы проанализировать его. В любом случае, подумайте, где код должен жить и быть наиболее эффективным. Добавление вспышки к чему-то, что не добавляет функциональности или поддержки, просто изнашивает клавиатуру быстрее. Это никому не приносит пользы. Ну ... если вам не нравятся очки брауни от человека, который, вероятно, неправильно учил вас, что все является объектом.

Короче говоря, программирование - это не просто бездумное нажатие на клавиатуру. Есть много конструктивных соображений для любого проекта. Я знаю, что это клише, но вы должны смотреть на это со всех сторон. Даже с современными типобезопасными языками. Вы не просто бросаете код и ожидаете, что он будет работать хорошо. Конечно ... это может сработать, но это может быть неправильный путь. В целом, выберите язык и формат, который лучше всего подходит для конкретной работы И окружающей среды. Но ни один язык не отнимает мысли, стоящие за этим. Если вы не думаете .. вы просто печатаете.


19
Языки не идеальны, и если вы составите список того, что вам не нравится в языке, вы можете получить интересные комментарии и идеи. Во-первых, это позволяет другим предлагать вам решения, о которых вы не знали (просмотрите посты, вы увидите, что некоторые вещи были изучены). Во-вторых, он представляет собой обратную связь с пользователями для разработчиков языка (разве вам не интересно, если ваши пользователи придумали список из 5 вещей, которые они больше всего ненавидят в вашем программном обеспечении?), И, в-третьих, интересно подумать над недостатками. ваших инструментов.
Сильвердраг

4
Если вы просматриваете его на этом уровне, не только break и continue являются goto, но и циклами являются goto (переходите в начало цикла, если выполняется условие), если выполняется goto (если условие не выполняется, перепрыгивайте через блок, вызовы функций goto (перейти к началу функции, а затем вернуться назад), ...
гелий

17
Создание исполняемых файлов из исходного кода «бесполезно»? Какая?
детально

4
Perl может создавать исполняемый файл из файла Perl с конца 80-х годов. Одна вещь для распространения полезна. Не нужно а) устанавливать Perl, б) устанавливать компоненты программы, в) возможно, писать скрипт для установки путей и выполнения всего этого ... Да, действительно бесполезно.
xcramps

1
Но если вы не можете создать .exe-файлы из источника, пользователи Windows не смогут его запустить. ;)
Эван Плейс

88

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

  1. Несмотря на то, что я фанат Java Generics, есть много странностей, которые возникают из-за того, как он был спроектирован. Таким образом, существует множество раздражающих ограничений с помощью дженериков (некоторые из которых являются результатом стирания типа).
  2. Принцип работы Object.clone () и интерфейсов Cloneable полностью нарушен.
  3. Вместо того, чтобы идти по шоссе и делать все объектами (например, SmallTalk), Sun освободилась от создания двух разных категорий типов данных: объекты и примитивы. В результате теперь есть два представления для фундаментальных типов данных и странных курьезов, таких как бокс / распаковка и невозможность поместить примитивы в коллекцию.
  4. Качели слишком сложны. Не поймите меня неправильно: с Swing можно сделать много классных вещей, но это отличный пример чрезмерного проектирования.
  5. Эта последняя жалоба в равной степени является ошибкой Sun и тех, кто написал XML-библиотеки для Java. Библиотеки Java XML слишком сложны. Чтобы просто прочитать XML-файл, мне часто приходится беспокоиться о том, какой анализатор я использую: DOM или SAX? API для каждого одинаково сбивает с толку. Нативная поддержка языка для простого разбора / написания XML была бы очень хорошей.
  6. дата отстой. Это не только излишне сложно, но и все полезные методы устарели (и заменены другими, которые увеличивают сложность).

32
Вы забыли о java.util.Date!
ТМ.

3
Также: интерфейс «Cloneable» не имеет метода «clone ()». Это делает интерфейс Cloneable оксюмороном. И так как clone () возвращает Object, безопасность типов выходит за пределы окна (не делается никаких попыток исправить это, даже после того, как Generics были введены в J2SE 5.0).
Райан Делукки

2
Пока мы клонируем клонируемость, может также включать так называемый Serializable «интерфейс». Всякий раз, когда я использую его, я всегда хочу нанести удар себе.
WDS

12
Трудно делать простые вещи, такие как открыть файл и прочитать из него.
Эрик Джонсон

3
@Ryan clone () не обязательно должен возвращать «Object». С J2SE 5.0 Java представила ковариантные возвращаемые типы, что означает, что вы можете возвращать любой подтип базового класса. Так что публичный клон MyType () возможен!
helpermethod

73

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

  • Замыкания (блоки) имеют 4 различных синтаксиса создания, и ни один из них не является оптимальным. Элегантный синтаксис неполон и неоднозначен с хешами, а полный синтаксис уродлив.
  • Сообщество склонно против реальной документации, предпочитая «читать код». Я нахожу это детским и ленивым.
  • Злоупотребление метапрограммированием, особенно в библиотеках, превращает ошибки в кошмар.
  • В связи с этим, повсеместное метапрограммирование делает комплексную IDE трудной, если не невозможной, для создания.
  • Способ передачи блока в функции глупый. Нет причин, по которым блоки должны передаваться за пределы списка параметров или иметь странный специальный синтаксис для доступа (yield). Я придерживаюсь мнения, что блокам должен был быть задан менее неоднозначный синтаксис (или хэши могли бы использовать разные разделители; возможно, <>, а не {}), и передача в качестве параметров в методы должна была быть такой же, как и все другие параметры.

    object.method(1, {|a| a.bar}, "blah")
    

    Эти странности, такие как блок должен быть последним переданным параметром, и передача более одного блока отличается с более длинным синтаксисом, действительно раздражают меня.


2
неоптимальная поддержка m17n & unicode, хотя становится все лучше. 1.9 остается сложным ...
Keltia

37
Я думал, что злоупотребление метапрограммированием называется "идиоматическим рубином" :)
Slartibartfast

2
akway: два других синтаксиса - лямбда и Proc.new .
Мирддин Эмрис

2
Что касается документации, я однажды услышал разговор кого-то, работающего в издательстве Pragmatic Programmers, который сказал, что когда компания была основана, они хотели книгу на Ruby, потому что единственная доступная книга была на японском языке. Таким образом, они могли бы перевести и издать эту книгу своей компанией. Но что они вместо этого сделали, что читать исходный код :-) Книга Ruby была, по-видимому, одной из книг, которые запустили Pragmatic Programmers.
Артур Рейтенауэр

13
Мне интересно, что 3 из них связаны с людьми, а не с самим языком. Руби остается языком, который я ненавижу меньше всего.
Тоби Хеде

72

Perl

  • Смешанное использование сигил

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = $array[0]; # not @array[0], you would get the length instead
    my $four = $array->[0]; # definitely not $array[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = @$array[1,2]; # coerce to array first
    
    my $length_a = @array;
    my $length_s = @$array;
    
    my $ref_a = \@array;
    my $ref_s = $array;
    
    • Например, ни один из них не одинаков:

      $array[0]   # First element of @array
      @array[0]   # Slice of only the First element of @array
      %array[0]   # Syntax error
      $array->[0] # First element of an array referenced by $array
      @array->[0] # Deprecated first element of @array
      %array->[0] # Invalid reference
      $array{0}   # Element of %array referenced by string '0'
      @array{0}   # Slice of only one element of %array referenced by string '0'
      %array{0}   # Syntax error
      $array->{0} # Element of a hash referenced by $array
      @array->{0} # Invalid reference
      %array->{0} # Deprecated Element of %array referenced by string '0'
      

    В Perl6нем написано :

    my @array = ( 1, 2, 3 );
    my $array = [ 4, 5, 6 ];
    
    my $one  = @array[0];
    my $four = $array[0]; # $array.[0]
    
    my( $two,  $three ) = @array[1,2];
    my( $five, $six   ) = $array[1,2];
    
    my $length_a = @array.length;
    my $length_s = $array.length;
    
    my $ref_a = @array;
    my $ref_s = $array;
    
  • Отсутствие истинного OO

    package my_object;
    # fake constructor
    sub new{ bless {}, $_[0] }
    # fake properties/attributes
    sub var_a{
      my $self = shift @_;
      $self->{'var_a'} = $_[0] if @_;
      $self->{'var_a'}
    }
    

    В Perl6нем написано :

    class Dog is Mammal {
        has $.name = "fido";
        has $.tail is rw;
        has @.legs;
        has $!brain;
        method doit ($a, $b, $c) { ... }
        ...
    }
    
  • Плохо разработанные функции регулярных выражений

    /(?=regexp)/;           # look ahead
    /(?<=fixed-regexp)/;    # look behind
    /(?!regexp)/;           # negative look ahead
    /(?<!fixed-regexp)/;    # negative look behind
    /(?>regexp)/;           # independent sub expression
    /(capture)/;            # simple capture
    /(?:don't capture)/;    # non-capturing group
    /(?<name>regexp)/;      # named capture
    /[A-Z]/;                # character class
    /[^A-Z]/;               # inverted character class
    # '-' would have to be the first or last element in
    # the character class to include it in the match
    # without escaping it
    /(?(condition)yes-regexp)/;
    /(?(condition)yes-regexp|no-regexp)/;
    /\b\s*\b/;              # almost matches Perl6's <ws>
    /(?{ print "hi\n" })/;  # run perl code
    

    В Perl6нем написано :

    / <?before pattern>  /;   # lookahead
    / <?after pattern>   /;   # lookbehind
    / regexp :: pattern  /;   # backtracking control
    / ( capture )        /;   # simple capture
    / $<name>=[ regexp ] /;   # named capture
    / [ don't capture ]  /;   # non-capturing group
    / <[A..Z]>           /;   # character class
    / <-[A..Z]>          /;   # inverted character class
    # you don't generally use '.' in a character class anyway
    / <ws>               /;   # Smart whitespace match
    / { say 'hi' }       /;   # run perl code
    
  • Отсутствие многократной отправки

    sub f(   int $i ){ ... }  # err
    sub f( float $i ){ ... }  # err
    sub f($){ ... } # occasionally useful
    

    В Perl6нем написано :

    multi sub f( int $i ){ ... }
    multi sub f( num $i ){ ... }
    multi sub f( $i where $i == 0 ){ ... }
    multi sub f(     $i ){ ... } # everything else
    
  • Плохая перегрузка оператора

    package my_object;
    use overload
      '+' => \&add,
      ...
    ;
    

    В Perl6нем написано :

    multi sub infix:<+> (Us $us, Them $them) |
                        (Them $them, Us $us) { ... }
    

5
Я не вижу недостатка в настоящем ОО столь же плохом, как вы это делаете. Иногда это спасение, особенно когда используемый вами модуль CPAN не задумывался о том, что вам нужно. И отсутствие множественной отправки могло бы быть хуже: perl мог бы быть строго напечатан ;-)
Tanktalus

3
Мне нравится, что Perl не является строго типизированным, но было бы полезно добавить некоторую информацию о типах.
Брэд Гилберт

13
Кажется, вы решили критиковать язык, который вам не нравится (вы должны были критиковать perl6)
Фрю Шмидт,

5
Какой смысл сравнивать с Perl 6? Вы предлагаете, чтобы Perl 6 исправил ваши проблемы или продолжил их?
Роберт П

2
Я сомневаюсь, что мне нужно сказать больше, чем: ozonehouse.com/mark/periodic
Арафангион

57

Я буду делать PHP так, как мне нравится, и Python будет слишком много.

  • Нет пространства имен; все в каком-то очень большом пространстве имен, которое ад в больших средах

  • Отсутствие стандартов в отношении функций: функции массива принимают иглу в качестве первого аргумента, стог сена - в качестве второго (см. Array_search ). Строковые функции часто берут стог сена первым, а иголку вторым (см. Стр. ). Другие функции просто используют разные схемы именования: bin2hex , strtolower , cal_to_jd

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

    $var = preg_match_all('/regexp/', $str, $ret);
    echo $var; //outputs the number of matches 
    print_r($ret); //outputs the matches as an array
    
  • Язык (до PHP6) делает все возможное , чтобы уважать почти-отсталый обратную совместимость, что делает его носить плохие методы и функции вокруг , когда не требуется (см mysql_escape_string против mysql_real_escape_string ).

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

  • Это отстой при импорте файлов. У вас есть 4 различных способа сделать это (включая, include_once, require, require_once), все они медленные, очень медленные. На самом деле весь язык медленный. По крайней мере, довольно медленно, чем Python (даже с фреймворком) и RoR из того, что я собираю.

Я все еще люблю PHP, хотя. Это цепная пила веб-разработки: вы хотите, чтобы сайт от маленького до среднего выполнялся очень быстро и был уверен, что кто-нибудь может его разместить (хотя конфигурации могут отличаться)? PHP прямо здесь, и он настолько вездесущ, что требуется всего 5 минут для установки полного стека LAMP или WAMP. Ну, я сейчас вернусь к работе с Python ...


4
Я полагаю, что пункт 1 реализован в 5.3 :). В то время как упорядочивание параметров улучшается, именование все еще оставляет желать лучшего. Я согласен с обратной совместимостью, хотя.
Росс

4
Должен любить # 4. Это одна из вещей, которая беспокоила меня больше всего тоже.
Франц

1
Я думаю, что аргумент скорости довольно субъективен. Скорость зависит в большей степени от того, насколько эффективен код, чем от самого языка. Плохой PHP-код, вероятно, медленнее, чем высококачественный Python-код, но хороший PHP может также работать лучше, чем плохой Python.
selfawaresoup

17
no_really_now_mysql_escape_the_string_im_serious ()
Зарплата

2
пространства имен schmamespaces. PHP находится во всемирной паутине, поэтому все должно быть глобально
Эван Плейс

50

Вот некоторые вещи, которые мне не нравятся в Java (это не мой любимый язык):

  • Стирание типа дженериков (т.е. никаких дженериков нет)
  • Невозможность отловить несколько исключений (разных типов) в одном блоке перехвата
  • Отсутствие деструкторов (finalize () - очень плохая замена)
  • Отсутствие поддержки замыканий или обработки функций как данных (анонимные внутренние классы являются очень многословной заменой)
  • Проверка исключений в целом или, более конкретно, проверка неустранимых исключений (например, SQLException)
  • Нет языковой поддержки для литеральных коллекций
  • Отсутствие вывода типов при вызове конструкторов универсальных классов, т. Е. Параметр (ы) типа должен повторяться по обе стороны от '='

1
@Svish - Я думаю, дело в том, что вы будете использовать эту конструкцию только тогда, когда вам все равно, с каким типом исключения вы имеете дело. Другими словами, когда вы хотите обращаться со всеми одинаково
Dónal

3
Я бы не назвал недостаток деструкторов недостатком, когда в языке есть GC и GC, которые становятся все лучше и лучше с каждым выпуском. Деструкторы были пропущены в java 1.1.8, но не в java 6, потому что gc значительно улучшен.
Майк Риделл

7
C # исправляет все это, кроме перехвата нескольких исключений. Обобщаются дженерики, деструкторы заменяются с помощью / IDisposable, замыкания реализуются анон-методами и лямбдами, исключения не проверяются, есть литералы коллекций, и есть «var», чтобы избежать указания составного типа дважды.
Дэниел Эрвикер

1
У Java определенно есть замыкания. Анонимный внутренний класс закрывается поверх локальных конечных переменных в своей области видимости. Я согласен, что анонимные внутренние классы не являются надлежащей заменой анонимных функций, но они являются замыканиями.
Адам Яскевич

2
Внутренние классы Anon НЕ являются замыканиями: попробуйте создать обратный вызов посетителя с чем-то вроде «sum + = current.amount ()», где «sum» - неконечная переменная из включающей области видимости. Близко, но не сигара.
Roboprog

40

C ++

  1. Синтаксис шаблона
  2. Проблемы наследования бриллиантов
  3. Изобилие / отсутствие стандартных библиотек, которые есть в современных языках (хотя повышение уже близко).
  4. IOStreams
  5. Синтаксис, используемый вокруг IOStreams

питон

  1. Пробелы имеют смысл (иногда)
  2. ключевые слова с подчеркиванием
  3. Ограниченная поддержка потоков (по крайней мере, в настоящее время)
  4. «я» вместо «это»
  5. Пробелы имеют смысл (иногда)

80
Вы можете ссылаться на «себя» как на «это», которое вы действительно хотите (хотя другим может быть трудно следовать). «Self» не является ключевым словом, и вы можете назвать переменную как угодно.
Mipadi

36
вот, пожалуйста, я бы на самом деле перечислил значимость пробелов (особенно отступов) в Python как один из его самых больших плюсов ...;)
Оливер Гизен

22
«пробелы значимы» - одна из лучших особенностей Python! ps попробуй запустить это в интерпретаторе "из будущих импортных скобок"
hasen

4
Я не согласен с почти всем вашим списком Python, кроме поддержки потоков. Пробел не имеет смысла, отступ имеет смысл; есть большая разница
Кристиан Удард

3
Ух ты. Как будто никто не изобрел текстовый редактор, который выделяет / показывает пробелы / табуляции как специальные символы (Что, вы кодируете в блокноте?). Кроме того, если вы расширяете вкладки до пробелов, пожалуйста, умри в огне.
Фальшивое имя

37

Objective-C

1) Нет пространств имен, только соглашения по именованию вручную - я не против этого с точки зрения разделения классов, но мне не хватает возможности импортировать все определения классов в пространстве имен в одну строку (например, import com.me.somelibrary. *).

2) В библиотеках все еще есть дыры в важных областях, таких как поддержка RegEx.

3) Синтаксис свойства немного неуклюжий, требующий три строки (в двух отдельных файлах) для объявления свойства.

4) Мне нравится модель сохранения / выпуска, но легче выпустить ссылку, а затем случайно использовать ее позже.

5) Хотя Xcode на самом деле не является языковой функцией, она настолько переплетена с использованием Objective-C, что я не могу не думать об этом аспекте ... в основном автозаполнение очень сомнительно. Это больше похоже на систему, которая вознаграждает вас за то, что вы нашли то, что вы хотите, существует, а затем представляет это как выбор. Но тогда я полагаю, что мне никогда не нравились двигатели с автозаполнением.


2
Согласитесь насчет пространств имен, префикс классов с буквенными кодами тупой. И я бы добавил недостающую поддержку для переменных реального класса, мне не нравится подделывать их статическими файлами.
zoul

2
Свойства Objective-C. Серьезно, они шокируют, я не могу понять шумиху, особенно видя, насколько хорошо C # делает их.
Юстиция

6
На самом деле мне очень понравился этот аспект Lisp и ObjC - вам просто нужен редактор с хорошим соответствием скобок, такой как Emacs или XCode. Обычно я набираю фигурные скобки в парах, прежде чем что-либо вводить в них, поэтому у меня не возникает проблем с сопоставлением ... и XCode может также выделить область, заключенную в фигурную скобку, просто дважды щелкнув по любой из них, содержащей фигурную скобку.
Кендалл Хельмштеттер Гелнер

1
@Chris S: Вы говорите, что YES/NOдля логических выражений это плохо? И что более важно, вы говорите, что именованные параметры - это плохо? Я могу понять bools, но именованные параметры, возможно, являются одной из лучших функций ObjC (с точки зрения читабельности).
Джбреннан

3
Может быть, я мазохист, но мне нравятся имена классов с префиксами. Это делает поиск в Google и документах кристально чистым, и нет никакой путаницы в том, какую строку вы используете, если класс называется NSString.
Куби

36

C ++

  • Строки.
    Они не совместимы со строками платформы, поэтому в итоге вы используете std :: vector половину времени. Политика копирования (копирование при записи или глубокое копирование) не определена, поэтому нельзя дать гарантии производительности для простого синтаксиса. Иногда они полагаются на алгоритмы STL, которые не очень интуитивно понятны в использовании. Слишком много библиотек катят свои собственные, которые, к сожалению, намного более удобны в использовании. Если вы не должны объединить их.

  • Разнообразие строковых представлений
    Теперь, это небольшая проблема с платформой - но я все еще надеюсь, что было бы лучше, если бы менее упрямый стандартный класс строк был бы доступен ранее. Следующие строковые представления, которые я часто использую:

    • универсальный LPCTSTR,
    • LPC (W) STR, выделенный CoTaskMemAlloc,
    • BSTR, _bstr _t
    • (Ж) строка,
    • CString,
    • станд :: вектор
    • класс roll-my-own ( sigh ), который добавляет проверку диапазона и базовые операции в буфер (w) char * известной длины
  • Построить модель.
    Я до смерти устал от того, что все время тратился на перепутывание с кем-то, что-то, предварительными декларациями, оптимизацией предварительно скомпилированных заголовков и включений, чтобы поддерживать переносимость как минимум добавочного времени сборки и т. Д. Это было здорово в восьмидесятых, но сейчас? Есть так много препятствий для упаковки кода, чтобы его можно было использовать повторно, чтобы даже маме собаке стало скучно слушать меня.

  • Трудно анализировать
    Это делает внешние инструменты особенно сложными для написания и получения правильных результатов. И сегодня нам, ребятам из C ++, в основном не хватает цепочки инструментов. Я люблю свое отражение в C # и делегатов, но я могу жить без них. Без большого рефакторинга я не могу.

  • Потоки слишком сложны.
    Язык даже не распознает их (на данный момент), и свободы компилятора - хотя и велики - слишком болезненны.

  • Статическая инициализация и инициализация по требованию. Технически, я обманываю здесь: это еще одна часть головоломки в «коде повторного использования»: это кошмар, чтобы получить что-то инициализированное только тогда, когда это необходимо. Лучшее решение всех других проблем с переадресацией - это бросить все в заголовки, эта проблема говорит: «Нет, вы не можете».


Конечно, многое из этого выходит за рамки строгой языковой компетенции, но IMO весь инструментарий необходимо оценивать и развивать.


Смотреть документацию по STL - это все равно, что искать руководства по созданию видеокарты с нуля.
Aviraldg

Честно говоря, большинство из этих пунктов звучат так, как будто вы никогда не удосужились изучить C ++ должным образом ... это становится довольно очевидным в # 3, так как защита включения - это то, что должен знать каждый программист C ++. Я не уверен, как понять пункт № 1, вы смущены std::string? может быть, чтение хорошей документации и / или учебника std::vector(и почему вы не должны использовать его std::stringв местах, для которых он никогда не был предназначен) может прояснить это для вас.

@nebukadnezzar: Я нашел Мейерса освещающим STL, но это не решает фундаментальных проблем. Честно говоря, это звучит так, как будто вам никогда не приходилось поддерживать большой проект, вам никогда не приходилось выслеживать круговую зависимость в иерархии включающих десятки глубин. Я знаю, включают охранников, но почему мы должны беспокоиться с ними? КСТАТИ. они не решают все проблемы. Насколько «стандартен», std::stringесли я не могу использовать его половину времени? (C ++ 0x по крайней мере исправляет это, но я все еще застрял с десятками библиотек, которые используют различные строковые представления).
peterchen

but why do we have to bother with them (inclusion guards)- потому что C ++ не имеет модулей. How "standard" is a std::string if I can't use it half of the time?- Я думаю, это зависит от того, как вы используете std::string. Строковый класс позволяет вам получить доступ к строковым данным как const char*через std::string::c_str, что уже делает его std::stringполностью совместимым с каждым классом / функцией, которая также принимает const char*аргументы.

потому что C ++ не имеет модулей - именно моя жалоба: модель сборки является устаревшей (я бы просто принял любое другое решение, кроме модулей). ----- отлично совместимо - но совершенно несовместимо со многими другими сценариями (я бы сказал, что исправление C ++ 0x говорит о том, что у меня здесь есть смысл.) Я был бы счастлив, если бы std :: string был достаточно распространенным, чтобы были приняты в качестве струнного класса 10 лет назад, но это не было - другая жалоба.
peterchen

35

JavaScript :

  • ObjectПрототип может быть изменен. Каждый отдельный объект в вашей программе получает новые свойства, и, возможно, что-то ломается.

  • Все объекты являются хеш-картами, но их безопасно использовать как таковые. В частности, если один из ваших ключей окажется __proto__, у вас проблемы.

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

    • Следствие: вызов функции без обозначения объекта или newоператора приводит к тому, thisчто его значение устанавливается равным глобальному объекту, что приводит к значительному повреждению.
  • Оператор сложения перегружен для выполнения конкатенации строк, несмотря на то, что эти две операции принципиально различаются. Причиняет боль, когда значение, которое вы ожидаете получить, на самом деле является строкой.

  • ==и !=операторы выполняют приведение типов. Сравнения между различными типами включают список правил, которые ни один смертный не может запомнить полностью. Это смягчается наличием ===и !==операторов.

  • И то, nullи другое undefinedсуществует, с немного разными, но лишними значениями. Почему?

  • Странный синтаксис для настройки цепочек прототипов.

  • parseInt(s)ожидает число в стиле C, поэтому рассматривает значения с начальными нулями как восьмеричные и т. д. Вы можете, по крайней мере, parseInt(s, 10)но поведение по умолчанию сбивает с толку.

  • Нет области видимости блока.

  • Может объявлять одну и ту же переменную более одного раза.

  • Может использовать переменную, не объявляя ее, в этом случае она является глобальной и, вероятно, нарушает вашу программу.

  • with { },

  • Действительно сложно документировать с помощью инструментов, подобных JavaDoc.


3
Для nullи undefined: иногда вы действительно хотите знать, было ли переменной присвоено значение или нет. Поскольку null - это значение, undefined - единственный способ определить это. Конечно, единственный раз, когда я нашел это полезным, было создание функций получения / установки.
Зак

1
«если один из ваших ключей оказывается прото », - это зарезервированное слово со специальным значением. это все равно что жаловаться, что вы не можете использовать forв качестве имени переменной.
Ник

5
@nickf: ключом к хешу является строка. Строки могут иметь любое значение, включая зарезервированные слова. В частности, значение "for"допустимо в качестве хеш-ключа. __proto__не зарезервированное слово Специальные строковые значения, которые не работают должным образом при использовании в качестве ключей хеша, нарушают разумные ожидания о том, как ассоциативные массивы работают на любом языке. Они также нарушают спецификацию EcmaScript.
Даниэль Кэссиди

2
Томас: Newline не всегда заканчивает утверждение. Поэтому разумные кодеры завершают каждое утверждение точкой с запятой, чтобы сделать код более понятным.
Дэниел Кэссиди,

2
newline may or may not end a statement depending on contextэто один из моих 5 лучших списков
reinierpost

34

Python:

  • Отсутствие статической типизации
  • Обработка аргументов по умолчанию (в частности, тот факт, что вы можете изменить аргумент по умолчанию по для будущих абонентов!)
  • Слишком много обязательных подчеркиваний (нужно вызывать конструкторы __init__ )
  • Отсутствие надлежащих закрытых членов и функций (соглашение просто говорит, что большинство вещей, которые начинаются с подчеркивания, являются частными, за исключением всего, что __getattr__ что не так)
  • Забавный синтаксис для printзагрузки в файл (но они исправляют это в Python 3)

10
То, что я хотел бы, это возможность использовать статические типы.
Грег Хьюгилл

4
Кстати: init на самом деле не конструктор, объект уже был создан, когда вы входите туда (угадайте, что такое self ...). Конструктор является совершенно новым, когда вы получаете доступ к классу, который будет создан.
Андре

90
Если вы предпочитаете статическую типизацию, почему Python ваш любимый язык?
Finnw

9
finnw: Статическая типизация отлично подходит для некоторых типов программ и не нужна для других типов. Я обычно не против отсутствия статической типизации, но когда вам это нужно, очень приятно иметь хотя бы такую ​​возможность.
Грег Хьюгилл

8
Я бы сказал, что отсутствие статической типизации является функцией, а не отсутствующей функциональностью ...
arnorhs

32

C #

  • Я хотел бы switch()на любой тип, и это caseможет быть любое выражение.

  • Нельзя использовать синтаксис инициализатора объекта с полями «только для private setчтения» / autoprops. Как правило, мне нужна языковая помощь в создании неизменяемых типов.

  • Использование {}для пространства имен и класса, а также метода и блоков свойств / индексаторов, блоков с несколькими операторами и инициализаторов массива. . Трудно понять, где вы находитесь, когда они далеко друг от друга или не соответствуют друг другу.

  • Я ненавижу писать (from x in y ... select).Z(). Я не хочу возвращаться к синтаксису вызова метода, потому что в синтаксисе запроса что-то отсутствует.

  • Я хочу doпункт о синтаксисе запроса, который похож foreach. Но тогда это не совсем вопрос.

Я действительно достигаю здесь. Я думаю, что C # - это фантастика, и трудно найти что-то сломанное.


14
1 для включения любого типа
oɔɯǝɹ

+1 за проблемы с переключателем и {} проблемы, о которых я до сих пор не задумывался
Маслоу

Я ненавижу {}. Они выглядят слишком похоже на (). Несовпадение никогда не было большой проблемой для меня, потому что я всегда ставлю их на одном уровне, если они не являются в основном однострочными.
Лорен Печтел

2
+1 за запрос linq. Особенно, когда вы хотите вернуть только один объект. Вместо (из x в y выберите) .first (), почему бы не (из x в y выбрать top 1) или что-то, чтобы приблизиться к фактическому синтаксису sql.
AdmSteck

если вы хотите, чтобы вы могли переключаться () на любой тип, и в этом случае можно использовать любое выражение, проверяющее соответствие шаблону F #. c-sharpcorner.com/UploadFile/mgold/…
gradbot

26

PHP

  1. Нет функций отладки, если вы не контролируете сервер, и даже тогда они отстой
  2. Огромное количество плохого PHP-кода дает плохое имя всем программистам PHP
  3. Непоследовательная функция именования
  4. Невозможность иметь статическую типизированную переменную, если я хочу ее (я большой поклонник динамической типизации 90% времени)
  5. REGISTER_GLOBALS это дьявол

25
REGISTER_GLOBALS однажды съел мою собаку :(
Pim Jager

2
1: я рекомендую xdebug и клиент с графическим интерфейсом, такой как MacGDBp. Это действительно облегчает некоторые боли ... Я согласен с другими моментами.
Йонас Дуэ Вестерхеден

5
# 2: Боже, не начинай меня с этого. Я всегда должен защищаться как разработчик PHP от людей, которые видели только тот беспорядок, который многие создают с помощью PHP.
selfawaresoup

1
+1 за # 2 Я потратил слишком много времени на то, чтобы защитить себя как разработчика PHP.
UnkwnTech

+1 за №2 - приводит и к плохой зарплате :(
Шики

25

C (хорошо, это не мой любимый, но это еще не было сделано.)

  • Синтаксис библиотеки сокетов.
  • Нет перегрузки функции.
  • Струны в стиле C
  • Переполнение буфера.
  • Загадочный синтаксис. Я не знаю, сколько раз я смотрел такие вещи, как атой, хлопал себя по лбу и кричал "Конечно!"

РЕДАКТИРОВАТЬ: я мог бы, вероятно, придумать больше, если бы я прибегнул к большему количеству библиотечного кода (как я сделал с сокетами, но это особенно плохо), но я уже чувствовал, что я обманывал для выбора на C. Так много языков существует только для хорошие части C и заменить плохие, что это похоже на избиение мертвой лошади.


22
Какой синтаксис сокета? С не имеет понятия о сокетах.
Ферруччо

3
О, да ладно! Вы можете придумать пять. Разве указатель арифметики просто не сосет? :)
Брайан Д. Фой

8
+1 Я смеялся над «струнами в стиле С». И @brain_d_foy: арифметика указателей - отстой, только если вы этого не понимаете.
Крис Латс

1
@Chris Luts: Даже когда я изучал простой C (прежде чем я знал C ++ или любой другой язык OO), я просто знал, что с массивами символов что-то не так. :)
Билл Ящерица

2
арифметика указателей - это силовая пила - очень эффективная, но вы рискуете забрать всю ногу
Торбьерн Равн Андерсен

24

Common Lisp:

  1. Ключевые слова часто слишком многословны.
  2. Поддержка библиотеки жалкая.
  3. Не работает в ОС, которые хотят более строго обрабатывать память.
  4. Не имеет хороших возможностей для взаимодействия с ОС.
  5. Средство "loop" не очень хорошо определено, и, конечно, не выглядит Lispy.

2
'loop' может быть не шустрым, но что плохо определено в этом?
Дэниел Кэссиди

2
Я не читал стандарт сам, я в основном собираюсь на Пол Грэхема "На Лиспе". Он говорит, что стандарт - это, в основном, примеры, и он плохо определяет угловые случаи.
Дэвид Торнли

3
Вы не имеете в виду ключевые слова слишком многословны?
GClaramunt

Я согласен с тем, что это не «шутка», но CLtLv2 тратит на это много времени. Я просто думаю, что он был разработан, чтобы делать слишком много. sunsite.univie.ac.at/textbooks/cltl/clm/…
Ханс Ван Слоотен

В дополнение к «loop», «format» также не очень похож на Lisp. Я ненавижу "форматировать" и "зацикливать" оба, хотя Лисп - мой любимый язык.
Пол Рейнерс

24

BrainF * ск

  • Ваш основной момент в том, что вы завершили сборку ? Я могу сделать больше в регулярных выражениях Perl!

  • Отсутствие предметов. Да ладно, люди! Это как, привет ...

  • Нет сетевых библиотек. Все, что я хочу, это очистить веб-страницу, GOSH.

  • Нет первоклассных функций. Поздравляем - вы можете поболтать с друзьями по Java.

  • Бесконечная лента для хранения и ничего больше. Это настолько анально претенциозно, что мы могли бы также написать Лисп.


6
Там нет пространства имен или поддержки динамического модуля. Как можно ожидать написания систем управления химическими заводами без таких основ?
Donal Fellows

Нет синтаксического сахара, такого как> 10 (переместить 10 раз), 0 (вставить ноль), +5 (добавить 5).
Шквал

23

JavaScript

  1. числа как строки - Математика может расстраивать, когда числа интерпретируются как строки. 5 + 2 = 52? Хмм ...
  2. разрешения - все самое лучшее требует разрешения от пользователя!
  3. обновления экрана - браузер должен находиться в устойчивом состоянии для обновления экрана. Кажется, нет способа заставить экран обновляться в середине скрипта.
  4. Медленно - хотя Google Chrome хорош ...
  5. Различия в браузерах делают использование языка [цензурированным].

4
Числа в виде строк легко исправить. Если у вас когда-либо есть строка, вам нужно проанализировать ее (x, 10). Гигантский сбой происходит, когда вы пропускаете, 10, и он интерпретирует «017» как OCTAL
Orion Edwards

3
false == 0 == [] == "", но null и NaN - нет. NaN! = NaN. ноль == ноль.
Джимми

7
typeof "строка" == "строка". typeof new String ("another string") == "object. new String ('a'). constructor ==" a ".constructor. typeof new Array () == 'object'
Джимми

1
for (x в объекте) возвращает функции
Джимми

14
-1, этот список в основном касается проблем браузера, а не самого языка.
Маурисио Шеффер

20

PHP:

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

Тем не менее PHP является (сценарии) языком. ;-)


ОК, только еще одна вещь, чтобы пойти!
Брайан Д. Фой

4
Полностью согласен с пунктом 5 - тоже будет в списке Javascript.
Стив Кларидж

Я не согласен со «всеми бедными программистами, которые не учатся тому, как заставить его работать должным образом, и называют его дурным именем». Я бы заменил его на «огромный выбор параметров конфигурации языка выполнения».
L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳

18

VB6

  1. Только для Windows
  2. Больше не поддерживается.
  3. Массивы могут начинаться с любого числа, а не нормализоваться до 0.
  4. скомпилированные приложения зависят от того, как многие DLL работают правильно.
  5. Многие сложные элементы управления, такие как элемент управления браузера или сложные фрагменты кода, имеют тенденцию нарушать IDE, когда вы запускаете код без компиляции, но прекрасно работают при компиляции.

13
VB чей-то любимый язык? O_o. Почему здесь не «синтаз, который полностью отличается от других языков» и «дает вредные привычки по отношению к другим языкам»?
Джонта

3
Я на самом деле считаю # 3 очень мощной функцией, а не ошибкой - я бы очень хотел, чтобы VB.NET имел это. В некотором смысле это есть в AWK, но в массивах AWK это действительно замаскированные хеши :(
Джо Пинеда,

3
На 1 и 4 и .NET C # не требуется ПОЛНАЯ РАМКА и операционная система ??? (эй, я слышал, что вы моно фанатик ... это все еще "полная структура" для вас, и я сомневаюсь, что Debian Dist когда-либо его съест). Что касается 5, ни один правый программист VB6 (в
прошлом) не оставил

2
Все равно придется периодически поддерживать vb6. Любимые ошибки: невозможно инициализировать переменную при объявлении, нет параметризованных конструкторов, один класс на файл и т. Д. Если они решат эти проблемы, язык может продолжаться еще 10 лет.
AngryHacker

14
Как насчет «On Error Resume Next» ... это все равно что сказать «этот код F ** KED, но все равно продолжаем его запускать. =)
StingyJack

18

Ruby - мой любимый язык, вот что мне не нравится:

  • Зеленые потоки + блокировка библиотек C = гигантский сбой
  • ТАК БЕЗУМНО МЕДЛЕННО
  • Сама стандартная библиотека несовместима с использованием взрыва! методы
  • Модуль включает в себя + расширение является грязным.
  • «Открытые классы» не могут быть ограничены - я хочу добавить String # dostuff, но я не хочу, чтобы это просачивалось во все сторонние библиотеки
  • Нет бинарного решения для развертывания пакетов.

3
Вы пробовали Ruby 1.9.1? Он предлагает значительное ускорение по сравнению с Ruby 1.8.6
Кристиан Штаде-Шульдт

Попробуйте jrubyc. JVM JIT FTW!
KitsuneYMG

+1 за включение разумных проблем, в отличие от «ненависти» от ответа Ruby с самым высоким рейтингом.
Phrogz

17

Delphi:

  • IDE немного нестабильна.
  • Понимание кода иногда путается.
  • Отладка иногда глючит.
  • Обновление нескольких файлов проекта может быть громоздким.
  • При запуске, когда один или несколько пакетов недоступны, сообщение об ошибке появляется несколько раз.

5
Кажется, что все это жалобы на Delphi IDE, а не на Delphi язык (AKA Object Pascal)
Dónal

11
Предположительно, это потому, что Object Pascal совершенен ;-)
Марк Бесси

3
Я немного опоздал на вечеринку, но в любом случае здесь: - необходимость дважды записывать сигнатуры методов (интерфейс + реализация) - ТРЕБУЕТСЯ, чтобы имя модуля было идентичным имени файла. WTF?!?
Мартин

1
Я считаю, что начало .. заканчивается лучше - они намного понятнее, чем {}. Вы тратите намного больше времени на чтение кода, чем на его написание. Однако для краткости - вы не можете использовать определенные поддиапазоны перечислимых типов в случае, даже если это совершенно законно, если вы объявляете диапазон прямо в этом случае. Кроме того, нет прямых ссылок между единицами.
Лорен Печтел

1
@ АлександрN: Нет, он никогда не был таким живым, популярным или великим.
Андреас Рейбранд

16

JavaScript

  • Каждый сценарий выполняется в едином глобальном «пространстве имен» ... то, на что вы должны обращать внимание при работе со сценариями из разных источников.

  • Если переменная используется, но не была определена ранее, она считается глобальной переменной

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

  • Чувствительность к регистру - учитывая, что не существует достойной IDE для разработки js с проверкой во время компиляции

  • Обходные пути (например, использование hasOwnPropertyметода) для выполнения некоторых, в противном случае простых операций.


AFAIK, все расширения языка JS (не DOM) от производителей браузеров, по крайней мере, были вынуждены принять стандарт, даже если процесс стандартизации не смог этого добиться. hasOwnProperty / обходные пути: обоюдоострый меч. Чтобы заставить «простоту», мы теряем много силы и гибкости. Эта жалоба всегда меня бесит. Пишите свои циклы правильно (и проверяйте членов вашего объекта тоже правильно)!
век

15

Haskell:

  1. Космические утечки из ленивой оценки.
  2. Числовая иерархия не построена с учетом математических абстракций.
  3. Строгое монадическое IO может затруднить отладку.
  4. Большие реализации обрабатывают ввод / вывод способами, которые не совсем совместимы со стандартом. (В частности, при выводе символов выводятся только младшие 8 битов, а затем создается код, который использует это предположение для выполнения двоичного ввода-вывода. Ick.)
  5. Ассоциативность ($)оператора может быть изменена, чтобы сделать некоторые выражения более красивыми.

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

Изменить: Там было некоторое замешательство по поводу пункта 5. В частности, некоторые люди, кажется, думают, что я имел в виду порядок аргументов, а я нет. Вместо того, чтобы объяснять, что я имел в виду, я просто укажу людям на следующую ссылку: http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity , которая хорошо это выражает.


3
Почему вы хотите изменить ассоциативность ($)? 'fghx' заключает в скобки как '((fg) h) x' и 'f $ g $ h $ x', заключает в скобки как 'f (g (hx))' ...
Эрик Хесселинк,

1
Я <3 Хаскелл. Стандартная библиотека должна включать горы математических абстракций, включая векторные пространства и др. Прелюдия также нуждается в операторе, который цепочек похож на ($), но слева направо {source |> func1 |> filter func2 |> map (func3 10)}.
yfeldblum

10
Вы пропустили действительно плохое: склонность программистов на Haskell использовать имена переменных из одной буквы.
Бенджамин Конфино

1
Левый ассоциативный ($) оператор - это просто приложение функции, которое в Хаскеле представлено символом пробела. @ Справедливость: попробуйте функцию флип. (|>) = flip ($)
Apocalisp

1
Может кто-нибудь объяснить суть # 5? Я думал, что правильная ассоциативность - это весь смысл ($).
Тим Мэтьюз
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.