Какой синтаксический элемент вы больше всего ненавидите в языке программирования, который вы часто используете? [закрыто]
27
Независимо от того, насколько вы любите язык программирования, в нем всегда есть несколько деталей, которые не так хороши, как могли бы быть.
В этом вопросе я бы хотел особо остановиться на элементах синтаксиса. В языке программирования, который вы часто используете (возможно, ваш любимый язык программирования или, возможно, тот, который вы вынуждены использовать на работе), какой элемент синтаксиса вы считаете наиболее нечитаемым, неясным, неудобным или неприятным?
@ Натан Тейлор, не для этого вопроса, а для другого вопроса .
Finnw
Этот вопрос изменился? Потому что, когда я ответил, он не был сосредоточен на «элементах синтаксиса» ... Мне придется изменить свой ответ сейчас.
Талви Ватиа
@ Талви: Нет, речь шла о синтаксисе с самого начала.
Тимви
@Timwi странно, это должен быть случай «ответить на вопрос, думая, что это был другой вопрос».
Талви Ватиа
Если вы можете голосовать и считаете, что это полезный вопрос или у него есть полезные ответы ниже, пожалуйста, проголосуйте. Сайты StackExchange нуждаются в голосах, чтобы создать хорошее сообщество. Вы можете отдавать 30 голосов в день, не тратьте их впустую. Специально для пользователей с высокой репутацией и низким количеством подсчитанных голосов, пожалуйста, прочитайте это: meta.programmers.stackexchange.com/questions/393/…
Maniero
Ответы:
39
Вставка точки с запятой в JavaScript.
Меня это не особо часто укусило, но это настолько феноменально плохая идея, что у меня кружится голова.
Вот правила (из ECMA-262, раздел 7.9)
Если программа содержит токен, который не разрешен формальной грамматикой, то точка с запятой вставляется, если (а) в этой точке есть разрыв строки, или (b) неожиданный токен был закрывающей скобкой.
Когда достигнут конец файла, если программа не может быть проанализирована иначе, вставляется точка с запятой.
Когда встречается «ограниченная продукция» и содержит терминатор строки в месте, где грамматика содержит аннотацию «[здесь нет LineTerminator]», то вставляется точка с запятой.
Да, многие ожидают, что JavaScript будет «языком свободной формы», но это не так.
Андреас Рейбранд
13
Это имеет смысл, как только вы поймете, что JavaScript был разработан для создания HTML, который также имеет долгую историю попыток интерпретировать, что ваш код «действительно означает», когда он не синтаксически допустим. (Когда-нибудь посмотрите принцип надежности - самое большое бедствие в истории вычислительной техники.)
Мейсон Уилер,
7
Эти типы ошибок, для меня, являются запахом кода, что программист небрежен и никогда не работал с большинством формальных «строгих» языков, которые обычно вызывают синтаксическую ошибку для пропуска точки с запятой.
Талви Ватиа
7
Wohoo, наконец, кто-то еще, кто также думает, что Принцип Надежности - это катастрофа, которая сделала HTML полным беспорядком.
Роман Старков
39
Синтаксис Java-бина из-за отсутствия свойств C #
/**
* Name of user
*/
private String name;
/**
* Gets name of user
* @return Name of user
*/
public String getName() {
return this.name;
}
/**
* Sets name of user.
* @param name
*/
public void setName(final String name) {
this.name = name;
}
GAH !!!
Проблемы у меня с этим
Слишком много кода. Иметь задокументированное поле, задокументированный метод получения и задокументированный метод установки. Этот чрезвычайно простой пример имеет 20 строк кода для одного свойства
Загромождает списки метода - «Позволь мне найти этот метод, руку на: getX, getY, getZ, getAnotherAnnoyingField, getWhyIHateJavaBeans, getThisIsVerbose, getGAH... ах там, hashCode.
Многочисленные области документации приводят к плохой, устаревшей или отсутствующей документации - раздражает при попытке понять, что делает код
Так что надоедливой третьей стороне пришлось придумать плагин, чтобы сделать это легко - Spoon , Shark и другие.
Еще раз, когда код настолько многословен, что для него нужны инструменты для автоматической генерации, что-то не так. Я парень из NetBeans, но у него также есть возможность автоматически генерировать геттеры и сеттеры. Но Javadoc выходит из-под контроля, он все еще многословен, он все еще загромождает Javadoc и т. Д.
TheLQ
11
Если вам нужны геттеры для всего, значит что-то не так с клиентским кодом.
Finnw
7
Наличие геттеров и сеттеров нарушает инкапсуляцию. Поле также может быть public. Члены должны быть частными и должны разумно обрабатываться классом с логикой более высокого уровня, а не с получателями и установщиками из клиентского кода.
Greyfade
6
@greyfade: если это общедоступно, вы не можете легко изменить то, что делает код настройки (вам придется изменить весь код, который устанавливает поле снаружи).
Барт ван Хейкелом
3
@SHiNKiROU: Java выглядит чисто? Я никогда не слышал этого раньше! Моя главная проблема с Java в том, что, казалось бы, простая вещь занимает десятки строк кода, которые я должен мысленно игнорировать.
конфигуратор
33
Чувствительность к пробелам.
Python раздражает меня в этом отношении. Я имею в виду, я отступ правильно так или иначе, но это ошибка мне , что я должен иметь к. Создание представления частью синтаксиса раздражает меня.
Вот пример того, почему я нахожу это очень неудобным:
switch (someVariable)
{
case 1:
int i = something();
doSomething(i);
break;
case 2:
int i = somethingElse();
doSomethingElse(i);
break;
}
Это не компилируется, потому что переменная iповторно объявлена в той же области видимости. Это кажется незначительной деталью, но она часто кусает меня. Я могу добавить фигурные скобки, чтобы смягчить его, но было бы неплохо, если бы фигурные скобки были обязательной частью синтаксиса и не было избыточного дополнительного уровня отступа. Я также очень ненавижу писать дополнительные break. Это было бы намного лучше:
switch (someVariable)
case 1
{
int i = something();
doSomething(i);
}
case 2
{
int i = somethingElse();
doSomethingElse(i);
}
default
{
...
}
Это делает его более похожим на if/ elsechain, что хорошо, так как семантически похоже. По крайней мере, в C # это все равно не будет тем же, потому что в switchутверждении порядок меток регистра не имеет значения, но в if/ elseэто имеет значение.
К сожалению, ваш улучшенный синтаксис избавляет от того, что, возможно, является самой большой особенностью коммутатора в большинстве этих языков: сквозной. «Устройство Даффа» в Си - прекрасный пример ценности этой конкретной «ошибки». В C-подобных языках также распространено использование провала в интерпретаторах и подобных программах.
Greyfade
7
Нет, это не покончит с этим. Требуется только сделать его более явным (используя a gotoили аналогичный), как это уже имеет место в C #.
Тимви
8
@greyfade: любой код, использующий устройство Даффа в C, должен умереть ужасной смертью. Компиляторы принимают лучшие решения относительно таких вещей, чем вы.
Билли ONEAL
4
@greyfade: Delphi получает вокруг проблемы множественного значения, просто позволяя несколько индексов в случае: case Foo of 1,3: Result := 'odd'; 2,4: Result := 'even' end;.
Фрэнк Шиарар
3
@jkerian: теперь представьте, что это breakбыло по умолчанию, и нужно было указать только падение. Больше не нужно помнить, чтобы прокомментировать это! :)
Тимви
27
Объявления массивов в VB.NET
Мне всегда удается забыть, что при инициализации фиксированных массивов в VB.NET вы указываете верхнюю границу массива, а не количество элементов, как в C / C ++, PHP или Java. Помимо VB6 (мы не пойдем туда ...), я не могу думать о другом языке, который делает это следующим образом:
Dim myArray(20) as Integer '# Creates an array with 21 elements,
'# indexed from 0 to 20
+1 за использование VB6 в качестве вашего наиболее распространенного языка.
Уолтер
9
Я использую это ежедневно
systempuntoout
У Паскаля нет похожего синтаксиса? Я всегда думал, что это противно.
Greyfade
1
Существует особый случай: если вы Dim Hurp As New Collection, если вы Hurpобращаетесь к Nothingнему, когда он ссылается , он будет магически инициализирован перед доступом. Если вы явно установите его Nothingи дотронетесь до него, он воскреснет ... ах!
Джеффри Хантин
1
+ 1 миллион за сумасшедший. Derp de derp de tiddly tum de derp.
MVCylon
24
Комментирование в CSS
//не закомментирует строки кода, как во многих других языках, таких как PHP и Javascript. Хотя /* this is commented out */работает, я предпочитаю использовать //.
Это неприятно, потому что половину времени я забываю, что редактирую CSS, а затем должен вернуться и исправить ошибку.
В наше время вы бы подумали, что необработанный CSS будет рассматриваться как объектный код.
Том Хотин - tackline
// отлично работает, чтобы закомментировать CSS. Я делаю это все время. Все, что я на самом деле делаю, это набираю мусор. но, похоже, это работает, пропуская непонятную строку.
MVCylon
1
@MVCylon Если вы используете //, чтобы закомментировать строку, все, что находится после этой следующей строки, также пропускается. {в этом конкретном стиле} Другими словами, он терпит неудачу, потому что эти строки не должны быть пропущены.
Талви Ватиа
20
PHP - последовательный порядок аргументов
В PHP есть несколько удобных функций для выполнения практически всех операций, которые вы можете себе представить над массивом или строкой. Многие из этих операций требуют использования и a, $needleи a $haystack, но разные функции принимают их в разных порядках. Какая функция требует, какие аргументы - один из тех фактов, которые мой мозг отказывается воспринимать, как бы часто я с ними ни сталкивался!
// Check whether $needle occurs in array $haystack
bool in_array (mixed $needle, array $haystack [, bool $strict])
// Check whether $needle is a substring of $haystack
string strstr (string $haystack, mixed $needle [, bool $before_needle=false])
Как ни странно, PHP кажется внутренне совместимым с этими порядками в том $haystack, $needleсмысле, что все строковые функции, кажется, используют, в то время как функции массива работают наоборот, но это может занять некоторое время, чтобы привыкнуть к кому-то новичку в PHP. В ExpressionEngine есть хороший пост, в котором более подробно рассказывается об этой специфической причуде, а также обсуждается список ошибок PHP , который содержит очень короткий ответ от команды PHP!
Проще запомнить порядок $needle, так $haystackкак он напоминает способ найти иголку в стоге сена .
kiamlaluno
3
Подсказка: в функциях массива игла стоит первой. в строковых функциях стог сена идет первым.
GSto
17
Я люблю это имя strstr. Так красиво бессмысленно.
конфигуратор
5
Просто прочитайте связанную запись в багтрекер PHP. Серьезно, ВТФ? oO Непротиворечивость Imho является допустимой проблемой для любого API, и просто ответ «использовать достойную IDE» просто не является верным ответом. По крайней мере, разработчики могли бы сформулировать это менее подстрекательски.
Baelnorn
2
Честно говоря, то, что сводит меня с ума, так это то, что это вообще не должно быть функцией! Это должен быть просто метод: $ haystack-> find ($ needle). Сделка сделана
В методе класса его обычно называют cls, а использование self противоречит соглашению.
Это действительно имеет смысл, если вы думаете об этом. Это то же самое, что объявить закрытый метод в других языках, параметр self явно указан в python, где он неявен в других языках. Если вы хотите, чтобы он был неявным, добавьте декоратор @classmethod перед объявлением метода. См. Docs.python.org/library/functions.html#classmethod . Изучение деталей того, как это работает, даст вам некоторое представление о том, как это неявно делается на других языках.
@Evan Plaice: «Параметр self явно указан в python, где он неявен в других языках». Это только одна часть истории. Другая часть - это python, который печатается еженедельно. Вместе это ужасно, забывать selfбывает легко и стоит времени.
Maaartinus
@maaartinus Затем добавьте декоратор метода класса к вашим методам экземпляра. Не имеет ничего общего со «слабо напечатанным». Это просто делает связь между статическими методами / функциями (без параметра «self») и методами экземпляра (включая «self») очевидными. Метод экземпляра не знает о своем родительском классе, если вы не дадите ему ссылку для этого. В других языках отличительная черта, которую я обозначил, скрыта за синтаксическим сахаром. Если бы у меня был выбор сделать все заново, я бы сначала начал изучать ООП на Python.
Эван Плейс
18
Джава
Период. Полная остановка. Конец истории.
Когда начать? О, я знаю, с чего начать: Java - безумно сложный, уродливый, глупый и по своей сути сломанный дженерик. Нужно ли мне сказать больше? :( Хорошо, хорошо, тогда: erasure .
Тогда есть недетерминированное управление ресурсами. Kewl Footcher!
Что дальше? Ах да: глупые регулярные выражения Java - моя самая раздражающая, кипящая говядина. Я не могу сосчитать, сколько раз меня держали в руке из-за недостатка обратной косой черты. Это даже хуже, чем отсутствие доступа к каким-либо свойствам Юникода в этом тысячелетии, что вполне закономерно. Десять офигенных лет устарели !!! Совершенно бесполезно. Мусор это.
Тогда есть ошибка, что ярлыки класса персонажа не работают на не-ASCII. Какая королевская боль! И даже не подумайте об использовании \p{javaWhiteSpace}; он не работает правильно с несколькими очень распространенными точками пробела Unicode.
Знаете ли вы, что есть \p{javaJavaIdentifierStart}недвижимость? Что они думают? Я так рада, что они получили таких умных пиперов, как на жестком диске.
Вы когда-нибудь пытались использовать флаг CANON_EQ? Вы знаете, что на самом деле делает, а что нет ? Как насчет так называемого «случая Unicode»? Куча нормальных оболочек просто не работает.
Затем они затрудняют написание поддерживаемых регулярных выражений. Java до сих пор не разобралась в том, как писать многострочные строки, поэтому в итоге вы пишете такие безумные вещи, как это:
Каковы все эти новые строки? О, просто глупость Java. Они использовали комментарии Perl, а не комментарии Java ( идиоты! ), Которые идут до конца строки. Так что, если вы не положите их \nтуда, вы отрубите остальную часть вашего паттерна. Дух и двойной дух!
Не используйте регулярные выражения в Java: вы просто захотите разбить вещи, все это так больно и сломано. Я не могу поверить, что люди терпят это. Некоторые нет .
Тогда мы можем начать говорить об идиотской бессмыслице Java с кодировками. Во-первых, существует тот факт, что кодировка платформы по умолчанию всегда представляет собой неаккуратную 8-битную кодировку, даже несмотря на то, что в Java используются символы Unicode. Тогда есть то, как они не вызывают исключение при ошибке кодирования. Вы гарантированно получите дерьмо. Или как насчет этого:
OutputStreamWriter(OutputStream out)
Creates an OutputStreamWriter that uses the default character encoding.
OutputStreamWriter(OutputStream out, Charset cs)
Creates an OutputStreamWriter that uses the given charset.
OutputStreamWriter(OutputStream out, CharsetEncoder enc)
Creates an OutputStreamWriter that uses the given charset encoder.
OutputStreamWriter(OutputStream out, String charsetName)
Creates an OutputStreamWriter that uses the named charset.
Какая разница? Знаете ли вы, что только один из них вызовет исключение, если у вас есть ошибка кодирования? Остальные просто намордники.
Тогда есть идиотизм символов Java, не достаточный, чтобы держать характер! Что, черт возьми, они думают? Вот почему я называю их чарчарами. Вы должны написать такой код, если ожидаете, что он будет работать правильно:
private static void say_physical(String s) {
System.out.print("U+");
for (int i = 0; i < s.length(); i++) {
System.out.printf("%X", s.codePointAt(i));
if (s.codePointAt(i) > Character.MAX_VALUE) { i++; } // UG!
if (i+1 < s.length()) { System.out.printf("."); }
}
}
А кто нибудь думает это сделать? Рядом ни с кем.
Сколько персонажей там "\uD83D\uDCA9"? Один или два? Зависит от того, как вы их считаете. Механизм регулярных выражений, конечно, работает с логическими символами, поэтому шаблон ^.$будет успешным, а шаблон ^..$- неудачным. Это безумие демонстрируется здесь:
Этот идиотизм - все, потому что ты не можешь написать совершенно разумный \u1F4A9 , и, конечно, вы не получите никакого предупреждения, что вы не можете этого сделать. Это просто делает неправильную вещь.
Stoooopid.
Пока мы в этом, вся \uXXXXнотация врожденно умерла. Препроцессор Java ( да, вы слышали меня ) добирается до этого раньше, чем Java, поэтому вам запрещено писать совершенно разумные вещи, например "\u0022", потому что к тому времени, когда Java это видит, его препроцессор превратил его в """, и вы проиграете. Ой , подождите, не , если это в регулярном выражении! Таким образом, вы можете использовать "\\u0022"просто отлично.
Riiiiiiiight!
Знаете ли вы, что в Java нет способа сделать isatty(0)звонок? Тебе даже не позволено думать такие мысли. Это не будет хорошо для вас.
И затем есть вся мерзость пути класса.
Или тот факт, что невозможно указать кодировку исходного файла Java в том же исходном файле, чтобы вы не потеряли его? Я еще раз требую знать: ЧТО, ЧТО ОНИ МЫ ДУМАЛИ?
Останови безумие! Я не могу поверить, что люди терпят этот мусор. Это полная шутка. Я бы предпочел быть приветствующим Walmart, чем страдать от слингов и стрел возмутительного безумия на Яве. Это все сломано, и они не только не могут это исправить, но и не могут это исправить.
Это те же самые люди-лисички, которые гордились тем, что сделали незаконным printf()функционирование. Ну и дела, что действительно сработало очень хорошо, не так ли?
Чистые черепа. Шлепки слишком добры к ним. Если бы я хотел программировать на ассемблере, я бы. Это не подлежащий спасению язык. У императора нет одежды.
Мы ненавидим это. Мы ненавидим это навсегда . Пусть умирает, умирает, умирает !
Ха-ха, хорошо, я не трогаю Java, потому что он слишком неполированный, как ты описал. Что касается \ uD83D ... я полагаю, что лучше сказать, что вы бы предпочли не строки UTF-16, а UTF-32. Если вы принимаете UTF-16-ность, тогда регулярные выражения делают правильные вещи; это длина звонка, который облажался.
Роман Старков
4
-1. За исключением комментариев к регулярному выражению и экранирования Unicode, ни одна из упомянутых вами вещей не является элементом синтаксиса.
Йорг Миттаг
3
@ Йорг, хочешь синтаксис? Хорошо, хорошо: Java позволяет вам помещать управляющие символы, включая ESC и NUL, в идентификаторы. Что они думают ???
2010 года
4
@tchrist: Ух ты! Если я когда-нибудь снова напишу программу на Java, все мои переменные будут иметь имена, состоящие из различного числа символов ^H
возврата
1
@ tchrist, тебе лучше?
16
Синтаксис объявления указателя функции в C и C ++:
(int)(*f)(int, int);
Это объявляет указатель на функцию с именем, fчье pointee может принимать два ints и возвращать int.
Я бы предпочел такой синтаксис:
f: (int, int) => int
Скажем, вы хотите объявить указатель на функцию, gчей pointee может взять два ints и функцию из intи intв int, и вернуть int.
С нотацией C или C ++ вы бы объявили ее как:
(int)(*g)(int, int, int(int, int));
С помощью предложенных выше обозначений то же самое может быть объявлено как:
g: (int, int, (int, int) => int) => int
Последнее гораздо более интуитивно понятное ИМО.
Кроме того: язык программирования под названием OOC исправляет этот синтаксис (и другие синтаксические проблемы в C и C ++). Проверьте его домашнюю страницу здесь .
Согласитесь, некоторые "обычные C" / "C ++" не поддерживают его или поддерживают с другим синтаксисом. Специальный синтаксис помогает указать, когда поддерживается функция языка программирования. Вот почему в C # добавлен синтаксис делегата.
umlcat
Делегаты являются не только синтаксическим сахаром, потому что они также хранят объект (в отличие от указателей на функции-члены C ++, синтаксис которых даже хуже, чем на обычных указателях функций)
"public static final int x = 4;" по сравнению с "х = 4" в Haskell.
Джаред Апдайк
24
Это не многословие. Попробуйте написать, a+(b*c)/d*e+f/g^20используя BigIntegerв Java. Почему этот язык не допускает перегрузки операторов?
МАК
4
@Michael: программисты, которым необходимо защитить себя от этих затрат, могут лучше защитить себя (и уменьшить боль для всех остальных), вообще не программируя: D.
МАК
12
\ we \ notnt \ fix \ синтаксис пространства имен нашего \ parser в PHP
Синтаксис не только уродлив, он приводит к путанице, когда новым разработчикам приходится задумываться о пространствах имен в строках. (PHP интерполирует обратные слэши в строках в двойных кавычках в качестве escape-последовательностей. Попытка представить пространство имен, как \you\should\never\do\thatв строке в двойных кавычках, а не в строке в одинарных кавычках, приведет к появлению новых строк, вкладок и к катастрофе.)
Да, кто-то придумал лучший способ сделать это, но PHP настаивает на том, что каждый оператор должен быть разным. Мне любопытно, что проблема злоупотребления здесь.
Алан Пирс
Согласен. PHP требует пространства имен, но этот синтаксис
облажался
9
Я презираю тот факт, что фигурные скобки могут быть необязательными после оператора if / while / for.
Особенно, когда я вижу код, как,
if (...)
for(...)
... One line of stuff ...
Пожалуйста, просто вставьте скобки и покончите с этим.
Хм .. это зависит. Для «Прервать Ifs», которые просто проверяют условие и возвращают код ошибки (или выдают исключение), я бы предпочел не видеть скобки.
Билли Онил
4
Я бы согласился, если бы вы ограничились крайними многоуровневыми случаями, но ваше утверждение слишком поверхностно. Существует возможность использовать короткие формы для простых операторов if и циклов с одним оператором.
Тимви
2
Мое правило: только если для утверждения требуется несколько подстатей или если оно содержит такое утверждение, его следует заключить в фигурные скобки. Таким образом for (...) while (...) if (...) { x(); y(); }, лучше переписать, как for (...) { while (...) { if (...) { x(); y(); } } }, с соответствующим отступом, конечно.
Джон Перди
6
Я скорее наоборот - я презираю людей, которые настаивают на установке скобок, когда они совершенно не нужны. Просто научись программировать.
Джерри Коффин
3
Мне действительно нравятся квадратные скобки даже в одиночных операторах if. Это заставляет меня лучше следить за ходом программы.
Рикардо Сантос
9
VBScript не имеет логических операторов
В отличие от почти каждого разумного языка, VBScript использует побитовые операторы вместо логических операторов. Что это значит на практике? Ну, как отмечает Эрик Липперт :
If Blah = True Then Print "True!" Else Print "False!"
а также
If Blah Then Print "True!" Else Print "False!"
НЕ одинаковы в VBScript!
Еще хуже, хотя, это означает , что нет никакой оценки короткого замыкания в VBScript , так что следующий оператор будет врезаться вашей программой , если BlahISNothing
If (Not Blah Is Nothing) And (Blah.Frob = 123) Then
...
Правильно, VBScript оценит обе части сравнения AND, даже если первая из них неверна! Просто позволь этому погрузиться ...
До того дня, когда вы обнаружили ошибку внутри If x Then ... If Not x Then ... End If ... End Ifи выяснили, что x равен 2, вы на самом деле не программировали на VB / VBScript.
конфигуратор
7
РЕДАКТИРОВАТЬ: После обсуждения в комментариях я решил обновить этот ответ, чтобы объяснить себя лучше.
Я действительно ненавижу то, как указатели на функции выглядят в C. Обычно любое объявление переменной выглядит как кортеж: type varname;
Объявления указателя функции, с другой стороны, выглядят как объявление функции с * перед именем функции. Я могу принять это как описание типа указателя, но в Си это объявляет как тип, так и имя переменной этого типа. Это выглядит противоречивым для меня, потому что объявления типов иначе отличаются от объявлений переменных. struct myStruct{int X; int Y;}определяет только тип, но не определяет переменную с именем myStruct. Точно так же я не вижу причин для объединения объявлений типов и объявлений переменных в один атомарный оператор в указателях функций, а также я не ценю отклонение отtype varname; структуры.
Кто-то указал, что это согласуется с каким-то спиральным правилом, и это может иметь место, но признаком хорошего синтаксиса является то, что он говорит само за себя, а его внутренняя логика очевидна. Спиральное правило не очевидно ни в коем случае.
Это согласуется с остальным языком, так что, может быть, ваше мнение касается синтаксиса C-объявлений вообще? Вы предпочитаете синтаксис, используемый в Go ?
Финн
В каком смысле? Обычно это идет: тип varname; И когда мы создаем новый составной тип, такой как структура, сначала идет объявление, может быть, с typedef, а затем мы создаем переменную этого типа. Когда мы объявляем указатель на функцию, это int (* foo) (int arg1, int arg2), который затем используется как тип аргумента, передаваемого в функцию: void newFoo (int (* foo) (int arg1, int art2 )) .... и как переменная: foo = a_compatible_func; Я думаю, что объявление функции сначала, а затем объявление var будет более согласованным, например: typedef int (* foo) (int, int) MyFoo; MyFoo myfoo;
EpsilonVector
Вот почему ты получил typedef.
zneak
4
@EpsilonVector: Я склонен согласиться с тем, что синтаксис указателя на функцию неприятен, но есть простое правило, которое облегчает чтение. Правило спирали по часовой стрелке (возможно, вы видели его?): C-faq.com/decl/spiral.anderson.html
Greyfade,
1
EpsilonVector: Я не уверен, что вы ожидаете от объявления переменной указателя, который объявляет не имя переменной.
6
Точки с запятой в VBScript - или их отсутствие
Я провожу весь день, работая на языках, которые ожидают точки с запятой в конце каждой строки. Добавьте один конец строки в VBScript, и ваш код больше не будет выполняться.
голосование за это не потому, что мне особенно нравятся точки с запятой, а потому, что я действительно ненавижу то, как VB поощряет очень длинные строки , делая разрывы строк такими неудобными.
Shog9
6
Аргументы в / из. Я весь в аргументах (хорошо, что я есть), наши аргументы тоже хороши, но аргумент, который должен передать эти два состояния, бесит меня.
Здесь я нацеливаюсь на функции, которые берут входные данные из параметра, а затем перезаписывают этот вход некоторым выводом. Это нормально, чтобы передать объект по ссылке, чтобы обновить его. Но, в основном, для примитивных типов: взять объект, использовать его, а затем полностью его изменить, я не прав. Вы не должны менять значение аргумента через inout.
Какой язык ты имеешь в виду? Если C #, то я бы не согласился, что это раздражает, потому что это всегда явно (в отличие от C ++.) Также я не знаю ни одного основного языка, где вы вынуждены объявлять аргументы как in / out.
Финн
@finnw Я никогда не видел языка, на котором ты должен был говорить inза inаргументы, я просто говорю о них. Кроме того, по моему мнению, ничто не может оправдать аргументы in / out, и их явное выражение не снимает боль. Не должно быть никаких причин для инициализации локальной переменной значением, полезным для функции, и иметь эту же переменную, которая затем внезапно будет содержать все, что функция решила поместить туда. Эти два должны быть разными. Всегда.
zneak
Извините, мне было не очень ясно. Я имел в виду сказать: «Я не знаю ни одного языка, где все аргументы неявно вводятся +», т. Е. Вы не обязаны использовать эту функцию, но существуют законные варианты использования (например, обновление, structгде новое значение зависит от значения другого поля того же struct.)
finnw
@finnw Объекты, переданные по ссылке (например, экземпляры classобъектов в C #), модифицируемые функцией, подходят мне. Кроме того, что мне не нравятся непостоянные структуры, передача structс refключевым словом для его обновления тоже подойдет. Что я действительно ненавижу, так это когда ввод перезаписывается выводом. Лучший пример, который я могу вспомнить, - это acceptфункция сокета Беркли : ей нужен socklen_t*аргумент, который при вводе должен содержать размер struct sockaddr*передаваемого вами значения; и на выходе будет содержать количество байтов, которые были записаны в него. Это должно быть преступным.
zneak
Я согласен, что это плохо (IIRC некоторые функции ввода-вывода Win32 делают то же самое), но это неправильное использование функции (вызов функции изменяет значение передаваемой переменной, а не только ее значение), и это не означает функцию само по себе плохо.
Финн
6
Объявления массивов в C и C ++.
Как правило, объявление переменной имеет формат type variable_name. Вы можете легко прочитать эти объявления слева направо. Но int foo[size]сначала выглядит так, будто оно объявляется fooкак int, а затем вы читаете дальше и видите, что foo типа «массив целых чисел». int[size] fooчитает намного лучше.
И я ненавижу, когда программисты объявлять указатели , как это по той же причине: int *foo. По какой-то причине я не понял, это типичный способ написания.
Ре объявления указателей: они написаны так, потому что ' ' привязывается к имени переменной, а не к типу. Так int* a, b;что * не объявлять aи bкак указатели; только aесть. Следовательно, лучше написать это как int *a, b;(или даже лучше написать их как две декларации).
Стив Мельникофф
Хорошая точка зрения. Это слишком плохо *, не привязывается к типу.
Джейкоб
2
И это не говоря о функциональных указателях ... void(int) *f;? Нет:void (*f)(int);
Обратите внимание на себя - придумайте имя
В современном C ++ очень мало потребности в указателях и массивах.
fredoverflow
2
@ Стив Мельникофф: Хотя я добавил +1 к этому ответу, я думаю, что int* a, b;упомянутая вами проблема гораздо более вопиющая.
j_random_hacker
5
Резервная параметризация в Java:
HashMap<String,HashMap<String,String>> foo = new HashMap<String, HashMap<String, String>>();
Что другой типа параметризация делает компилятор думаетfoo , может иметь?
Надеюсь, вы знаете о (ограниченном) выводе типа Java? HashMap<String,HashMap<String,String>> foo = Maps.newHashMap();
Finnw
1
Ява 7:HashMap<String,HashMap<String,String>> foo = new HashMap<>();
Барт ван Хейкелом
5
Ну, он может иметь любой тип, который он хочет, типы все равно стираются ...
Конфигуратор
Вы имеете в виду отсутствие типа вывода?
фактор
What other type parameterization does the compiler think foo could have?- По какой бы то ни было причине - это необработанный тип - как будто кто-нибудь в здравом уме даже смешивает необработанный и параметризованный типы
Maaartinus
5
Поскольку люди уже жаловались на « =против» ==, позвольте мне указать на гораздо худшую альтернативу. У PL / I было и то :=и другое =, но когда что-то было «очевидно» заданием, это позволяло бы вам избежать использования =для этого. С помощью:= позволяет вам заставить что-то быть присваиванием в ситуации, когда компилятор иначе интерпретирует это как сравнение.
К сожалению, компилятор не всегда принимал решения так, как вы ожидаете. Рассмотрим только один очевидный пример:
A = B = 0;
Теперь, для большинства людей, знакомых с большинством "обычных" языков, смысл этого довольно очевиден - присваивать 0 как A, так и B. PL / I немного ... отличается. По причинам, известным только (безумным) разработчикам языка, первое =интерпретируется как задание, а второе= - как сравнение. Следовательно, это сравнивает B с 0, а затем присваивает результат этого сравнения A (в соответствии с соглашением в стиле C, что «false» приводит к 0 и «true» в 1).
Итак, если B было 0, то A становится 1. В противном случае A становится 0. Другими словами, вместо того, чтобы присваивать одно и то же значение A и B, это фактически гарантирует, что A не сможет иметь то же значение, что и B.
Итог: хотя изначально стиль C / C ++ / PHP кажется болезненным, альтернатива намного хуже 1 .
1 Технически, есть другая альтернатива: стиль Pascal, где =всегда означает, что всегда требуется сравнение и назначение :=. После того, как вы используете это в течение некоторого времени, становится достаточно очевидным (по крайней мере для меня), что назначение является более распространенным, чем сравнение, что, если вам потребуется дополнительная «вещь» для устранения неоднозначности, вы должны определенно сохранять задания чистыми и простыми, и требует дополнительных «гранж» при сравнении, а не наоборот.
Я бы даже предложил использовать ==для равенства и :=для назначения. Таким образом, вам нужно больше печатать, но избегание одиночества =помогает избежать ошибок.
Maaartinus
@maartinus: по крайней мере для меня, это звучит как наихудшая возможность, но такова жизнь ...
Джерри Гроб
3
Perl
Я хотел бы, чтобы Perl позволил мне написать if($x < 10) do_something();. На данный момент вы должны написать это либо как, либо do_something() if($x < 10);как if($x < 10) { do_something(); }.
Это не так, и во многих случаях это намного чище, чем if(..) ...при загрузке, так как все выражения выстраиваются в ряд справа. Но бывают моменты, когда я действительно хочу сказать if($x < 10) do_something();, и, к сожалению, Perl не позволит мне.
Гаурав
7
К сожалению, пока вы не напишите, if ($x<10) do_something(); and_call_me(); а потом удивляетесь, почему вам никогда не позвонят. Я хотел бы, чтобы C и семья потребовали фигурные скобки, чтобы предотвратить этот тип ошибки.
AShelly
2
@AShelly: или почему вы всегда получаете звонок, на самом деле.
zneak
1
@zneak Кроме как нет else. (Хотелось бы, чтобы это было EXPR1 if COND else EXPR2как у Python)
Ming-Tang
3
reinterpret_cast<unsigned long>в с ++. Эта операция полезна при работе с зарубежными API и обеспечивает точность числовых данных. Почему печатать так трудно и так уродливо?
Ужасно напоминать вам, что вы должны стремиться писать код, который не требует этого. :)
Greyfade
Для меня это хороший теоретический аргумент в области компьютерных наук, но, по моему опыту, его слишком полезно избегать (однако, большая часть моего опыта - простой старый C, поэтому у меня, вероятно, предвзятость).
AShelly
5
Это не совсем теоретический аргумент CS: использование reinterpret_castв C ++ - очень сильный запах кода. В 99% случаев, когда вы собираетесь его использовать, скорее всего, вам это не нужно - вы, вероятно, сделали что-то не так. Остальные 1% времени, когда вы взаимодействуете с C., reinterpret_castломает систему типов, чтобы заставить что-то работать, когда это иначе не может. Обычно это плохо.
Greyfade
3
Конструкция for ... in в JavaScript и конструкция foreach в PHP при зацикливании массивов. Оба из них облегчают написание ошибок, чем правильный код.
Вау, это такая фигня. «Чем правильный код». Уходи.
Джонатан Стерлинг
Если мне нужно написать дополнительный код для безопасного их использования, их проще использовать неправильно в моей книге. For ... in требует дополнительных проверок, чтобы убедиться, что вы не выполняете итерации по объектам из прототипа, а foreach требует, чтобы вы впоследствии очистили ссылки или рискнули перезаписать последнее значение в массиве.
Джори Себрехтс
foreach с изменяющимися ссылками (& operator) - это известная ошибка ...
umlcat
1
Я в замешательстве, я думал, что всем известно, что конструкция "for..in" в javascript нарушена ... почему это оскорбительно?
lvilnis
2
Указатели массивов или массивов указателей в C / C ++. Я все еще смущен этим.
Читайте тип в обратном порядке. int[]*это указатель на массив целых чисел и int*[]массив указателей на целые числа. Хорошо работает и с consts: int* constэто постоянный указатель на целые числа, тогда как const int*и int const*являются указателями на постоянные целые числа (или на целочисленные константы).
Javascript / Java и т. Д., Равнозначное сравнение, например, если (a == 1)
Сколько раз я пишу, если (a = 1)?
Как человек, я прекрасно это прочитал. Но проклятый интерпретатор / компилятор говорит: «Эй, я назначу 1 для a, затем проверим, равно ли a 1, и вы поверите, да, это так!
Подводит меня к стене.
если (a == 1) гораздо менее читаемо, и интерпретатор / компилятор должен в любом случае знать, что я имею в виду; многие другие менее известные языки (VB) успешно работали в течение сотен лет.
Назначение просто не должно возвращать значение. Иногда это полезно, но в большинстве случаев это просто боль в шее.
конфигуратор
в Javascript JSLint поймает это для вас.
Захари К
Беда в том, что назначение в условиях может быть полезным. Я нахожу <tt> while (element = list-> next ()) </ tt> вполне разборчивым. Так что я не уверен, что хотел бы, чтобы он был удален.
Инка
3
@Tom: Это означает, что вы не понимаете логическое значение. Если вы имели в виду if (a == true), просто напишите if (a). Если вы имели в виду a = true, то ifутверждение является избыточным.
Ден04
1
Многословие в Java анонимных классов. Будем надеяться, скоро исправят.
К сожалению, его следует отличать от того ., который применяется к элементам не указателя объекта. Неоднозначный синтаксис плох, мммкай?
Greyfade
2
@greyfade: Да! Поскольку компилятор не может использовать свои правила системы типов, чтобы определить, когда вы используете тип указатель на структуру, и неявно применить разыменование. Нет, это сумасшедший разговор! (И все же это может как-то дать вам сообщение об ошибке, если вы ошиблись.) В синтаксисе нет ничего двусмысленного. Это просто C, как обычно, беспорядок мозга. Delphi отлично справляется с неявными разыменованиями, если вы действительно работаете в темных углах, где требуются указатели на записи, так что это, безусловно, можно сделать, не путая синтаксический анализатор ...
Мейсон Уилер
5
@ Мейсон: А как насчет случаев shared_ptr, когда ->доступ к содержащемуся типу и .доступ к свойствам shared_ptrсамого? Извините, но я здесь совершенно не согласен.
Билли ONEAL
2
могло быть и хуже. Может быть PHP, где вы должны использовать ->для доступа к членам чего-либо .
Карсон Майерс
1
@maaartinus: любой код, который в значительной степени полагается на неочевидный порядок операций, не является кодом, который я буду писать.
Билли ONEAL
0
Многострочный код Scala в скобках
Например:
class Foo(
val bar: String,
val baz: Int,
val bing: String,
val bong: Boolean
) extends Model {
// body here
}
То, что вы на самом деле получаете от этого, потрясающе. Он генерирует конструктор, геттеры и сеттеры для вас. Но это, конечно, уродливо и ломает все мои ментальные модели того, как делать отступы в коде, и в основном заставляет меня чувствовать, что я нахожусь в каком-то странном бутерброде с Java с одной стороны и Lisp с другой. (Ой, подождите ... это скорее точка Скала.)
Я в замешательстве - вы имеете в виду часть в скобках ( val barи так далее) или часть в фигурных скобках (часть после extends Model)? (В этом коде нет скобок)
Billy ONeal,
3
Часть в скобках. Я английский. Мы называем их скобками, черт возьми, потому что в этой ситуации они не играют роль скобок.
Ответы:
Вставка точки с запятой в JavaScript.
Меня это не особо часто укусило, но это настолько феноменально плохая идея, что у меня кружится голова.
Вот правила (из ECMA-262, раздел 7.9)
Пример:
источник
Синтаксис Java-бина из-за отсутствия свойств C #
GAH !!!
Проблемы у меня с этим
getX
,getY
,getZ
,getAnotherAnnoyingField
,getWhyIHateJavaBeans
,getThisIsVerbose
,getGAH
... ах там,hashCode
.источник
public
. Члены должны быть частными и должны разумно обрабатываться классом с логикой более высокого уровня, а не с получателями и установщиками из клиентского кода.Чувствительность к пробелам.
Python раздражает меня в этом отношении. Я имею в виду, я отступ правильно так или иначе, но это ошибка мне , что я должен иметь к. Создание представления частью синтаксиса раздражает меня.
источник
switch
Заявление (в C, C ++, C #, Java и т.д.)Вот пример того, почему я нахожу это очень неудобным:
Это не компилируется, потому что переменная
i
повторно объявлена в той же области видимости. Это кажется незначительной деталью, но она часто кусает меня. Я могу добавить фигурные скобки, чтобы смягчить его, но было бы неплохо, если бы фигурные скобки были обязательной частью синтаксиса и не было избыточного дополнительного уровня отступа. Я также очень ненавижу писать дополнительныеbreak
. Это было бы намного лучше:Это делает его более похожим на
if
/else
chain, что хорошо, так как семантически похоже. По крайней мере, в C # это все равно не будет тем же, потому что вswitch
утверждении порядок меток регистра не имеет значения, но вif
/else
это имеет значение.источник
goto
или аналогичный), как это уже имеет место в C #.case Foo of 1,3: Result := 'odd'; 2,4: Result := 'even' end;
.break
было по умолчанию, и нужно было указать только падение. Больше не нужно помнить, чтобы прокомментировать это! :)Объявления массивов в VB.NET
Мне всегда удается забыть, что при инициализации фиксированных массивов в VB.NET вы указываете верхнюю границу массива, а не количество элементов, как в C / C ++, PHP или Java. Помимо VB6 (мы не пойдем туда ...), я не могу думать о другом языке, который делает это следующим образом:
источник
VB6 - Отдельная декларация и присвоение переменной
Большинство языков позволяют вам объявлять переменную и назначать ее в одной строке кода; VB6, с другой стороны, заставляет вас использовать два.
Вы можете использовать двоеточие, чтобы поместить две команды в одну строку, но это быстро превращает беспорядок в реальный код.
источник
Dim Hurp As New Collection
, если выHurp
обращаетесь кNothing
нему, когда он ссылается , он будет магически инициализирован перед доступом. Если вы явно установите егоNothing
и дотронетесь до него, он воскреснет ... ах!Комментирование в CSS
//
не закомментирует строки кода, как во многих других языках, таких как PHP и Javascript. Хотя/* this is commented out */
работает, я предпочитаю использовать//
.Это неприятно, потому что половину времени я забываю, что редактирую CSS, а затем должен вернуться и исправить ошибку.
источник
PHP - последовательный порядок аргументов
В PHP есть несколько удобных функций для выполнения практически всех операций, которые вы можете себе представить над массивом или строкой. Многие из этих операций требуют использования и a,
$needle
и a$haystack
, но разные функции принимают их в разных порядках. Какая функция требует, какие аргументы - один из тех фактов, которые мой мозг отказывается воспринимать, как бы часто я с ними ни сталкивался!Возьмите функции in_array и strstr :
Как ни странно, PHP кажется внутренне совместимым с этими порядками в том
$haystack, $needle
смысле, что все строковые функции, кажется, используют, в то время как функции массива работают наоборот, но это может занять некоторое время, чтобы привыкнуть к кому-то новичку в PHP. В ExpressionEngine есть хороший пост, в котором более подробно рассказывается об этой специфической причуде, а также обсуждается список ошибок PHP , который содержит очень короткий ответ от команды PHP!источник
$needle
, так$haystack
как он напоминает способ найти иголку в стоге сена .strstr
. Так красиво бессмысленно.питон
self
параметр в определениях метода экземпляраисточник
self
бывает легко и стоит времени.Джава
Период. Полная остановка. Конец истории.
Когда начать? О, я знаю, с чего начать: Java - безумно сложный, уродливый, глупый и по своей сути сломанный дженерик. Нужно ли мне сказать больше? :( Хорошо, хорошо, тогда: erasure .
Тогда есть недетерминированное управление ресурсами. Kewl Footcher!
Что дальше? Ах да: глупые регулярные выражения Java - моя самая раздражающая, кипящая говядина. Я не могу сосчитать, сколько раз меня держали в руке из-за недостатка обратной косой черты. Это даже хуже, чем отсутствие доступа к каким-либо свойствам Юникода в этом тысячелетии, что вполне закономерно. Десять офигенных лет устарели !!! Совершенно бесполезно. Мусор это.
Тогда есть ошибка, что ярлыки класса персонажа не работают на не-ASCII. Какая королевская боль! И даже не подумайте об использовании
\p{javaWhiteSpace}
; он не работает правильно с несколькими очень распространенными точками пробела Unicode.Знаете ли вы, что есть
\p{javaJavaIdentifierStart}
недвижимость? Что они думают? Я так рада, что они получили таких умных пиперов, как на жестком диске.Вы когда-нибудь пытались использовать флаг CANON_EQ? Вы знаете, что на самом деле делает, а что нет ? Как насчет так называемого «случая Unicode»? Куча нормальных оболочек просто не работает.
Затем они затрудняют написание поддерживаемых регулярных выражений. Java до сих пор не разобралась в том, как писать многострочные строки, поэтому в итоге вы пишете такие безумные вещи, как это:
Каковы все эти новые строки? О, просто глупость Java. Они использовали комментарии Perl, а не комментарии Java ( идиоты! ), Которые идут до конца строки. Так что, если вы не положите их
\n
туда, вы отрубите остальную часть вашего паттерна. Дух и двойной дух!Не используйте регулярные выражения в Java: вы просто захотите разбить вещи, все это так больно и сломано. Я не могу поверить, что люди терпят это. Некоторые нет .
Тогда мы можем начать говорить об идиотской бессмыслице Java с кодировками. Во-первых, существует тот факт, что кодировка платформы по умолчанию всегда представляет собой неаккуратную 8-битную кодировку, даже несмотря на то, что в Java используются символы Unicode. Тогда есть то, как они не вызывают исключение при ошибке кодирования. Вы гарантированно получите дерьмо. Или как насчет этого:
Какая разница? Знаете ли вы, что только один из них вызовет исключение, если у вас есть ошибка кодирования? Остальные просто намордники.
Тогда есть идиотизм символов Java, не достаточный, чтобы держать характер! Что, черт возьми, они думают? Вот почему я называю их чарчарами. Вы должны написать такой код, если ожидаете, что он будет работать правильно:
А кто нибудь думает это сделать? Рядом ни с кем.
Сколько персонажей там
"\uD83D\uDCA9"
? Один или два? Зависит от того, как вы их считаете. Механизм регулярных выражений, конечно, работает с логическими символами, поэтому шаблон^.$
будет успешным, а шаблон^..$
- неудачным. Это безумие демонстрируется здесь:Этот идиотизм - все, потому что ты не можешь написать совершенно разумный
\u1F4A9
, и, конечно, вы не получите никакого предупреждения, что вы не можете этого сделать. Это просто делает неправильную вещь.Stoooopid.
Пока мы в этом, вся
\uXXXX
нотация врожденно умерла. Препроцессор Java ( да, вы слышали меня ) добирается до этого раньше, чем Java, поэтому вам запрещено писать совершенно разумные вещи, например"\u0022"
, потому что к тому времени, когда Java это видит, его препроцессор превратил его в"""
, и вы проиграете. Ой , подождите, не , если это в регулярном выражении! Таким образом, вы можете использовать"\\u0022"
просто отлично.Riiiiiiiight!
Знаете ли вы, что в Java нет способа сделать
isatty(0)
звонок? Тебе даже не позволено думать такие мысли. Это не будет хорошо для вас.И затем есть вся мерзость пути класса.
Или тот факт, что невозможно указать кодировку исходного файла Java в том же исходном файле, чтобы вы не потеряли его? Я еще раз требую знать: ЧТО, ЧТО ОНИ МЫ ДУМАЛИ?
Останови безумие! Я не могу поверить, что люди терпят этот мусор. Это полная шутка. Я бы предпочел быть приветствующим Walmart, чем страдать от слингов и стрел возмутительного безумия на Яве. Это все сломано, и они не только не могут это исправить, но и не могут это исправить.
Это те же самые люди-лисички, которые гордились тем, что сделали незаконным
printf()
функционирование. Ну и дела, что действительно сработало очень хорошо, не так ли?Чистые черепа. Шлепки слишком добры к ним. Если бы я хотел программировать на ассемблере, я бы. Это не подлежащий спасению язык. У императора нет одежды.
Мы ненавидим это. Мы ненавидим это навсегда . Пусть умирает, умирает, умирает !
источник
^H
Синтаксис объявления указателя функции в C и C ++:
Это объявляет указатель на функцию с именем,
f
чье pointee может принимать дваint
s и возвращатьint
.Я бы предпочел такой синтаксис:
Скажем, вы хотите объявить указатель на функцию,
g
чей pointee может взять дваint
s и функцию изint
иint
вint
, и вернутьint
.С нотацией C или C ++ вы бы объявили ее как:
С помощью предложенных выше обозначений то же самое может быть объявлено как:
Последнее гораздо более интуитивно понятное ИМО.
Кроме того: язык программирования под названием OOC исправляет этот синтаксис (и другие синтаксические проблемы в C и C ++). Проверьте его домашнюю страницу здесь .
источник
Многословие в Java.
то есть:
источник
const int
например.a+(b*c)/d*e+f/g^20
используяBigInteger
в Java. Почему этот язык не допускает перегрузки операторов?\ we \ notnt \ fix \ синтаксис пространства имен нашего \ parser в PHP
Синтаксис не только уродлив, он приводит к путанице, когда новым разработчикам приходится задумываться о пространствах имен в строках. (PHP интерполирует обратные слэши в строках в двойных кавычках в качестве escape-последовательностей. Попытка представить пространство имен, как
\you\should\never\do\that
в строке в двойных кавычках, а не в строке в одинарных кавычках, приведет к появлению новых строк, вкладок и к катастрофе.)источник
Я презираю тот факт, что фигурные скобки могут быть необязательными после оператора if / while / for.
Особенно, когда я вижу код, как,
Пожалуйста, просто вставьте скобки и покончите с этим.
источник
for (...) while (...) if (...) { x(); y(); }
, лучше переписать, какfor (...) { while (...) { if (...) { x(); y(); } } }
, с соответствующим отступом, конечно.VBScript не имеет логических операторов
В отличие от почти каждого разумного языка, VBScript использует побитовые операторы вместо логических операторов. Что это значит на практике? Ну, как отмечает Эрик Липперт :
а также
НЕ одинаковы в VBScript!
Еще хуже, хотя, это означает , что нет никакой оценки короткого замыкания в VBScript , так что следующий оператор будет врезаться вашей программой , если
Blah
ISNothing
Правильно, VBScript оценит обе части сравнения AND, даже если первая из них неверна! Просто позволь этому погрузиться ...
источник
If x Then ... If Not x Then ... End If ... End If
и выяснили, что x равен 2, вы на самом деле не программировали на VB / VBScript.РЕДАКТИРОВАТЬ: После обсуждения в комментариях я решил обновить этот ответ, чтобы объяснить себя лучше.
Я действительно ненавижу то, как указатели на функции выглядят в C. Обычно любое объявление переменной выглядит как кортеж:
type varname;
Объявления указателя функции, с другой стороны, выглядят как объявление функции с * перед именем функции. Я могу принять это как описание типа указателя, но в Си это объявляет как тип, так и имя переменной этого типа. Это выглядит противоречивым для меня, потому что объявления типов иначе отличаются от объявлений переменных.struct myStruct{int X; int Y;}
определяет только тип, но не определяет переменную с именемmyStruct
. Точно так же я не вижу причин для объединения объявлений типов и объявлений переменных в один атомарный оператор в указателях функций, а также я не ценю отклонение отtype varname;
структуры.Кто-то указал, что это согласуется с каким-то спиральным правилом, и это может иметь место, но признаком хорошего синтаксиса является то, что он говорит само за себя, а его внутренняя логика очевидна. Спиральное правило не очевидно ни в коем случае.
источник
typedef
.Точки с запятой в VBScript - или их отсутствие
Я провожу весь день, работая на языках, которые ожидают точки с запятой в конце каждой строки. Добавьте один конец строки в VBScript, и ваш код больше не будет выполняться.
источник
Аргументы в / из. Я весь в аргументах (хорошо, что я есть), наши аргументы тоже хороши, но аргумент, который должен передать эти два состояния, бесит меня.
Здесь я нацеливаюсь на функции, которые берут входные данные из параметра, а затем перезаписывают этот вход некоторым выводом. Это нормально, чтобы передать объект по ссылке, чтобы обновить его. Но, в основном, для примитивных типов: взять объект, использовать его, а затем полностью его изменить, я не прав. Вы не должны менять значение аргумента через inout.
источник
in
заin
аргументы, я просто говорю о них. Кроме того, по моему мнению, ничто не может оправдать аргументы in / out, и их явное выражение не снимает боль. Не должно быть никаких причин для инициализации локальной переменной значением, полезным для функции, и иметь эту же переменную, которая затем внезапно будет содержать все, что функция решила поместить туда. Эти два должны быть разными. Всегда.struct
где новое значение зависит от значения другого поля того жеstruct
.)class
объектов в C #), модифицируемые функцией, подходят мне. Кроме того, что мне не нравятся непостоянные структуры, передачаstruct
сref
ключевым словом для его обновления тоже подойдет. Что я действительно ненавижу, так это когда ввод перезаписывается выводом. Лучший пример, который я могу вспомнить, - этоaccept
функция сокета Беркли : ей нуженsocklen_t*
аргумент, который при вводе должен содержать размерstruct sockaddr*
передаваемого вами значения; и на выходе будет содержать количество байтов, которые были записаны в него. Это должно быть преступным.Объявления массивов в C и C ++.
Как правило, объявление переменной имеет формат
type variable_name
. Вы можете легко прочитать эти объявления слева направо. Ноint foo[size]
сначала выглядит так, будто оно объявляетсяfoo
как int, а затем вы читаете дальше и видите, что foo типа «массив целых чисел».int[size] foo
читает намного лучше.И я ненавижу, когда программисты объявлять указатели , как это по той же причине:
int *foo
. По какой-то причине я не понял, это типичный способ написания.источник
int* a, b;
что * не объявлятьa
иb
как указатели; толькоa
есть. Следовательно, лучше написать это какint *a, b;
(или даже лучше написать их как две декларации).*
, не привязывается к типу.void(int) *f;
? Нет:void (*f)(int);
int* a, b;
упомянутая вами проблема гораздо более вопиющая.Резервная параметризация в Java:
Что другой типа параметризация делает компилятор думает
foo
, может иметь?источник
HashMap<String,HashMap<String,String>> foo = Maps.newHashMap();
HashMap<String,HashMap<String,String>> foo = new HashMap<>();
What other type parameterization does the compiler think foo could have?
- По какой бы то ни было причине - это необработанный тип - как будто кто-нибудь в здравом уме даже смешивает необработанный и параметризованный типыПоскольку люди уже жаловались на «
=
против»==
, позвольте мне указать на гораздо худшую альтернативу. У PL / I было и то:=
и другое=
, но когда что-то было «очевидно» заданием, это позволяло бы вам избежать использования=
для этого. С помощью:=
позволяет вам заставить что-то быть присваиванием в ситуации, когда компилятор иначе интерпретирует это как сравнение.К сожалению, компилятор не всегда принимал решения так, как вы ожидаете. Рассмотрим только один очевидный пример:
Теперь, для большинства людей, знакомых с большинством "обычных" языков, смысл этого довольно очевиден - присваивать 0 как A, так и B. PL / I немного ... отличается. По причинам, известным только (безумным) разработчикам языка, первое
=
интерпретируется как задание, а второе=
- как сравнение. Следовательно, это сравнивает B с 0, а затем присваивает результат этого сравнения A (в соответствии с соглашением в стиле C, что «false» приводит к 0 и «true» в 1).Итак, если B было 0, то A становится 1. В противном случае A становится 0. Другими словами, вместо того, чтобы присваивать одно и то же значение A и B, это фактически гарантирует, что A не сможет иметь то же значение, что и B.
Итог: хотя изначально стиль C / C ++ / PHP кажется болезненным, альтернатива намного хуже 1 .
1 Технически, есть другая альтернатива: стиль Pascal, где
=
всегда означает, что всегда требуется сравнение и назначение:=
. После того, как вы используете это в течение некоторого времени, становится достаточно очевидным (по крайней мере для меня), что назначение является более распространенным, чем сравнение, что, если вам потребуется дополнительная «вещь» для устранения неоднозначности, вы должны определенно сохранять задания чистыми и простыми, и требует дополнительных «гранж» при сравнении, а не наоборот.источник
==
для равенства и:=
для назначения. Таким образом, вам нужно больше печатать, но избегание одиночества=
помогает избежать ошибок.Perl
if($x < 10) do_something();
. На данный момент вы должны написать это либо как, либоdo_something() if($x < 10);
какif($x < 10) { do_something(); }
.источник
do_something() if ($x < 10);
не так уж и плохоif(..) ...
при загрузке, так как все выражения выстраиваются в ряд справа. Но бывают моменты, когда я действительно хочу сказатьif($x < 10) do_something();
, и, к сожалению, Perl не позволит мне.if ($x<10) do_something(); and_call_me();
а потом удивляетесь, почему вам никогда не позвонят. Я хотел бы, чтобы C и семья потребовали фигурные скобки, чтобы предотвратить этот тип ошибки.else
. (Хотелось бы, чтобы это былоEXPR1 if COND else EXPR2
как у Python)reinterpret_cast<unsigned long>
в с ++. Эта операция полезна при работе с зарубежными API и обеспечивает точность числовых данных. Почему печатать так трудно и так уродливо?источник
reinterpret_cast
в C ++ - очень сильный запах кода. В 99% случаев, когда вы собираетесь его использовать, скорее всего, вам это не нужно - вы, вероятно, сделали что-то не так. Остальные 1% времени, когда вы взаимодействуете с C.,reinterpret_cast
ломает систему типов, чтобы заставить что-то работать, когда это иначе не может. Обычно это плохо.Конструкция for ... in в JavaScript и конструкция foreach в PHP при зацикливании массивов. Оба из них облегчают написание ошибок, чем правильный код.
источник
Указатели массивов или массивов указателей в C / C ++. Я все еще смущен этим.
источник
int[]*
это указатель на массив целых чисел иint*[]
массив указателей на целые числа. Хорошо работает и сconst
s:int* const
это постоянный указатель на целые числа, тогда какconst int*
иint const*
являются указателями на постоянные целые числа (или на целочисленные константы).int (*p)[10];
объявляетсяp
как указатель на массив из 10-ти. Еслиsizeof (int) == 4
, тогдаp++
продвинетсяp
на 40.Тот факт, что Python опирается на форматирование текста.
источник
Javascript / Java и т. Д., Равнозначное сравнение, например, если (a == 1)
Сколько раз я пишу, если (a = 1)?
Как человек, я прекрасно это прочитал. Но проклятый интерпретатор / компилятор говорит: «Эй, я назначу 1 для a, затем проверим, равно ли a 1, и вы поверите, да, это так!
Подводит меня к стене.
если (a == 1) гораздо менее читаемо, и интерпретатор / компилятор должен в любом случае знать, что я имею в виду; многие другие менее известные языки (VB) успешно работали в течение сотен лет.
источник
if (a = true)
должно означать?if (a == true)
, просто напишитеif (a)
. Если вы имели в видуa = true
, тоif
утверждение является избыточным.Многословие в Java анонимных классов. Будем надеяться, скоро исправят.
источник
structPointer->member
в C / C ++. Может быть хорошо читать чужой код, но мне это не нравится. Два персонажа вместо одного ... какая трата пространства!источник
.
, который применяется к элементам не указателя объекта. Неоднозначный синтаксис плох, мммкай?shared_ptr
, когда->
доступ к содержащемуся типу и.
доступ к свойствамshared_ptr
самого? Извините, но я здесь совершенно не согласен.->
для доступа к членам чего-либо .Многострочный код Scala в скобках
Например:
То, что вы на самом деле получаете от этого, потрясающе. Он генерирует конструктор, геттеры и сеттеры для вас. Но это, конечно, уродливо и ломает все мои ментальные модели того, как делать отступы в коде, и в основном заставляет меня чувствовать, что я нахожусь в каком-то странном бутерброде с Java с одной стороны и Lisp с другой. (Ой, подождите ... это скорее точка Скала.)
источник
val bar
и так далее) или часть в фигурных скобках (часть послеextends Model
)? (В этом коде нет скобок)