Что вам не нравится в вашем любимом языке?
В последнее время существовал кластер Perl-ненависти в переполнении стека, поэтому я подумал, что принесу свой " Пять вещей, которые вы ненавидите в своем любимом языке" для. Возьмите свой любимый язык и расскажите мне пять вещей, которые вы ненавидите. Это могут быть вещи, которые просто раздражают вас, допускают недостатки дизайна, признанные проблемы с производительностью или любую другую категорию. Вам просто нужно ненавидеть это, и это должен быть ваш любимый язык.
Не сравнивайте его с другим языком и не говорите о языках, которые вы уже ненавидите. Не говорите о том, что вам нравится на вашем любимом языке. Я просто хочу услышать то, что вы ненавидите, но терпите, чтобы вы могли использовать все другие вещи, и я хочу услышать его о языке, который вы хотели бы использовать другими людьми.
Я спрашиваю об этом, когда кто-то пытается навязать мне свой любимый язык, а иногда и вопрос о интервью. Если кто-то не может найти пять вещей, чтобы ненавидеть его любимый инструмент, он не знает его достаточно хорошо, чтобы либо защищать его, либо использовать большие доллары, используя его. Он не использовал его в достаточно разных ситуациях, чтобы полностью изучить его. Он защищает его как культуру или религию, а это значит, что если я не буду выбирать свою любимую технологию, я ошибаюсь.
Мне все равно, какой язык вы используете. Не хотите использовать определенный язык? Тогда нет. Вы выполняете должную осмотрительность, чтобы сделать осознанный выбор и по-прежнему не использовать его? Хорошо. Иногда правильный ответ: "У вас есть сильная команда разработчиков с хорошей практикой и большим опытом работы в баре. Переход на Foo был бы глуп".
Это хороший вопрос для обзоров кода. Люди, которые действительно знают кодовую базу, будут иметь для этого всевозможные предложения, а те, кто этого не знает, имеют нестандартные жалобы. Я спрашиваю: "Если бы вы могли начать с этого проекта, что бы вы сделали по-другому?" В этой фантастической стране пользователи и программисты жалуются на что угодно и все, что им не нравится. "Я хочу лучший интерфейс", "Я хочу отделить модель от представления", "Я бы использовал этот модуль вместо этого другого", "Я бы переименовал этот набор методов" или что бы они ни делали Не нравится нынешняя ситуация. Вот как я понимаю, насколько конкретный разработчик знает о кодовой базе. Это также подсказка о том, как много программиста эго связано с тем, что он говорит мне.
Ненависть - это не единственное измерение выяснения того, насколько люди знают, но я нашел, что это довольно хороший. То, что они ненавидят, также дает мне понять, насколько хорошо они думают о предмете.
Ответы
Ответ 1
Пять вещей, которые я ненавижу в Java:
- Нет первоклассных функций.
- Нет вывода типа.
- Отсутствие нормальных значений по умолчанию, например, графики.
- NullPointerException не содержит больше информации о том, что равно null.
- Распространение бессмысленно "настраиваемых" инфраструктур/интерфейсов поставщика услуг / factory классов/систем впрыска зависимостей. Конфигурируемость почти никогда не используется, DRY нарушается вопиюще, а код в четыре раза по размеру и пополам в удобочитаемости.
Я знаю, я должен проверить Scala.
Ответ 2
Ничего себе, я удивлен тем, что SQL пока не сделал этого. Угадайте, что это значит, что никто не любит это:)
- Несогласованный синтаксис во всех реализациях
- Тонкие различия в коде могут иметь серьезные последствия для кажущихся неясными причин.
- Плохая поддержка текстовых манипуляций
- Легкая стоимость входа, но крутая кривая обучения для овладения языком.
- Минимальная стандартизация в сообществе для лучших практик, включая стиль синтаксиса.
... И несколько бонусных причин ненавидеть его, без дополнительной оплаты
- предложение WHERE продолжается, что позволяет преждевременно выполнять UPDATE или DELETE, уничтожая всю таблицу. Вместо этого ГДЕ должно идти куда-то впереди.
- Трудно реализовать реляционное деление.
- Я могу установить значение NULL, но я не могу проверить его на равенство с NULL. Я могу проверить IS NULL, но это просто усложняет код - как ни крути, на мой взгляд.
- Почему нам нужно полностью отразить формулу для столбца GROUPed, а не устанавливать псевдоним в столбце, а затем GROUP BY псевдоним (или индекс столбца, как и для SORT)?
Ответ 3
JavaScript
-
Все самые крутые вещи безумно сложны, но тогда вся холодность также завершается в таком небольшом количестве кода, что вы считаете глупым, чтобы бороться за него.
-
'+' - абсурдный выбор оператора для конкатенации на слабо типизированном языке. Они пытались отпугнуть нобов?
-
Это кросс-браузерное совместимое минное поле (неважно, включено ли оно или нет)
-
Обычно он не доверен - связан с scummery, например, блокировкой кнопки "назад", всплывающих окон, которые никогда не умирают, и т.д.
-
Отлаживать его почти невозможно, потому что есть только несколько сообщений об ошибках и несколько разных типов (Number, String, Object и т.д.)
Если бы не jQuery, я бы, вероятно, все еще ненавидел его так же, как и раньше:)
Ответ 4
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) Бонусный ответ: '@'. Если вы не можете беспокоиться о правильном написании кода, просто добавьте "@" и слишком плохого для тех, кто должен отлаживать ваш код позже.
Ответ 5
C++
- Слишком легко случайным образом испортить память и создать почти невозможные ошибки (хотя Valgrind имеет большое значение фиксируя это).
- Сообщения об ошибках шаблонов.
- При использовании шаблонов легко в конечном итоге включить все в один файл, а затем получить глупое время компиляции.
- Стандартная библиотека - шутка в современную эпоху (по умолчанию нет нитей или сети?)
- Много неприятных маленьких кусков C, пробивающих (в частности, все преобразования между short/int/unsigned/etc..)
Ответ 6
С#/.NET:
- Классы должны быть закрыты по умолчанию.
- Не должно быть оператора
lock
, вместо этого у вас должны быть определенные объекты блокировки, и должны быть такие методы, как Acquire
, которые возвращают одноразовые блокировки токенов. Следствие: не должно быть монитора для каждого объекта.
-
GetHashCode()
и Equals()
не должны находиться в System.Object
- не все, что подходит для хэширования. Вместо этого выполните IdentityComparer
, что делает то же самое, и сохраните интерфейсы IComparer<T>
, IComparable<T>
, IEqualityComparer<T>
и IEquatable<T>
для пользовательских сопоставлений.
- Плохая поддержка неизменности
- Плохой способ обнаружения методов расширения - это должно быть гораздо более осознанное решение, чем просто тот факт, что я использую пространство имен.
Те были у меня в голове - спросите меня завтра, и я придумаю другой 5:)
Ответ 7
С
Необходимость ручного управления буферами строк - это подверженная ошибкам боль. Поскольку так много вычислений действительно перемещается и модифицирует строки (компьютеры не используются так же сильно для большого количества хрустящих вещей, как люди думали, что они вернутся назад), очень приятно иметь возможность использовать управляемые языки или строку С++ объекты для решения этих проблем. Когда мне приходится делать это прямо в С, то это похоже на плавание в зыбучих песках.
Ответ 8
Как насчет пяти вещей, которые я ненавижу в списках "Вещи, которые я ненавижу в отношении некоторых языков"?: D
5- Картина оранжевого красного не делает ее яблоком.
Когда язык разработан, дизайнеры обычно имеют в виду, для чего это полезно. Использование его для чего-то совершенно другого может работать, но жаловаться, когда это не так, просто глупо. Возьмите Python. Я уверен, что кто-то или кто-то когда-нибудь сделает утилиту для создания exe из кода Python. Почему на земле вы хотели бы этого сделать? Это было бы аккуратно, не поймите меня неправильно, но это бесполезно. Поэтому перестаньте жаловаться на это!
Хорошо спроектированный проект, скорее всего, содержит код с нескольких языков. Это не значит, что вы не можете завершить проект только на одном языке. Некоторые проекты могут быть в пределах возможностей любого языка, который вы используете.
4- Вы стоите на деревянных ногах?
Платформа может быть большим влиянием того, что может сделать язык. С сегодняшними сборщиками мусора или даже даже паскалями ранняя попытка "сбора мусора" может помочь в исчезновении памяти (может быть, malloc больше ram?). Компьютеры быстрее и, конечно же, мы ожидаем большего от наших языков. И, честно говоря, мы, вероятно, должны это сделать. Тем не менее, существует огромная плата за удобство компилятора для создания хэш-таблиц или строк или множества других концепций. Эти вещи могут не наследоваться на платформе, из которой они используются. Сказать, что их легко включить в язык, просто говорит мне, что у вас может не хватить ноги.
3 Кто это на самом деле?
Bugs. Вы знаете. Я люблю ошибки. Почему я люблю ошибки. Потому что это означает, что я должен выполнять свою работу. Без ошибок было бы много закрытых магазинов пиццы. Однако пользователи ненавидят ошибки. Но вот небольшой всплеск холодной воды. Каждая ошибка - ошибка программистов. Не язык. Язык с таким строгим синтаксисом, который значительно уменьшил бы количество ошибок, которые могли быть созданы, был бы совершенно бесполезным языком. Вероятно, его способности можно было бы подсчитать с одной стороны. Вам нужна гибкость или сила? У вас есть ошибки. Зачем? Потому что вы не идеальны, и вы совершаете ошибки. Возьмем действительно идентифицируемый пример в C:
int a[10];
for (int idx = 0; idx < 15; idx++) a[idx] = 10;
Мы все знаем, что это будет делать. Однако, возможно, некоторые из нас не понимают, что эта функциональность может быть очень полезной. В зависимости от того, что вы делаете. Стоимость переполнения буфера - это стоимость этой функции. Этот код выше. Если бы я действительно опубликовал это для публики. Это снова.. скажи это со мной.. "Моя вина". Не C, чтобы позволить мне это сделать.
2- Не следует ли помещать это в корзину?
Очень легко указать на функцию на языке, который мы не понимаем, потому что мы не часто его используем и называем его глупым. Жалуйтесь, что это там и так. Goto всегда развлекайте меня. Люди всегда жалуются на то, что перешли на язык. Тем не менее, я уверен, ваша последняя программа включала тип goto. Если вы когда-либо использовали перерыв или продолжение, вы использовали goto. Что это такое. Конечно, это "безопасный" переход, но это то, что есть. Получите их использование. Используются ли "неявные" gotos, такие как continue или break, или явные gotos (используя фактическое ключевое слово "goto" для любого языка). Не то, что разработчики языка безупречны, но обычно... если функциональность существует с самого начала (для этого языка). Вероятно, этот аспект является определяющим качеством этого языка. Значение.. оно используется и, вероятно, не висит вокруг из-за обратной совместимости. Это используется сегодня. Как и 5 минут назад. И используется правильно. Ну.. возможно, кто-то использует его неправильно, но это относится к № 3 в моем списке.
1. - Все это объект.
Хорошо. Это действительно подмножество # 2. Но это самая неприятная жалоба, которую я вижу в списках ненависти. Не все - объект. Существует множество концепций, которые не принадлежат или должны быть объектами. Помещение вещей, где они не принадлежат, просто уродливое и может снизить эффективность программы. Конечно. Возможно, не так много в зависимости от языка. Это также относится к №5. Это значит... да. Глобально все в порядке. Функции, связанные с статическими методами, в порядке. Совмещение программирования OO с глобальными функциями в порядке. Теперь.. это не значит, что мы все должны выйти и "освободить" наш код от него объектными моделями. При разработке раздела кода или целого проекта следует учитывать, что происходит за кулисами, при объединении. Не только там, где живет эта концепция, и многие другие факторы. Зачем включать глобальные функции в классы или концепции пространства имен, если это нецелесообразно? Возьмите статические переменные-члены. Это очень меня забавляет, потому что... ну.. В зависимости от языка и реализации, конечно, но, вообще говоря, вы просто объявили глобальным. Да, есть несколько причин, чтобы обернуть эти концепции, отличные от OO, в обертках OO. Один из них, конечно, самодокументирующий код. Это может иметь смысл. Так... как я говорю. Не выходите и не "производите" свой код. Но любой хороший современный язык будет иметь глобальную концепцию вне модели OO. Да, я специально хочу отметить, что язык программирования OO без глобальной концепции, скорее всего, имеет серьезный недостаток в дизайне. Опять же, хотя.. зависит от намерения и дизайна языка, поэтому я не пытаюсь выбрать какой-либо конкретный язык, и здесь слишком много для анализа. Anywho, подумайте, где код должен жить и быть наиболее эффективным. Добавление куча вспышки к чему-то, что не добавляет функциональности или поддержки, просто ускоряет работу клавиатуры. Это никому не помогает. Ну.. если вам не нравятся точки коричневого цвета от человека, который, вероятно, неправильно учил вас, что все это объект.
Короче говоря, программирование не просто бездумно постукивает по клавиатуре. В любом проекте есть много конструктивных соображений. Я знаю это клише, но вы должны смотреть на него со всех сторон. Даже с сегодняшними типами безопасных языков. Вы не просто выкидываете код и ожидаете, что он будет работать хорошо. Конечно.. это может сработать, но это может быть неправильный путь. В целом выберите язык и формат, которые лучше всего подходят для конкретной работы и среды. Но ни один язык не отнимает за этим мысли. Если вы не думаете... вы просто печатаете.
Ответ 9
Пять вещей, которые я ненавижу в Java (который в настоящее время является моим любимым языком) в определенном порядке.
- Насколько я являюсь поклонником Java Generics, существует множество странностей, которые возникают из-за того, как он был разработан. Таким образом, существует множество досадных ограничений с помощью дженериков (некоторые из которых являются результатом стирания типа).
- Поведение объектов Object.clone() и Cloneable полностью нарушено.
- Вместо того, чтобы идти по дорожке и делать все на одном объекте (a.la. SmallTalk), Sun не смог создать две разные категории типов данных: объекты и примитивы. В результате в настоящее время существуют два представления для фундаментальных типов данных и странных курьезов, таких как бокс/распаковка и невозможность поместить примитивы в коллекцию.
- Свинг слишком сложный. Не поймите меня неправильно: есть много классных вещей, которые можно сделать с Swing, но это отличный пример сверхтехнического развития.
- Эта окончательная жалоба также является ошибкой Sun и тех, кто написал XML-библиотеки для Java. Библиотеки Java XML слишком сложны. Чтобы просто читать в XML файле, мне часто приходится беспокоиться о том, какой парсер я использую: DOM или SAX? API для каждого одинаково запутывает. Родная поддержка в языке для легко разбора/написания XML была бы очень приятной.
- java.util.Date отстой. Это не только излишне сложно, но и все полезные методы устарели (и заменены другими, что усложняет).
Ответ 10
Ruby имеет много недостатков, связанных с его скоростью, но я их не ненавижу. У него также есть недостатки, когда общинное евангелизация выходит за борт, но это меня действительно не беспокоит. Это то, что я ненавижу:
- Closures (blocks) имеет 4 разных синтаксиса создания, и ни один из них не является оптимальным. Элегантный синтаксис является неполным и неоднозначным с хэшами, а полный синтаксис уродлив.
- Сообщество, как правило, против реальной документации, предпочитая "читать код". Я нахожу это детским и ленивым.
- Нарушение метапрограммирования, особенно в библиотеках, делает ошибки кошмаром для отслеживания.
- В соответствующей заметке повсеместное метапрограммирование делает сложную, если не невозможную, комплексную IDE.
-
Путь, передаваемый блоку, выполняется глупо. Нет никаких причин, по которым блоки должны быть переданы за пределами списка параметров или иметь нечетный специальный синтаксис для доступа (yield). Я полагаю, что блокам следовало бы дать менее двусмысленный синтаксис (или хеши могли использовать разные разделители, возможно, < > а не {}), а передача в качестве параметров методов должна была точно так же, как и все другие параметры.
object.method(1, {|a| a.bar}, "blah")
Эти странности, такие как блок, должны быть последним переданным параметром и пропускать более одного блока с более сильным синтаксисом, действительно раздражают меня.
Ответ 11
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;
-
Например, none из них те же:
$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 <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) { ... }
Ответ 12
Я буду делать PHP, когда мне это нравится, и Python будет слишком много.
-
Нет пространства имен; все в
вид очень большого пространства имен, которое
ад в более крупных средах
-
Отсутствие стандартов, когда дело доходит до
функции: функции массива принимают
игла в качестве первого аргумента, стога сена
как второй (см. array_search).
Строковые функции часто принимают
стог сена сначала, игла вторая (см.
strpos). Другие функции просто
используйте различные схемы именования:
bin2hex, strtolower,
cal_to_jd
Некоторые функции имеют странный возврат
значения, из нормального: это
заставляет вас иметь третью переменную
объявлен из ниоткуда, в то время как PHP
может эффективно интерпретировать пустую
массив как false с его типом
жонглирование. Рядом нет других
функции выполняют то же самое.
$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).
-
Язык, исходящий из
язык шаблонов
полный-backend один. Это означает, что кто-либо
может выводить что угодно, когда захочет,
и он получает злоупотребление. Вы в конечном итоге
шаблоны для шаблонов
язык...
-
Отказывается при импорте файлов. Вы
есть 4 разных способа сделать это
(include, include_once, require,
require_once), все они медленные,
очень медленно. На самом деле все
язык медленный. По крайней мере, довольно
медленнее, чем питон (даже с
рамки) и RoR из того, что я
собирать.
Мне все еще нравится PHP. Это бензопила веб-разработки: вы хотите, чтобы небольшой и средний сайт работал очень быстро и уверен, что кто-нибудь сможет его разместить (хотя конфигурации могут отличаться)? PHP находится прямо там, и для повселокального развертывания всего LAMP или WAMP стека требуется всего 5 минут. Ну, я вернусь к работе с Python сейчас...
Ответ 13
Вот некоторые вещи, которые мне не нравятся в Java (это не мой любимый язык):
- Стирание типа дженериков (т.е. не генерируемых обобщений)
- Невозможность поймать несколько исключений (разных типов) в одном блоке catch
- Отсутствие деструкторов (finalize() - очень плохая замена)
- Нет поддержки для закрытия или обработки функций как данных (анонимные внутренние классы - очень многословная замена)
- Проверяемые исключения в общем случае, или, более конкретно, проверка исключенных исключений (например, SQLException)
- Поддержка языкового уровня для литеральных коллекций
- Нет типа-вывода, когда вызываются конструкторы родовых классов, т.е. параметр типа должен быть повторен с обеих сторон '='
Ответ 14
С++
- Синтаксис шаблонов
- Проблемы с алмазным наследованием
- Множество/отсутствие стандартных библиотек, которые имеют современные языки (хотя ускорение приближается).
- IOStreams
- Синтаксис, используемый в IOStreams
Python
- Пробелы имеют смысл (иногда)
- подчеркнутые ключевые слова
- Ограниченная поддержка потоков (по крайней мере в настоящее время)
- "self" вместо "this"
- Пробелы имеют смысл (иногда)
Ответ 15
Objective-C
1) Нет пространств имен, только ручные соглашения об именах. Я не против этого в терминах разделения классов, но я пропускаю возможность импорта всех определений классов в пространстве имен в одной строке (например, import com.me.somelibrary. *).
2) Библиотеки по-прежнему имеют некоторые отверстия в важных областях, таких как поддержка RegEx.
3) Синтаксис синтаксиса немного неуклюжий, требующий трех строк (в двух отдельных файлах) для объявления свойства.
4) Мне нравится модель сохранения/выпуска, но это проще, чем нужно освободить ссылку, а затем случайно использовать ее позже.
5) Хотя это и не является особенностью языка, Xcode настолько переплетается с использованием Objective-C, я не могу не думать об этом аспекте... в основном автозаполнение, очень хорошо. Это больше похоже на систему, которая вознаграждает вас за то, что вы нашли то, что хотите, и затем представляет ее как выбор после этого. Но потом, полагаю, мне никогда не нравились автозаполненные двигатели.
Ответ 16
C++
-
Строки.
Они не совместимы со строками платформы, поэтому вы в конечном итоге используете std::vector половину времени. Политика копирования (копия на запись или глубокая копия) не определена, поэтому гарантии производительности не могут быть предоставлены для простого синтаксиса. Иногда они полагаются на алгоритмы STL, которые не очень интуитивно понятны в использовании. Слишком много библиотек, которые, к сожалению, гораздо удобнее в использовании. Если вам не нужно их комбинировать.
-
Разнообразие строковых представлений
Теперь это немного проблема с платформой, но я все еще надеюсь, что было бы лучше, если бы более менее упрямый стандартный класс строк был бы доступен ранее. В следующих строковых представлениях я часто использую:
- общий LPCTSTR,
- LPC (W) STR, выделенный CoTaskMemAlloc,
- BSTR, _bstr _t
- (w) строка,
- CString,
- std::vector
- класс roll-my-own (sigh), который добавляет проверку диапазона и базовые операции в буфер (w) char * известной длины
-
Создать модель.
Я болен до смерти все время, потраченное на путаницу с тем, кто включает в себя, что, форвардные декларации, оптимизация предварительно скомпилированных заголовков и включает в себя, по крайней мере, постепенное время сборки терпимое и т.д. Это было здорово в восьмидесятые годы, но теперь? Есть так много препятствий для упаковки кусочка кода, чтобы его можно было повторно использовать, чтобы даже собака мамы скучала, слушая меня.
-
Трудно разобрать
Это делает внешние инструменты особенно трудными для написания и правильными. И сегодня у нас, парней С++, в основном нет цепочки инструментов. Я люблю свое отражение в С# и делегатов, но я могу жить без них. Без большого рефакторинга я не могу.
-
Threading слишком тяжелая
Язык даже не распознает его (к настоящему времени), а свободы компилятора - в то время как великие - - болезненны.
-
Статическая и по требованию инициализация
Технически я обманываю здесь: это еще одна головоломка в "завершающем коде для повторного использования": это кошмар, чтобы получить что-то инициализированное только тогда, когда это необходимо. Лучшее решение для всех других проблем с переименованием бросает все в заголовки, эта проблема говорит "neeener - вы не можете".
Конечно, многое из того, что выходит за рамки строгого языка, но ИМО, всю инструментальную цепочку нужно судить и нужно развивать.
Ответ 17
JavaScript
-
Прототип Object
может быть изменен. Каждый объект в вашей программе получает новые свойства, и что-то, вероятно, ломается.
-
Все объекты являются хеш-картами, но трудно безопасно использовать их как таковые. В частности, если один из ваших ключей окажется __proto__
, у вас проблемы.
-
Отсутствие замыкания объекта при контрольном времени функции. Фактически, никакого закрытия объекта вообще - вместо этого this
устанавливается всякий раз, когда вызывается функция с нотной записью объекта или оператором new
. Результаты во многом путают, особенно при создании обратных вызовов событий, потому что this
не настроен на то, что ожидает программист.
- Следствие: вызов функции без объектной нотации или оператора
new
приводит к тому, что this
устанавливается равным глобальному объекту, что приводит к большому поломке.
-
Оператор добавления перегружен, чтобы выполнять конкатенацию строк, несмотря на то, что две операции принципиально разные. Результаты боли, когда значение, которое вы ожидаете быть числом, на самом деле является строкой.
Операторы -
==
и !=
выполняют принуждение типа. Сравнение между различными типами включает список правил, которые никто из смертных не может запомнить полностью. Это смягчается наличием операторов ===
и !==
.
-
Существуют как null
, так и undefined
, с немного отличающимися, но избыточными значениями. Почему?
-
Странный синтаксис для настройки цепочек прототипов.
-
parseInt(s)
ожидает номер C-стиля, поэтому обрабатывает значения с ведущими нулями как восьмеричные и т.д. Вы можете как минимум parseInt(s, 10)
, но поведение по умолчанию запутывается.
-
Нет области блока.
-
Может объявлять одну и ту же переменную более одного раза.
-
Может использовать переменную без объявления ее, и в этом случае она глобальна и, вероятно, нарушает вашу программу.
-
with { }
.
-
Действительно трудно документировать с помощью подобных JavaDoc инструментов.
Ответ 18
Python:
- Отсутствие статической типизации
- Обработка аргументов по умолчанию (в частности, что вы можете изменить аргумент по умолчанию для будущих абонентов!)
- Слишком много требуемых подчеркиваний (конструкторы должны называться
__init__
)
- Отсутствие надлежащих частных членов и функций (соглашение просто говорит, что большинство вещей, начинающихся с подчеркивания, являются частными, за исключением всего, что есть, например,
__getattr__
)
- Смешной синтаксис для
print
для файла (но они исправляются в Python 3)
Ответ 19
С#
-
Мне бы хотелось, чтобы я мог switch()
для любого типа, и что case
может быть любым выражением.
-
Невозможно использовать синтаксис инициализатора объекта с полями "readonly" /private set
autoprops. Как правило, я хочу, чтобы языковая помощь создавала неизменяемые типы.
-
Использование {}
для пространства имен и класса и метода и блоков свойств/индексатора и многозадачные блоки и инициализаторы массива. Трудно понять, где вы находитесь, когда они далеко друг от друга или несовместимы.
-
Я ненавижу писать (from x in y ... select).Z()
. Я не хочу возвращаться к синтаксису вызова метода, потому что синтаксис запроса отсутствует.
-
Я хочу предложение do
в синтаксисе запроса, которое похоже на foreach
. Но это не вопрос.
Я действительно добираюсь сюда. Я думаю, что С# является фантастическим, и трудно найти много, что сломалось.
Ответ 20
PHP
- Нет функций отладки, если вы не контролируете сервер, и даже тогда они вроде сосать
- Крайнее количество плохого PHP-кода, плавающего вокруг, дает всем PHP-программистам дурное имя
- Непостоянное назначение функций
- Невозможность иметь статическую типизированную переменную, если я хочу ее (я большой поклонник динамической типизации 90% времени)
- REGISTER_GLOBALS - это дьявол
Ответ 21
C (ОК, это не мой любимый, но это еще не сделано.)
- Синтаксис библиотеки Socket.
- Нет перегрузки функций.
- Строки в стиле C.
- Переполнение буфера.
- Критический синтаксис. Я не знаю, сколько раз я искал такие вещи, как атои, ударил меня по лбу и крикнул "Конечно!"
EDIT: я мог бы придумать больше, если бы прибегнул к большему количеству библиотечного кода (например, я сделал с сокетами, но это особенно плохо), но я уже чувствовал, что я обманываю за сбор на C. Так много языков существует только чтобы взять хорошие части С и заменить плохое, что это вроде как избиение мертвой лошади.
Ответ 22
Общий Lisp:
- Ключевые слова часто слишком многословны.
- Поддержка библиотек жалкая.
- Не работает в операционных системах, которые хотят более строго обрабатывать память.
- Не имеет хороших возможностей для взаимодействия с ОС.
- Объект "loop" не определен корректно и, конечно, не выглядит Lispy.
Ответ 23
BrainF * ск
-
Ваше изюминка заключается в том, что вы полностью усовершенствуетесь? Я могу сделать больше в регулярных выражениях Perl!
-
Отсутствие объектов. Давай, люди! Это нравится, привет...
-
Нет сетевых библиотек. Все, что я хочу, это очистить веб-страницу, GOSH.
-
Нет первоклассных функций. Поздравляем - вы можете сочувствовать своим друзьям из Java.
-
Бесконечная лента для хранения и ничего больше. Это настолько ненормально претенциозно, что мы могли бы написать Lisp.
Ответ 24
JavaScript
- числа как строки - математика может быть
разочарование, когда числа
в виде строк. 5 + 2 = 52?
Хмм...
- Разрешения - все лучшие вещи требуют разрешения от пользователя!
- Обновления экрана - браузер должен находиться в устойчивом состоянии для обновления экрана. Кажется, что нет способа заставить экран обновляться в середине script.
- Slow - хотя Google Chrome хорош...
- Различия в браузере делают использование языка [цензуре].
Ответ 25
PHP:
- Никогда нельзя быть уверенным, что некоторые почти общие расширения доступны на всех веб-серверах.
- пытается быть всем в будущем (goto, закрытие,...)
- много угроз безопасности для неопытных пользователей
- больше перегрузки оператора было бы приятным
- все бедные программисты, которые не учатся, как заставить его работать правильно, и дают ему плохое имя.
Тем не менее PHP - это (скриптовый) язык.; -)
Ответ 26
VB6
- Только Windows.
- Больше не поддерживается.
- Массивы могут начинаться с любого числа, а не все нормализуются до 0.
- скомпилированные приложения зависят от многих DLL для правильной работы.
- Многие сложные элементы управления, такие как управление браузером или сложные фрагменты кода, как правило, ломают IDE, когда вы запускаете код без компиляции, но при компиляции отлично работаете.
Ответ 27
Ruby - мой любимый язык, вот что мне не нравится:
- Зеленые потоки + блокировка библиотек C = гигантский сбой
- SO PAINFULLY SLOW
- Стандартная библиотека сама по себе несовместима с ее использованием взрыва! Методы
- Модуль включает в себя + расширение грязно.
- "Открытые классы" не могут быть охвачены областью - я хочу добавить String # dostuff, но я не хочу, чтобы это просочилось во все сторонние библиотеки.
- Отсутствует решение для пакетной установки развертывания.
Ответ 28
Delphi:
- IDE немного нестабильна.
- Понимание кода иногда путается.
- Отладка иногда бывает ошибочной.
- Обновление нескольких файлов проекта может быть громоздким.
- При запуске, когда один или несколько пакетов недоступны, сообщение об ошибке вызывается несколько раз.
Ответ 29
JavaScript
-
Каждый script выполняется в одном глобальном пространстве имен... что-то, что вам нужно искать при работе со сценариями из разных источников
-
Если используется переменная, но она не определена до начала, она считается глобальной переменной
-
Поставщики браузеров, составляющие стандарты по своему усмотрению, делают кодирование для разработчиков, использующих такой красивый язык сложнее, чем это должно быть
-
Чувствительность к регистру - учитывая, что нет достойной IDE для разработки js с проверкой времени компиляции
-
Временные решения (например, использование метода hasOwnProperty
) для выполнения некоторых, в противном случае простых операций.
Ответ 30
Haskell:
- Утечка пространства от ленивой оценки.
- Числовая иерархия, не построенная в отношении математических абстракций.
- Строгий монодичный IO может затруднить отладку.
- Большие реализации обрабатывают ввод-вывод способами, которые не кажутся вполне совместимыми со стандартом. (В частности, вывод символов выводит только младшие 8 бит - и затем создается код, который использует это предположение для выполнения двоичного ввода-вывода. Ick.)
- Ассоциативность оператора
($)
может быть изменена, чтобы сделать некоторые выражения более красивыми.
Большинство из них не поднимаются до уровня ненависти, и есть люди, которые пытаются исправить или построить сложные обходные пути для каждого из них.
Изменить: В точке 5 возникла некоторая путаница. В частности, некоторые люди, похоже, думают, что я имел в виду порядок аргументов, чего у меня нет. Вместо того, чтобы объяснять, что я имел в виду, я просто укажу людей на следующую ссылку: http://hackage.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity, которая хорошо ее выражает.