На свете много языков программирования и каждый из них обладает своими маленькими причудами — странным синтаксисом, необычным функционалом или нестандартными реализациями. Порой это сбивает с толку не только новичков, но и опытных разработчиков. Иногда эти причуды всерьез останавливают от изучения языка или, напротив, становятся известной фишкой.
Есть очень много подобных вещей в языках программирования, но мы выбрали для вас самые известные из них.
Пустые строки в Oracle SQL
Image courtesy Nic Hughes CC BY 2.0
Oracle считает строки нулевой длины эквивалентными NULL. Это существенное отличие от других БД и ANSI/ISO стандарта SQL, который подразумевает, что пустая строка — ранее известное значение, а NULL — неизвестное, и они не могут быть эквивалентны. Это может принести головную боль при написании кода для нескольких RDBMS или переписывании кода.
Возникла путаница в далёком 1979 году, когда вышла первая версия SQL, а соответствующий стандарт ещё не был разработан. Впрочем, в Oracle предупреждают, что в ближайшем будущем подобное явление пустой строки может исчезнуть.
Цитаты:
«Да, это одна из „прекрасных“ фич Oracle DB» — Lukas Eder
«Пустая строка эквивалентна NULL не больше, чем числу 0» — Ben Blank
«ЧТО!? Я так рад, что мы не используем Oracle. Это пугает» — Jeff Davis
+ как универсальный оператор конкатенации в JavaScript
Image courtesy MicroAssist CC BY-SA 2.0
Оператор + перегружен в JavaScript, и выполняет роль как математического сложения чисел, так и конкатенации строк. То есть если один из операндов строчный, а другой числовой, то условно вместо 1+1=2 вы получите ‘1’+1=’11’: JavaScript без предупреждения приведет число к строке.
Причина тому — недостаточный контроль за совместимостью типов. Например, в Python + используется ровно для тех же целей, но у вас ни за что не получится сложить число и символ.
Цитаты:
«Проблема в том, что скрытое приведение типов в выражениях непредсказуемо» — Anonymous
«JavaScript должен выбрасывать исключение в таком случае» — crgwbr
«+ для конкатенации строк — кошмар» — Matteo Riva
Модули Perl должны возвращать true
Image courtesy anthony kelly CC BY 2.0
Каждый модуль в языке Perl должен возвращать true. Если же этого не происходит, то разработчик рискует сильно подпортить себе карму и столкнуться с ошибкой компиляции.
Причина этого ясна и понятна, если понимать, что такое модуль в Perl. Программа компиляции, рассматривая подключённые к коду модули, в первую очередь проверяет их выполняемость. Даже если в модуле нет кода инициализации, Perl все еще ожидает получить на выходе True.
Цитаты:
«Эта штука всегда оставляет у меня тошнотворное чувство» — Drew Hall
«Это не имеет практического применения, учитывая непрерывно возникающее раздражение» — Schwern
Триграфы в C и C++
Image courtesy REUTERS/Gary Hershorn
Языки C и C++ поддерживают триграфы — трёхсимвольные обозначения, которые автоматически конвертируются в односимвольные. Так, например, комбинация ??! выдаст вам |. Если вы хотите максимально запутать необразованного врага, решившего прочитать ваш код, используйте вместо квадратных скобок комбинацию ??( и ??).
Смысл триграфов вовсе не в желании разработчиков языка обфусцировать код, а в том, что когда-то давно многие клавиатуры просто не содержали распространённых ныне символов, например фигурных скобок.
Цитаты:
«Google не поможет, если вы ищете что-то по запросу ??!??!» — Isaac
«Все так ненавидят триграфы, что C99 принес диграфы как альтернативу… еще больше обфускации» — dododge
«Радость триграфов — делает C нечитаемым с 1977 года» — Martin Beckett
Чувствительность к регистрам PHP
Image courtesy Gregg O'Connell CC BY 2.0
В то время как большинство языков программирования чувствительны к регистру, в PHP названия функций, классов и методов к нему нечувствительны. Но что наиболее сильно поражает разработчиков — то, что имена переменных, констант и свойства классов всё же регистрозависимы.
Доподлинно неизвестно, откуда повелось такое расхождение, но наиболее вероятный вариант — изначальное желание создателей PHP выделить интерфейс CGI в отдельный полноценный язык программирования.
Цитаты:
«Ну, это PHP. Не удивляйтесь» — Grzechooo
«Вот почему PHP-программисты используют подчеркивания вместо CamelCase, называя свои функции» — paperstreet7
«Я не имею ни малейшего представления о том, как создавать языки программирования...» — создатель PHP Rasmus Lerdorf
«Есть ли в PHP что-то, не вызывающее недоумения?» — Lambda Fairy
Истинный ноль в Ruby
Image courtesy DaveBleasdale CC BY 2.0
В Ruby 0 == TRUE. Это неожиданно, расходится с большинством других языков, включая Python и C, где 0 всё-таки FALSE, и часто сбивает с толку новичков в Ruby.
Причина в том, что в Ruby только boolean false и нулевое значение (nil) вычисляются в FALSE; все остальное имеет значение TRUE. 0 рассматривается как любое другое число.
Цитаты:
«Это может быть странным, если бы я не считал это неплохим» — Chris Lutz
«Вот почему я люблю Ruby. Мне не приходится иметь дело с таким zero-false злом» — Edditoria
«0==true // аргх, компилятор C в моей голове взорвался!!» — kenny
Пробелы в Python
Image courtesy Paul Kitchener CC BY 2.0
Вместо пунктуации или ключевых слов Python использует отступ для обозначения блока, к которому принадлежит строка кода. Неправильное количество пробелов или смешивание пробелов и табуляции может привести к ошибкам.
Создатели языка стремились сделать код более читабельным и уменьшить количество нажимаемых клавиш за счет того, что многие редакторы и IDE расставляют отступы автоматически.
Цитаты:
«Нет, правда: это то, что мешает мне когда-либо полюбить Python» — wazoox
«Я обожаю отступы в Python, но есть ньюанс: при копировании и вставке кода из Интернета это часто приводит к необходимости дополнительной очистки» — Greg
«Если вам нужны навязанные отступы, вы слишком ленивы» — Joris Meys
Массивы в C подчиняются арифметике указателей
Image courtesy BlueGum CC BY-ND 2.0
Кроме того, что можно получить ссылку на элемент массива как a[i], можно получить ее как i[a].
Причина в том, что массивы в C — указатели на блоки памяти, поэтому a[i]=*(a+i)=*(i+a)=i[a].
Цитаты:
«… это бесценно, когда вы участвуете в конкурсе обфускации C...» — Confusion
«Я не расцениваю это как особенность, это просто взгляд на ядро C. Все для указателей и максимально быстрого получения доступа к памяти. В некотором смысле это красиво» — Michael Neale
Предопределённые переменные Perl
Image courtesy Emily Mathews CC BY 2.0
Если внимательно ознакомиться с описанием языка Perl, можно найти достаточно большое количество предопределённых переменных с, мягко говоря, странными названиями (правда, имеющими достаточно длинный английский эквивалент).
Они служат для выдачи информации или обеспечения доступа к различным аспектам программы. Так, например, $@ — сообщение об ошибке, $$ — идентификатор процесса, $^V — используемая версия Perl. Новичкам приходится часто заглядывать в документацию.
Цитаты:
«Очень раздражает» — MatrixFrog
«Классная штука для однострочников, кстати» — niXar
«Я думаю, что худшие из них — $@ и @$. Работают оба, но я до сих пор не знаю, что делает второй...» — Artem Russakovskii
«Между прочим, есть еще серьезная проблема с этими переменными: они не гуглятся!» — malvim
Автоматическая вставка точки с запятой в JavaScript
Image courtesy Nate Angell CC BY 2.0
JavaScript требует установку точки с запятой в конце каждого законченного выражения. В случае, если этого сделано не было, а после идёт, скажем, пустая строка, JavaScript расценивает это как невнимательность разработчика и самостоятельно вставляет точку с запятой, что иногда помогает, но нередко приводит к ошибкам и неожиданному поведению программы.
Изначально вставка точки с запятой предназначалась для удобства, чтобы сделать C-подобный синтаксис JavaScript проще для новых разработчиков.
Цитаты:
«У вас точно будут проблемы, если вы разрабатываете язык с расчетом на то, что ваши пользователи идиоты» — Rob Van Dam
«Совет: выясните нужное место для точки с запятой и поставьте ее. Это лучше всего» — Doug Crockford
«Вставка точки с запятой — одна из злейших частей JavaScript» — fennec
Автоупаковка в Java и кеширование Integer
Image courtesy Erich Ferdinand CC BY 2.0
Java автоматически упаковывает примитивы в объекты, например, int в Integer. В целом ничего страшного, но Integer кешируется, если его значение лежит между -128 и 127. Это может привести к непредвиденным результатам в случае сравнения автоупакованных объектов, так как программа будет присваивать значение TRUE, если оба объекта имеют значение от -128 до 127, и FALSE во всех остальных случаях.
Autoboxing уменьшает количество кода, а кеширование Integer повышает производительность. Но нужно помнить о подводных камнях.
Цитаты:
«Вот результат преждевременной оптимизации» — Joschua
«Это не распространенная ошибка, но хороший повод использовать нативные типы Java для чисел, логических переменных и так далее» — Ravi Wallau
«Я так рад, что пишу на C#» — Will
Автор перевода: Илья Бубнов
___
P. S. Выбрать направление и начать обучаться по одной из технологий, о которых рассказывалось выше, можно на сайте GeekBrains.
Автор: GeekBrains