11 неожиданных особенностей языков программирования

Original author: Phil Johnson
  • Translation
На свете много языков программирования и каждый из них обладает своими маленькими причудами — странным синтаксисом, необычным функционалом или нестандартными реализациями. Порой это сбивает с толку не только новичков, но и опытных разработчиков. Иногда эти причуды всерьез останавливают от изучения языка или, напротив, становятся известной фишкой.

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

Пустые строки в 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
Образовательная площадка для программистов

Comments 175

    +16
    Странности есть во всех языках, а хейтят за странности только JS и PHP.
      +5
      Разработчиков в JS+PHP в разы больше, чем в прочих языках, потому и хейтеров также, в разы больше. Плюс, это языки для начинающих, которые делают свои первые шаги и набивают первые шишки. Потом набираются опыта и переходят в другие языки, а первые шишки помнят и ненавидят за них не себя, а языки.
        +14
        Потому, что это одни из немногих языков, где динамическая типизация ко всему прочему ещё и слабая.
          +12
          хочется назвать ее бессильной
          0
          JS и PHP — это языки для начинающих

          Вы чего такое говорите? Каких начинающих?
          Языки с кучей подводных камней и слабой типизацией намного сложнее, чем те, в которых этого нет. На Java или C# писать код проще, чем на Javascript, а качественный код тем более.
          Смысл скриптовых языков другой: на них можно гнать код быстрее. Так как жесткие правила в языках могут быть обузой при качественной архитектуре и покрытии модульными тестами.
          +13
          Просто у JS и PHP как в анекдоте "в вашем спирте крови не обнаружено", языки (при всем к ним уважении) это одна большая Странность. Так уж сложилось исторически, я помню как девелоперы JS сами угорали от видео про "логику" сравнений и приведений типов в JS.
          P.S. Пишу и на JS и на PHP и нисколько не считаю их плохими, просто их создатели изначально не рассчитывали на появление Node.js или что на PHP будут писать фейсбук, а сейчас кое-какие вещи сложно уже исправить из-за обратной совместимости, увы. :(
            0
            Я плохо знаю JS, но есть же фантастическая возможность использовать конструкции типа "use strict", позволяющие писать новый код с использованием нового синтаксиса. Почему бы не придумать что-то типа "use super-duper-operators" для исправления ситуации с совершенно непонятными для новичков операторами сравнения/приведения.
            Понимаю, наверняка, вопрос задавался не раз, и на него есть разумный ответ. Просто интересно было бы узнать, почему в комитете стандартизации до сих пор придерживаются крыше-сносящих практик.
              0
              Все очень просто, представьте вы работаете с Node.js или очень большим фреймворком в PHP, у вас в проекте уже сотни тысяч кода, которые импортируют сотни чужих модулей, которые состоят из миллионов строк кода и после использования "use super-duper-operators" в сотне мест как вашего кода, так и чужого поведение меняется на прямо противоположенное, там где был true стал false и наоборот. Вам придется потратить многие месяцы чтобы исправить все эти ошибки (если вы их вообще исправите).
              С другой стороны в экосистеме нет ничего хуже когда половина фреймворков и библиотек работает с одним флажком, вторая половина с другим. По сути единственный способ это придумать новый язык и как-то убедить всех на него перейти. У всех старых языков: Java, C++, Php, JS есть свои проблемы из-за совместимости.
                +3
                При грамотной реализации число ошибок интеграции со старым кодом будет минимально. Проблемы будут с привычками программистов.
                  0
                  По поводу перейти — у JS думаю нет с этим проблем, синтаксис ES6 все вроде приняли и уже сейчас с babel'ом используют.
                    0
                    0
                    TypeScript?
                      +2
                      Для этого есть eslint. И надо настроить сборщик, чтобы в прод не собирал, если что-то не прошло eslint.
                      Ну или TypeScript + tslint, как уже подсказали.
                      –5
                      В JS по сравнению с другими языками их слишком много, как мне кажется.
                      JS должен стать языком кросс-компиляции из Java, Kotlin, Python, C# и т.п. Ну или WebAssembly, если взлетит. Тогда про его странности забудут все, кроме создателей кросс-компиляторов :)
                        +1
                        JS должен стать языком кросс-компиляции из Java

                        GWT? Нет уж, не надо.
                          +1
                          Вы куда-то назад в прошлое полезли. Сейчас хотят вытеснить JS с этого "поста" тем же WebAssembly, а вы наоборот. Тогда получается и суть WebAsm'а пропадёт.
                            +1
                            Так я и говорю, если WebAsm взлетит. Пока-то возможности его практического применения нет?
                            GWT помер, но, как мне кажется, идея была правильной.
                              +1
                              Ну, во-первых, некоторые браузеры его уже ввели у себя. Во-вторых, WebAsm — по сути, язык-посредник. Это его основная роль. Ну, и в-третьих, JS — это скрипт, и, соответственно, передаётся в текстовом виде. WebAsm же бинарный. Т.е. при поднятии виртуальной машины имеем целых 2 плюса по сравнению с JS: снижение трафика и увеличение скорости обработки (всё же последовательность RISC команд проще спарсить, нежели скрипт). Ещё до его внедрения, года 2 назад, читал статейку, что производители аномально им заинтересовались (аномально в том смысле, что натолкнуть производителей на общий стандарт довольно сложно, а тут чуть ли не сами просились). Так что думаю, что не взлететь он может только из-за каких-либо фундаментальных косяков, но скорее всего над чем-то другим думать будут. Всё же JS как основа всего и вся — это костыль.
                                +1
                                WebAssembly не будет заменой JS. Собственно, сам webasm — низкоуровневая штука и основная его ниша — написание критичных к скорости частей кода. Наиболее очевидное применение — написание игровых движков. JS со своей инфраструктурой никуда не денется и будет дальше развиваться.
                                  +1
                                  А я и не говорил, что он будет заменой JS. Но для чего нужен JS? По сути, автоматизация веб интерфейса. А для чего используют? Кто во что горазд. У некоторых производителей по поводу WebAsm'а существуют небезосновательные амбиции перевода всего веб на WebAsm. Точнее так: вся инфраструктура останется, но будет робить под WebAsm'ом, в т.ч. и JS (т.е. компиляция JS в WebAsm), что имхо вполне логично и грамотно.
                                  • UFO just landed and posted this here
                                      +1
                                      Честно говоря, мне сложно ответить на ваш вопрос, но тезис:
                                      кроме исторически сложившегося и уже окостеневшего

                                      я поддерживаю. Я не особо ориентируюсь в веб, так что мои знания о JS:
                                      отсутствие типизации (что уже довольно странно); куча надстроек (исторически сложилось: в нём производители видели что-то вроде ассемблера для веб, но скриптовость явная помеха этому); по аналогии с VBS: урезанная java (на сколько — увы, не знаю, если на том же уровне, что vbs, то это печально); м.б. ещё что-нибудь знаю, но сразу не вспомню.
                                      Для меня из плюсов: неплохо дружит с батниками :)
                                      На сколько мне известно, пхп тоже довольно устаревший. Вот даже интересно, на чём сейчас современно сайты писать?
                                      • UFO just landed and posted this here
                                          +1
                                          Да какой там флейм… Сам я не веб программист, ближе к системному. Но с этим в РФ мягко говоря не очень (пресловутые китайцы). По этому и планирую в веб, скорее всего как раз на JS. Вот и хотел узнать, что ещё существует. У Вас вроде не полный список. Есть ещё что-то у майкрософта, но последние тенденции их IDE мне как-то не очень.
                                          • UFO just landed and posted this here
                                              +1
                                              А можно и на С++. Есть Erlang, Clojure, Scheme, Go, Haskel (!)

                                              Да и не только, в этот список можно включить любой язык, работающий со стандартным (консольным) вводом-выводом. Собственно, это всё одним словом и называется CGI (если конечно к кому-нибудь из них не привинтили транслятор в JS). С CGI немного имел дело, правда, так сказать, "по ту сторону баррикад": сервер с нуля поднимал. Время правда тогда не хватило, потом заброшен был. Думаю, ещё вернусь. Тогда это делалось всё на VB6 (Winsock Control+WinAPI), сейчас уже не плохо было бы на C++ + WinAPI.
                                              Кстати, а по БД какую-нибудь литературу можете посоветовать? Что-нибудь их проектирования. Просто есть жуткая проблема: как только сталкиваюсь с БД, код становится отменным набором костылей и велосипедов (либо тонны однотипных запросов, либо тщетные попытки реализовать в ООП), что раздражает.
                                              По поводу IDE, PHPStorm, я так понимаю, заточен под PHP? Мне Brackets советовали. Даже скачал, запустил. Вроде не тормозит, значит хороший.
                                              Ubuntu или Debian

                                              От Ubuntu (а точнее от KUbuntu) нехорошие впечатления остались. Вообще, я любитель аскетичного софта. В этом плане из окон люблю WinXP, а в Linux среде пока выбор стоит между Gentoo и Debian. Кроме того, приглянулась оболочка lxde.
                                              В остальном, спасибо за советы и пояснения.
                                              • UFO just landed and posted this here
                                                  0
                                                  Спасибо за развёрнутый ответ.
                                            0
                                            Всё же немного пофлеймлю :)
                                            PHP — я правда не понимаю, почему был выбран именно такой синтаксис: ->, =>, ::. Это и выглядит не очень, и писать неудобно (тире и угловая скобка находятся в противоположных рядах клавиатуры).

                                            Ruby и Perl — побратимы. Первый написан японцем, второй — лингвистом. Мне одному здесь видятся иероглифы и клинопись?
                                            def push(n)
                                                @args ||= []
                                                @args << n
                                            end

                                            %h = ("Lennon"=>"John","Lenin"=>"Leonid");
                                            print $h{"Lennon"}, "\n";
                                            $h{"df0"}="DF)";
                                            print %h,"\n";
                                            
                                            for(keys %h){
                                                print "$_","-","$h{$_}\n";
                                            }
                                            
                                            for(sort keys %h){
                                                print "$_","-","$h{$_}\n";
                                            }
                                            
                                            $h{"df01"}="DF)!";
                                            print scalar(%h),"\n";
                                            print values %h, "\n";
                                            print %h, "\n";
                                            
                                            for($i=0; $i<100;$i++){
                                                $h{$i}="$i";
                                            }
                                            
                                            print scalar%h,"\n";
                                            $h1{1}='1';
                                            $h1{01}="2";
                                            
                                            print scalar %h1,"\n";
                                            
                                            print $h1{1},"\n";

                                            ES6 — вместо того, чтобы решить вопрос с приведением типов (время как раз подходящее, babel сильно помогает в плавном переходе), они пихают синтаксический сахар и доп. способы объявления переменных… и еще одну реализацию ООП. 8(

                                            Python — проблема 3-й ветки в том, что хотели провести глобальную ревизию, но испугались из-за несовместимости с уже существующим кодом, потому получилось, что ветки почти взаимозаменяемы, вроде даже ВМ не тронули. Непонятно, зачем убрали range ;(

                                            Идеология питона — есть только один верный путь — не понятно откуда там десять вариантов. Я так понимаю вам был нужен этот код (выводит в консоль содержимое ответа по url с 101 символа и до конца):
                                            response = urllib2.urlopen('http://ya.ru')
                                            data = response.read()
                                            print data[100:]
                                            • UFO just landed and posted this here
                                              0
                                              >Мне одному здесь видятся иероглифы и клинопись?

                                              Да. Как и мне, когда я не знал языка.
                                    +1
                                    По-настоящему WebAsm «полетит», как мне кажется, тогда, когда его не просто поддержат все браузеры, а когда закостенелый энтерпрайз обновится внутри до нужной версии IE (или того, на что они там перейдут).
                                    JS неплохо минифицируется и достаточно шустро уже исполняется. Я не знаю как устроены современные JS-движки в браузерах, но не удивлюсь, если окажется, что внутри они на лету компилируют JS и исполняют его в виде байт-кода или вообще native-кода. Но, я согласен, это всё скорее просто из-за того, что «так заведено», или то самое «исторически сложившееся и уже окостеневшее», и нормальный с нуля разработанный под браузерные нужды байт-код конечно лучше.
                                    Аномальная заинтересованность мне тоже необычна; возможно это связано с тем, что поддерживать JS с его «особенностями» всех уже так достало, что вовремя поднятый флаг привлёк всех :)
                                      0
                                      Ну, я не говорил, что быстро взлетит. Бывает так, что хорошие технологии ну очень долго взлетают. Вспомнить тот же UEFI, который в базовом варианте существует с середины 90-х, а полноценная спецификация появилась в нулевых. При этом обширное использование началось порядка 6-7 лет назад. И то, сейчас какого-то толкового комьюнити по программированию и использованию UEFI нет, только голые стандарты, да горстка тем на форумах (стоит отметить, под встроенную виртуалку компиляторов, отличных от ассемблера я так и не нашёл). С настройкой ещё помогут, а программирование — тёмный лес. А некоторые даже не слышали о нём.
                                        0
                                        Большинство узнало об UEFI только в связи с выходом Windows 10.
                                          0
                                          Хотя первой из окон под UEFI была то ли виста, то ли семёрка. Причём, многие, у кого был UEFI об этом даже не знали. Понимаю у друга навороченный UEFI, там разительное отличие от BIOS, но на большинстве меню настроек идентично.
                                          • UFO just landed and posted this here
                                              0
                                              Да, была, но простые смертные действительно её не видели (а если быть точнее, не видели итаниум), поэтому не учитывал.
                                        0
                                        У V8 используется JIT: http://www.html5rocks.com/en/tutorials/speed/v8/
                                0
                                Не критикуют только мертвые языки, но с php, пожалуй, соглашусь.
                                  0
                                  Приведите пример на C#. Нет, я не злорадствую, мне действительно интересно и даже обидно что его тут не упомянули :)
                                    +1
                                    Ну, например:
                                    static void Main(string[] args)
                                    {
                                    SomeEnum thisEnum;
                                    thisEnum = (SomeEnum)50;
                                    Console.WriteLine(thisEnum); //50
                                    }

                                    public enum SomeEnum
                                    {
                                    One,
                                    Two,
                                    Three
                                    }
                                    Нет, понятно что enum это «integral type» и по дефолту «int». Но все же…
                                    В живую на это можно напороться принимая от девайса какие-то значения\состояния и дальше рассматривая их как enum. Например:
                                    public enum DeviceState
                                    {
                                    On,
                                    Off
                                    }
                                    А тут раз и девайс выдал недокументированное «Intermediate» состояние = 2. А дальше у вас switch или что-то такое. Утрированный пример, но разок такое было.
                                  +2
                                  При переходе с python на ruby, истинный ноль сначала ошарашивает, а потом понимаешь на сколько это красиво.
                                  В Go тоже присутствует автоматическая вставка точки с запятой и авторы советуют пропускать их там, где они не требуются явно. По началу не приятно, но на практике это правило приводит к красиво отформатированному тексту (плюс питона), без жестких требований (длинющие однострочники через; допустимы).
                                    0
                                    При переходе с python на ruby, истинный ноль сначала ошарашивает, а потом понимаешь на сколько это красиво.
                                    Можно подробнее???
                                      +8
                                      К примеру у вас есть выражение, отвечающее на вопрос "по какому индексу?". Ответ 0 покажет, что элемент присутствует и находится по 0 индексу, а значит должен расцениваться как true. К примеру:
                                      input = "test"
                                      puts "Match!" if /test/ =~ input
                                      puts "At: #{/test/ =~ input}"
                                      # Match!
                                      # At: 0

                                      Часто в выражениях "значение или значение по умолчанию" такие значения, как 0, "", пустые коллекции все же являются true значениями, а потому не должны заменяться значением по умолчанию:
                                      [0, 1, nil].each do |val|
                                        puts val || "(none)"
                                        # 0
                                        # 1
                                        # (none)
                                      end

                                      Во всяких однострочниках с boolean callbacks, где сторятся промежуточные выборки, не требуется писать (value || value == "") если фильтруем по строкам. Еще более это полезно, при работе базой данных, так что логика работы NULL, 0 и пустых строк отчасти совпадает. С другой стороны, в рельсах часто используется value.present?, чтобы добиться значения false от пустых строк, пустых коллекций и т.д. В целом, дело вкуса.
                                        –1
                                        Для меня как-то очень странно, что после работы с питоном для вас булевое приведение при поиске индекса подстроки в руби выглядит красивее, чем питоновский 'sub in string'
                                          +2
                                          Хех. Сразу вспомнился request.xhr? из rails возвращающий либо nil либо 0.
                                            +1
                                            про руби ниже написал ) Но тут тоже классные примеры приведены. Я к тому же вел — поведение конкретное изменить ничто не мешает, вопрос вкуса. А "голое" — очень понятно.
                                          0
                                          при переходе с php на ruby навсегда забываешь про конструкции типа if (strpos(...) === FALSE)
                                            +7
                                            Описание кейса в статье отвратительно неграмотное. Во-первых, в Руби нет ключевого слова или типа TRUE, это просто название константы, которая содержит значение true, и никто в сообществе саму константу не использует, ну да ладно, это привет сишникам с макросами из 90х. В языке нет неявного приведения типов с потерей данных, как в js и некоторых других плохо спроектированных языках. Т.е. в языке и true == 0 и false == 0 будет всегда однозначно false, потому что 0 и true/false — это разные типы. Вторая часть утверждения "только boolean false и нулевое значение (nil) вычисляются в FALSE" — полный бред с точки зрения языка.
                                            В чем же дело на самом деле.
                                            Дело в "хитром" устройстве операторов if, case и тернарного оператора, которые трактуют все значения, кроме nil и false, как true. В том числе это: 0, отрицательные числа, комплексные числа, пустые строки и полные массивы, объекты любых других классов и т.д. Ничего по факту не вычисляется, грубо говоря это проверка для "значение nil или false — значит выражение ложно, иначе — истинно". В языке верны только выражения true == true и false == false, все эти домыслы про 0 == true от незнания поведения такой простейшей конструкции языка, как условный оператор.
                                            На мой взгляд это логичное поведение оператора if и оно намного лучше, чем Сишное, где отдельных булевских типов не было, и пришлось заменять false нулем и потом таскать везде макросы #define FALSE 0. Зачем это поведение тащили в js — для меня загадка. К слову, Java и C# этот атавизм (0 == TRUE) не поддерживают и даже не скомпилируют код с ошибкой, что, на мой взгляд, является самым правильным решением проблемы в принципе.
                                              +1
                                              В lua, кстати, то же самое с истинностью. Это иногда удобно, а иногда удобнее вариант Python: здесь в стандартных типах ложно всё, что 0 или пусто, а в своих вы можете сами задать критерии. Конечно, приведение типа к bool вызовом метода сильно хуже с точки зрения производительности, но писать not obj вместо, к примеру, проверок на равенство длины нулю довольно удобно, если вы знаете тип obj.
                                              Требование использовать только и исключительно булевые значения в условии if является самым правильным решением, если вы пишете язык со строгой типизацией. Python и Ruby имеют варианты, соответствующие замыслу их авторов.
                                                +1
                                                #irb
                                                2.2.1 :004 > true
                                                 => true
                                                2.2.1 :005 > true.class
                                                 => TrueClass
                                                2.2.1 :006 > true.class.class
                                                 => Class

                                                так что тип (класс) TrueClass в руби есть
                                                  +1
                                                  Прочитайте мое сообщение более внимательно, я говорил про TRUE, а не про true.
                                                  2.2.3 :001 > TRUE
                                                   => true 
                                                  2.2.3 :002 > TRUE = false
                                                  (irb):2: warning: already initialized constant TRUE
                                                   => false 
                                                  2.2.3 :003 > TRUE
                                                   => false 
                                                +1
                                                При мемоизации, может быть функция/вычисление, чей результать любое целое число, вычисление тяжелое, но вычислить достаточно лишь раз при первом обращении. Если бы 0 == false, то необходимо завести дополнительный флаг, который бы показывал, что вычисление уже выполнено, а в случае Ruby имеем такие конструкции:
                                                def foo
                                                  @bar ||= begin
                                                    #вычисляем значение
                                                  end
                                                end

                                                Если результат может принимать значения true или false
                                                def foo
                                                  return @bar unless @bar.nil?
                                                  @bar =  #вычисляем значение
                                                end

                                                Если результат может быть и nil в том числе
                                                def foo
                                                  return @bar if defined? @bar
                                                  @bar =  #вычисляем значение
                                                end
                                                0
                                                В отличии от JS, в GO такое не сработает:
                                                func a() int {
                                                return
                                                3
                                                }

                                                Но в JS это полностью валидный код. Типизация помогает избавляться от таких ошибок.
                                                  +1
                                                  В Go многое не сработает, к примеру:
                                                  // скобки не обязательны
                                                  // сразу после ) компилятор поставит ';' и ругнется: missing condition in if statement
                                                  if (variable > 0)
                                                  {
                                                    fmt.Printf(variable)
                                                  }

                                                  Я видел многих людей и много guideline'ов для C-подобных языков, советующих переносить фигурную скобку на следующую строку для лучшей наглядности. Совет имеет смысл, но в Go нереализуем. Go вообще подходит с позиции мягкой силы. Красивое оформление кода награждается отсутствием ';'. Но если что, с компилятором идет gofmt, который превратит любую кашу в легко читаемый код. Обычно gofmt ставится на хуки в git, чтобы в репозитории все добровольно-принудительно придерживались одного стиля.
                                                    +2
                                                    Иногда приходится править исходники на других языках, добавляю строки без отступов, сохраняю и сразу возникает недоумение, почему они не стали на свое место? На столько привыкаешь к gofmt при сохранении файла.
                                                      +1
                                                      Тут вы не совсем правы, го не ставит; и потом ругается, го требует скобочку на той же строке, ибо это символизирует конец условия. Тут не в; дело, фигурные скобки — это отдельная независимая проверка.
                                                    0
                                                    Присоединяюсь к просьбе подробностей как истинный ноль (равно ложный ноль) может быть красивым. Мне кажется в языках подобных Ruby и Python, где есть полноценный булевский тип, вообще не стоит опираться на числовое значение как на булевское, как это принято в C, где полноценного булевского типа нет.
                                                  • UFO just landed and posted this here
                                                      +2
                                                      Город-побратим Нью Йорка? =)
                                                      • UFO just landed and posted this here
                                                        • UFO just landed and posted this here
                                                            0
                                                            Не во всяком ться есть лишний мягкий знак. Более того, правило применения тся/ться великолепно ложится именно на устную речь: http://tsya.ru/mnemonic.html
                                                            • UFO just landed and posted this here
                                                                0
                                                                Ну, не знаю, меня ещё в школе учили правилу "делает — делать"...
                                                                • UFO just landed and posted this here
                                                        –1
                                                        typeof null
                                                          +1
                                                          Есть эпичней :)
                                                          isNaN(NaN) // true
                                                          isNaN(undefined) // true
                                                          isNaN({}) // true
                                                          isNaN(new Date().toString()) // true
                                                          isNaN(«words») // true
                                                          • UFO just landed and posted this here
                                                            0
                                                            0
                                                            В Lua больше всего удивило, что индексы массивов начинаются с единицы и объекты присваиваются по ссылке, а не по значению.
                                                            a = {x = 1}
                                                            b = a
                                                            a.x = 2
                                                            print(a.x, b.x)
                                                            >2 2
                                                              +1
                                                              В Lua можно привыкнуть к тому, что индексы начинаются с 1, а вот отсутствие «continue» раздражает.
                                                                +2
                                                                Да черт бы с ним с continue, в Lua для побитовых операций надо библиотеку импортировать и функции оттуда вызывать!
                                                                Как вам нравится bit32.band(a,b) вместо a&b?
                                                                • UFO just landed and posted this here
                                                                    +1
                                                                    Обновитесь до Lua 5.3. Будет a&b.
                                                                    0
                                                                    (перенёс коммент выше)
                                                                    +13
                                                                    Обьекты почти везде по ссылке присваиваются а не по значению.
                                                                      +1
                                                                      Я, если не ошибаюсь, то в Lua массивы — это таблицы. И у них может быть не только нулевой, но и отрицательный индекс.
                                                                      А по умолчанию массивы начинаются с 1 из-за того, что вроде как, так сложилось исторически — Lua разрабатывалась для нефтяной промышленности, а там чуваки не секут в программировании — им привычней с 1.
                                                                      Скрытый текст
                                                                      Lua is descended from Sol, a language designed for petroleum engineers with no formal training in computer programming. People not trained in computing think it is damned weird to start counting at zero. By adopting 1-based array and string indexing, the Lua designers avoided confounding the expectations of their first clients and sponsors.

                                                                      Anyway, there are a couple conveniences to using 1-based indexing. Namely, the # (length) operator: t[#t] access the last (numeric) index of the table, and t[#t+1] accesses 1 past the last index. To someone who hasn't already been exposed to 0-based indexing, #t+1 would be more intuitive to move past the end of a list. There's also Lua's for i = 1,#t construct, which I believe falls under the same category as the previous point that «1 to the length» can be more sensible than indexing «0 to the length minus 1».

                                                                      Possible justification: C only did it because an array is basically just a pointer and array[0] == array + 0;, and 1-based counting is more natural when array is really a hash table.

                                                                      (http://stackoverflow.com/questions/2785704/why-do-lua-arraystables-start-at-1-instead-of-0)
                                                                        +1
                                                                        Отрицательный индекс (в отличном от «считать с конца массива» смысле) и в C есть: просто передавайте не начало массива, а середину, никто не запрещает. Но так весьма редко делают по той же причине, что и в lua: стандартные функции (та же free) рассчитывают на соблюдение определённых соглашений, Если та же #table для таблиц с нулевым первым индексом в lua всего лишь выдаст индекс последнего элемента (вместо длины) или 0 (для пустой таблицы, т.е. 0 будет для как для таблицы с одним, так и с нулём элементов), то table.concat просто проигнорирует первый элемент.
                                                                        Luajit #table ещё и странно оптимизирует: к примеру, в lua #{[0]=1, [2]=2} — это 0, в luajit это 2. Но это не «посмотри количество заполненных ячеек в хэше и проверь, есть ли элемент с таким номером»: #{[0]=1, [10]=3, [3]=2} даёт 0, #{[0]=1, [1]=3, [3]=2} даёт 1, a #{[0]=1, [2]=3, [3]=2} даёт 3, тогда как в lua только вариант с «0, 1, 3» даёт тот же результат, а остальные нули.
                                                                        • UFO just landed and posted this here
                                                                            +1
                                                                            Некоторые вещи с произвольными индексами не дружат. Например, как узнать размер массива:
                                                                            print(table.getn{[0] = 1, 2, 3})
                                                                            > 2
                                                                            • UFO just landed and posted this here
                                                                            0
                                                                            по уму ИНДЕКСЫ и должны начинаться с единицы, с нуля начинается СМЕЩЕНИЕ

                                                                            индексы с нуля упрощали перенос алгоритмов придуманных для линейного размещения данных в памяти
                                                                              0
                                                                              Индексы — это просто ключи доступа к элементам, они могут быть чем угодно и начинаться с чего угодно, и даже могут иметь разрывы в последовательности или вообще не быть последовательными. Индексами могут быть строки, например (ассоциативные массивы). Или ряд натуральных чисел. Или смещения в памяти. Выбор диктуется областью применения. Низкоуровневые массивы вполне естественно индексировать смещениями, для прикладных (математических) массивов естественнее натуральный ряд (Фортран, VB, Lua etc).
                                                                                0
                                                                                С единицы начинается номер элемента массива. А индексы массивы вообще говоря просто какое-то абстрактное множество. Целые положительные или целые неотрицательные числа — частные случаи.
                                                                                  0
                                                                                  Индекс всё-таки больше с номером ассоциируется — чаще имеет прикладное значение. А отсчёт с нуля — отсылка к (неактуальной) реализации. Мне кажется высокоуровневые абстракции должны быть ближе к естественному положению вещей. То, что в некоторых языках пытаются заново переосмыслить сущности, а не следуют догмам — хорошая практика.
                                                                              0
                                                                              В LabVIEW разным терминалам и индикаторам можно смело давать одинаковые имена (имена, кстати, можно вообще давать любые — набор символов ничем не ограничен).
                                                                              Это как если бы мы написали что-то такое:
                                                                              int x = 1;
                                                                              int x = 2;
                                                                              int y;
                                                                              int y;
                                                                              
                                                                              y = x + 3;
                                                                              y = x + 4;

                                                                              Одного взгляда вот на такой код будет недостаточно, чтобы сказать, каков будет результат:
                                                                              image
                                                                              Равно как и нельзя сказать, какой результат будет вот в таком случае, так как порядок исполнения операторов не определён:

                                                                              Всё это валидные конструкции. Их можно отловить статическим анализатором, но некоторых новичков это дело вводит в ступор.
                                                                                +2
                                                                                Oracle считает строки нулевой длины эквивалентными NULL

                                                                                Мне лично — это удобно и привычно.
                                                                                в Oracle предупреждают, что в ближайшем будущем подобное явление пустой строки может исчезнуть

                                                                                Ох и много legacy-кода в этом случае полетит с неожиданными ошибками-сюрпризами! Потому что, не я один исхожу из того, что строки нулевой длины эквивалентны NULL — я такое постоянно встречаю в унаследованном коде.
                                                                                  +1
                                                                                  Я вангую, что просто сделают опцию в базе данных, как рассматривать пустую строку, чтобы старый код не падал.
                                                                                    +1
                                                                                    Возможно, сделают тип VARCHAR с поведением, как по стандарту; и оставят тип VARCHAR2 таким же, как сейчас.
                                                                                    +1
                                                                                    в оракле не разбираюсь, но уверен естественно есть опция "не может быть NULL" или некие еще надстройки какие неоднозначность убирают.
                                                                                    Плюс валидация на уровне приложения. Не думаю что у ораклистов это "проблема" )
                                                                                    +1
                                                                                    Python:
                                                                                    a = ([1,2,3], )
                                                                                    a[0].append(4)
                                                                                    print a
                                                                                    a[0] += [5]
                                                                                    // exception
                                                                                    print a
                                                                                      +1
                                                                                      def a(somevar=[]):
                                                                                      somevar.append(1)
                                                                                      return somevar

                                                                                      print a() # -> [1]
                                                                                      print a() # -> [1, 1]
                                                                                      print a() # -> [1, 1, 1]
                                                                                      print a() # -> [1, 1, 1, 1]
                                                                                      От такого иногда плачешь немного недоумеваешь.
                                                                                        +1
                                                                                        Ну об этом в доках сразу предупреждают. Значения для аргументов по-умолчанию вычисляются только один раз, когда считывается файл модуля с этой функцией. Если значение mutable, получается что-то похожее на замыкание.
                                                                                          +1
                                                                                          Сам факт описан в доке, но не ясно каких целей придерживались авторы языка. К примеру в ruby/rails быстро привыкаешь писать:
                                                                                          def some_text_snippet(locale=I18n.locale)
                                                                                            # здесь locale = I18n.locale  будет вычислятся при каждом вызове
                                                                                            # в I18n.locale лежит язык пользователя, устанавливаемый из профиля, URL, Accept-Language и т.д.
                                                                                          end
                                                                                            +1
                                                                                            Я предполагаю, что тут речь идёт о том, что списки в питоне мутабильны, и аргумент в функции уже ссылается на существующий объект, так как функция компилится в момент объявления. Вроде так.
                                                                                            def a(somevar="asd"):
                                                                                                somevar = somevar + "v"
                                                                                                return somevar
                                                                                            
                                                                                            print a()    # asdv
                                                                                            print a()    # asdv
                                                                                            
                                                                                            print a("dfdsf")    # dfdsfv
                                                                                            print a("dfdsf")    # dfdsfv
                                                                                            
                                                                                            def b(somevar=['a','b']):
                                                                                                somevar.append('v')
                                                                                                return somevar
                                                                                            
                                                                                            print b()    # ['a', 'b', 'v']
                                                                                            print b()    # ['a', 'b', 'v','v']
                                                                                            
                                                                                            print b([1,2,3])    # [1, 2, 3, 'v']
                                                                                            print b([1,2,3])    # [1, 2, 3, 'v']
                                                                                            
                                                                                            x = ['o','p','q']
                                                                                            print b(x)    # ['o', 'p', 'q', 'v']
                                                                                            print b(x)    # ['o', 'p', 'q', 'v', 'v']
                                                                                              +1
                                                                                              Функция с таким же успехом могла компилироваться не в «код + значения по‐умолчанию» а в «код + код получения значений по‐умолчанию», как в Ruby, по словам предыдущего комментатора. Изменяемые списки тут не при чём, если они будут создаваться каждый раз при вызове, то таких побочных эффектов не будет.
                                                                                                +1
                                                                                                Но если взять за пример представленную выше функцию, то её аналог в руби будет вести себя по-разному в зависимости от того, передали ли мы в функцию аргумент, или нет:
                                                                                                def a(somevar=['q','w','e'])
                                                                                                    somevar.push('v')
                                                                                                    return somevar
                                                                                                end
                                                                                                
                                                                                                a()    # ["q", "w", "e", "v"]
                                                                                                a()    # ["q", "w", "e", "v"]
                                                                                                
                                                                                                x = [1,2,3]
                                                                                                a(x)    # [1, 2, 3, "v"]
                                                                                                a(x)    # [1, 2, 3, "v", "v"]

                                                                                                В общем, и в руби, и в питоне эти механизмы не являются интуитивно понятными, ИМХО.
                                                                                                Питоний стиль скорее "от вызова", а стиль руби — "от кода".
                                                                                                А вообще стоит всегда стараться использовать чистые функции :)
                                                                                                  +1
                                                                                                  В общем, и в руби, и в питоне эти механизмы не являются интуитивно понятными, ИМХО.

                                                                                                  ИМХО как раз в питоне не совсем очевидно, т.к. в тех языках что видел, значение по-умолчанию всегда подставляется новое, а не берется ранее вычисленное.
                                                                                          +1
                                                                                          Это как раз логично, append добавляет элемент к списку, модифицируя его in-place. a[0] += [5] эквивалентно a[0] = a[0] + [5], что создаст новый список и попробует записать его по нулевому индексу в tuple — но tuple неизменяем, и это невозможно, о чём exception любезно скажет. Если очень хочется, можно делать так: a[0].extend([4])
                                                                                            0
                                                                                            Магия тут в том, что после того как python выбросит Exception с ошибкой "Я не могу подифицировать tuple", мы можешь распечатать этот самый tuple и увидить что в массив внутри него все же был добавлен элемент.
                                                                                              0
                                                                                              Никакой магии. Просто код
                                                                                              a[0] += [5]
                                                                                              заменяется на что-то подобное
                                                                                              b = a[0].extend([5]) # расширяет list "in place"
                                                                                              a[0] = b # при присваивании выдается исключение
                                                                                              0
                                                                                              a[0] += [5] эквивалентно a[0] = a[0] + [5]

                                                                                              Нет, не эквивалентно.
                                                                                              x + y — берет аргумент x и y, получает сумму и ее возвращает.
                                                                                              x+=y — берет аргумент x и по месту его модифицирует, после этого возвращает его.
                                                                                              Поэтому во втором случае и получаем побочный эффект — исключение выдано, а список все равно изменился.
                                                                                                0
                                                                                                import operator
                                                                                                a = [1]
                                                                                                b = [2]
                                                                                                
                                                                                                c = operator.add(a, b)
                                                                                                c is a # False
                                                                                                
                                                                                                c = operator.iadd(a, b)
                                                                                                c is a # True
                                                                                              0
                                                                                              Можете привести кейсы, где пустая строка обязательно должна быть не NULL?
                                                                                              Я работал с Ораклом, и там пустая строка есть NULL ("" IS NULL), и это никак не мешало. Мне кажется это даже удобно.
                                                                                                +1
                                                                                                Строковой номер элемента:
                                                                                                1) пустая строка: кому-то лень было вводить артикул, но поля заполнили
                                                                                                2)Null: нет такого элемента
                                                                                                "Префикс" + Null = нет такого элемента, а не элемент "Префикс"
                                                                                                В конце концов Null превратить в пустую строку вобще не проблема, а понять где Null если уже всё слепили в один ком… это зло в чистом виде.
                                                                                                  +2
                                                                                                  Если в хранимой процедуре есть параметр типа varchar2, то вы никогда не узнаете, был он пустой намеренно или его просто не передали. Т.е. сделать апдейт в значения таблице на пустой или ничего не делать если он налл.
                                                                                                    0
                                                                                                    Т.е. сделать апдейт в значения таблице на пустой или ничего не делать если он налл.

                                                                                                    какая разница делать ли апдейт или нет. Ведь null — это и есть пустая строка в Оракле. Что сделал апдейт, что нет — одинаково. Вывод — апдейт можно не делать
                                                                                                      0
                                                                                                      Если в строке было значение и надо понять, скинуть его в пустое или не менять вообще, то определить это можно только лишними костылями.
                                                                                                    +1
                                                                                                    В результате для того чтобы отличать в оракле пустую строку от null вводится маркер, обозначающий пустую строку, обычно это единичный пробел — он отобразится в любом софте без обработки null. А потом, когда вы начинаете поддерживать что-то кроме оракла, вы не можете отказаться от этого маркера, т.к. нужна совместимость по sql, репликации и проч.
                                                                                                      +4
                                                                                                      Ну, например условие джойна. Вот там пустая строка и null будут очень сильно влять на логику
                                                                                                        0
                                                                                                        добавить в условие JOIN:
                                                                                                        OR (t.str is null and t2.str is null)
                                                                                                      0
                                                                                                      JavaScript: В Java тоже конкатенации строк + и она даже умеет складывать так числа и строки вместе в новую строку.
                                                                                                      PHP: Не чувствительность регистра есть в Pascal и Delphi, но больше всего странно то, что в php она только для методов, классов и функций.
                                                                                                      Ruby: Все таки думаю в ruby просто любой объект считают true, а 0 это объект в ruby, поэтому есть в этом своя логика.
                                                                                                        0
                                                                                                        Да, но в Java статические типы как аргументов, так и результата и ошибку с использованием + сделать значительно сложнее (вот деление double на int реально выносит мозг когда про него забываешь/не заметишь). На самом деле, оператор + и — в JS работает куда веселее когда в одном из аргументов оказывается массив, объект, null, undefined и т.п. Пересказать не смогу, лучше посмотреть видео тут (про JS начинают говорить с 1:20). Ну или почитать эту статью.
                                                                                                          0
                                                                                                          думаю в ruby просто любой объект считают true

                                                                                                          false и nil – тоже объекты
                                                                                                          0
                                                                                                          Чувствительность к регистрам PHP
                                                                                                          + как универсальный оператор конкатенации в JavaScript
                                                                                                          Автоматическая вставка точки с запятой в JavaScript

                                                                                                          Такие проблемы встречаются только в теории, а на практике никто в здравом уме не будет сложит 1 + '1' или назвать 2 метода с разным регистром.
                                                                                                            0
                                                                                                            а на практике никто в здравом уме не будет сложит 1 + '1'

                                                                                                            Ты можешь сложить две переменных, в обоих хранится число, но случится конкатенация, так как тип одной переменной строка.
                                                                                                            var text = "asd_234";
                                                                                                            var match = text.match(/_(\d+)$/);
                                                                                                            var a = match[1];
                                                                                                            var b = a + 3;//ожидаем 237, получим '2343'
                                                                                                            0
                                                                                                            В то время как большинство языков программирования чувствительны к регистру, в PHP названия функций, классов и методов к нему нечувствительны.
                                                                                                            Доподлинно неизвестно, откуда повелось такое расхождение, но наиболее вероятный вариант — изначальное желание создателей PHP выделить интерфейс CGI в отдельный полноценный язык программирования.

                                                                                                            Да все очень просто — очень часто название класса, функции или метода берется из URL и это сделано для того, чтобы однозначно, быстро и просто сопоставить некий URL вроде
                                                                                                            http://mydomain/verygoodcontroller/thebestmethod?params
                                                                                                            независимо от регистра — вызову конкретного метода в конкретном классе:
                                                                                                            class VeryGoodController
                                                                                                            {
                                                                                                                public function theBestMethod()
                                                                                                                {
                                                                                                                     ....
                                                                                                               }
                                                                                                            }
                                                                                                              +1
                                                                                                              Что-то сомневаюсь, что роутинг и контроллеры повсеместно использовались во времена PHP 1. :)
                                                                                                                +1
                                                                                                                Это плохо вяжется с class loading'ом по названию класса в PHP и регистрозависимостью имен в файловой системе Linux, например.
                                                                                                              • UFO just landed and posted this here
                                                                                                                    0
                                                                                                                    Это и есть перевод этой статьи
                                                                                                                      0
                                                                                                                      Скорее статья написана по мотивам опроса со stackoverflow.
                                                                                                                        0
                                                                                                                        Нет, в статье упоминается некто Artem Russakovskii, который есть на stackoverflow. Так что на stackoverflow раньше появилось.
                                                                                                                    0
                                                                                                                    никогда раньше на слышал и не встречал, чтобы в Си (и Си++) писали 4[arr]. специально сейчас проверил, думал на тип ругнется. не, сожрал.
                                                                                                                    меня еще в Си удивляет, что имя в объявлении структуры — это не тип.
                                                                                                                      +1
                                                                                                                      >меня еще в Си удивляет, что имя в объявлении структуры — это не тип.

                                                                                                                      Поясните, что конкретно удивляет? Объявление структуры никак не может быть типом, это совершенно разные контексты.
                                                                                                                        +1
                                                                                                                        Имеется в виду то, что в C есть пространство тегов структур/объединений/перечислений, отдельное от пространства имён типов. Т.е. в объявлении «struct T {… }» имя структуры (тег) «T» не является именем типа, ибо настоящим именем типа является «struct T». Отсюда извраты с повсеместным «typedef struct T {… } T»

                                                                                                                        В С++ это не так — тег класса (и, по аналогии, структуры/объединения/перечисления) автоматически объявляет новый тип, и можно запросто писать «T *t;» вместо «struct T *t;»
                                                                                                                          0
                                                                                                                          Между C и C++ как минимум 15 лет. Ну, хорошо, 10 :-)
                                                                                                                          Во времена разработки C это было нафиг не нужно (см K&R, даже не смотря на низкоуровневую ориентированность — структуры идут как бы «дополнением», которое особо не востребовано).
                                                                                                                          Для многих, кто познакомился со страусоповским изначальным C++, тогда C был именно как «C с классами», ну и с приятными фишками, типа этой :)
                                                                                                                      0
                                                                                                                      Оракловый NULL может показаться ужасным при хранении данных, но с точки зрения преобразования данных мы получаем некоторый плюс: конкатенация с NULL по факту работает как конкатенация с пустой строкой, а не обnullяет весь результат. Конечно обнуление строки при конкатенации с null тоже может использоваться в логике преобразований, но на моём опыте первое поведение требуется значительно чаще второго.
                                                                                                                      Да и стоит отметить, что код без кучи вызовов COALESCE/NVL выглядит чище и легче читается.
                                                                                                                        0
                                                                                                                        В JS ‘1’+1=2, а не '11', а вот 1+'1' = '11'. Приведение типов в операторе "+" идет по правому операнду.
                                                                                                                          0
                                                                                                                          Нет, результат будет одинаковым. И там и там будет '11'
                                                                                                                            0
                                                                                                                            Зато вот так прикольней :)
                                                                                                                            > undefined
                                                                                                                            undefined
                                                                                                                            
                                                                                                                            > {}
                                                                                                                            undefined
                                                                                                                            
                                                                                                                            > {}+1    // {} -- null?
                                                                                                                            1
                                                                                                                            
                                                                                                                            > undefined+1
                                                                                                                            NaN
                                                                                                                            
                                                                                                                            > {}+'1'    // {} -- wtf?
                                                                                                                            1
                                                                                                                            
                                                                                                                            > undefined+'1'
                                                                                                                            "undefined1"
                                                                                                                            
                                                                                                                            > {}+null    // {} -- null?
                                                                                                                            0
                                                                                                                            
                                                                                                                            > undefined+null
                                                                                                                            NaN

                                                                                                                            Пример несколько наигран — такой код вряд ли встретится в реальности ({} — здесь пустой блок кода), однако забавно.
                                                                                                                              0
                                                                                                                              {} — это не только пустой блок кода, но и пустой объект
                                                                                                                                0
                                                                                                                                Когда стоит в начале строки — это блок кода.
                                                                                                                                > x = {}+[]
                                                                                                                                "[object Object]"
                                                                                                                                
                                                                                                                                > {}+[]
                                                                                                                                0
                                                                                                                                
                                                                                                                                > +[]
                                                                                                                                0
                                                                                                                                
                                                                                                                                > x = { a:10, b:20 }
                                                                                                                                Object { a: 10, b: 20 }
                                                                                                                                
                                                                                                                                > { a:10, b:20 }
                                                                                                                                SyntaxError: missing ; before statement
                                                                                                                                
                                                                                                                                > a:100
                                                                                                                                100
                                                                                                                                
                                                                                                                                > { a:100 }
                                                                                                                                100
                                                                                                                          0
                                                                                                                          python:
                                                                                                                          a = 'dog' and 'cat'
                                                                                                                          print(a)
                                                                                                                          'cat'
                                                                                                                            +1
                                                                                                                            А что тут неожиданного?
                                                                                                                            Ruby
                                                                                                                            a = 'a' && 'b' => 'b'
                                                                                                                            b = 'a' || 'c' => 'a'
                                                                                                                            "И" требует истинности всех аргументов и вернется результат последнего вычисленного
                                                                                                                              +1
                                                                                                                              После C/C++, Java, C# и т.п. ожидаешь получить результат булевого типа: True или False, а не значение последнего вычисленного.
                                                                                                                                +1
                                                                                                                                Там скорее всего это связано с тем, что языки со статической типизацией и сравнивая теплое с мягким получить мокрое, в них будет разрыв шаблона.
                                                                                                                                • UFO just landed and posted this here
                                                                                                                                    +1
                                                                                                                                    Таки тернарный, просто сокращённый.
                                                                                                                                    • UFO just landed and posted this here
                                                                                                                                        +1
                                                                                                                                        Просто один аргумент можно невозбранно выкинуть. Причём не только второй, но и третий.
                                                                                                                                        • UFO just landed and posted this here
                                                                                                                              0
                                                                                                                              Каждый раз заходя в Python я вижу более менее одинаковый код, чего нет в остальных языках.
                                                                                                                              Именно поэтому идея с отступами гениальна!
                                                                                                                                +2
                                                                                                                                Идея хороша, но не всегда удобно. Скопируешь себе кусок интересного кода и вместо того что бы начать с ним [s]играться[/s] работать начинаешь выполнять квест: выделил фрагмент ->Ctrl+[ или Ctrl+]… И так пока не заработает.
                                                                                                                                  0
                                                                                                                                  Тут есть плюс в том, что вместо бездумного копипаста приходится хоть немного в код смотреть в процессе выравнивания :)
                                                                                                                                –5
                                                                                                                                Ха, Оракловские NULL строки им видите ли не нравятся. А то что в Яве (и где еще? шарп, не? не в курсе) все сравнения с нормальных == и ли != превратились в сущий пипец .equalsTo() — про это никто не вспомнил. А код стал похож на овно.
                                                                                                                                  +4
                                                                                                                                  А какое из множества равенств (т.е. отношений эквивалентности) вы считаете более «нормальным»:
                                                                                                                                  1) идентичность: a == b истинно лишь когда a и b — один и тот же объект
                                                                                                                                  2) бинарное равенство: a == b истинно лишь когда содержимое a и b одинаково вплоть до каждого бита
                                                                                                                                  3) посимвольное равенство: a == b истинно, если содержат одинаковые символы текста, даже если у них разная кодировка
                                                                                                                                  4) смысловое равенство: a == b истинно, если содержат текст с одинаковым смыслом, даже если отличаются кодировка, регистр, некоторые символы заменены эквивалентами (например, немецкое двойное с) и т.п.
                                                                                                                                  • UFO just landed and posted this here
                                                                                                                                    0
                                                                                                                                    в Perl модулях необходимость возвращать true связанна с этапом компиляции, на котором выполняется код модуля и есть возможность вернуть false если что то пошло не так. смешные цитаты про бесполезность и раздражение ))
                                                                                                                                      +1
                                                                                                                                        +1
                                                                                                                                        В рубях, на самом деле, здравый подход. false это nil (аналог null пустого значения с оговорками) или сам false. Все остальное true. То есть, с одной стороны если вы кодируете такие методы и исключения какие возвращают nil, беспокоиться не о чем. Единый подход.
                                                                                                                                        Но даже если Ваш метод что-то другое возвращает, проверок различных можно сделать массу.
                                                                                                                                        Это удобно, ребят )))) Избавляет от размышлений является ли false пустая строка (в руби — конечно нет!). И стимулирует использовать родные методы например к строке это .zero?
                                                                                                                                          +2
                                                                                                                                          В Ruby 0 == TRUE

                                                                                                                                          это не так:
                                                                                                                                          #irb
                                                                                                                                          2.2.1 :001 > 0 == true
                                                                                                                                           => false

                                                                                                                                          ну и для полноты картины:
                                                                                                                                          2.2.1 :002 > 0 == false
                                                                                                                                           => false
                                                                                                                                            +1
                                                                                                                                            имелась автором в виду не проверка на равенство а вывод в логических выражениях видимо:
                                                                                                                                            puts "это правда" if 0 # число 0 не рассмотрено как false, будет выведен текст "это правда"

                                                                                                                                            то есть все что не nil и не false рассматривается как true в логических выражениях:
                                                                                                                                            puts "Сработало" unless nil #это работает, противоположность nil - true в логическом эквиваленте
                                                                                                                                            puts "Сработало" unless false #это тоже работает
                                                                                                                                            puts "Сработало" if 0 #тоже сработает, 0 - не false
                                                                                                                                              +1
                                                                                                                                              но безусловно я с Вами согласен если заявление звучит как 0 == true это не правда. Как Вы и показали в irb. Эти величины проверку на сравнение не пройдут. Только логическую. Поставил Вам плюс )
                                                                                                                                              +1
                                                                                                                                              В C++17 триграфы убрали.
                                                                                                                                                +1
                                                                                                                                                А до этого отключили по умолчанию во всех компиляторах, вроде.
                                                                                                                                                +1
                                                                                                                                                Еще в MySql CONCAT('colum1','column2') вернет null если в column2 будет null. Неудобно, когда надо соединить firstname, middlename и lastname, ведь middlename есть не у всех.
                                                                                                                                                  +1
                                                                                                                                                  Это для всех SQL справедливо, кроме Oracle.
                                                                                                                                                  +1
                                                                                                                                                  Но что наиболее сильно поражает разработчиков — то, что имена переменных, констант и свойства классов всё же регистрозависимы.
                                                                                                                                                  Вот тут не соглашусь, так как за все время программирования на пхп не сталкивался с этой проблемой решил специально проверить данное утверждение в PHP 7. Все работает в независимости он регистра.
                                                                                                                                                  Как обычно, на пхп гонят завистники :)
                                                                                                                                                  Myth Busted!
                                                                                                                                                  • UFO just landed and posted this here
                                                                                                                                                  • UFO just landed and posted this here
                                                                                                                                                      0
                                                                                                                                                        0
                                                                                                                                                        Всякие особенности Python:
                                                                                                                                                        https://docs.python.org/2/faq/design.html
                                                                                                                                                          0
                                                                                                                                                          К особенностям Oracle можно отнести механизм sequence, довольно отличительная черта от остальных RDBMS строящие таблицы с автоинкрементном. А вот строки нулевой длины эквивалентны NULL удобно. Не хотелось бы, чтоб это правило в дальнейшем поменялось.
                                                                                                                                                          • UFO just landed and posted this here
                                                                                                                                                              0
                                                                                                                                                              Остальные — это MySQL? Postgre знает sequence (по сути только его и знает), MS знает.
                                                                                                                                                                0
                                                                                                                                                                В MS SQL сравнительно недавно появился sequence. На практике пока встречаю, что многие еще не используют данный механизм
                                                                                                                                                              0
                                                                                                                                                              Конечно же от этого больше плюсов — сквозные "айдишки", кэширование, шаг инкримента, начальная/конечная позиция. Но реакция пользователей других СУБД примерно такая же как и когда узнают про is null, вместо = ''
                                                                                                                                                                0
                                                                                                                                                                В Perl есть два разных набора операторов сравнения — один для строк, другой для чисел: http://ru.perlmaven.com/sravnenie-skalarov-v-perl


                                                                                                                                                                Нужно следить за кавычками в print:
                                                                                                                                                                @i = ('a', 'b', 'c');
                                                                                                                                                                print "@i";    # a b c
                                                                                                                                                                print @i;      # abc

                                                                                                                                                                Списковый оператор print. Для запятых слева от него он имеет наименьший приоритет, но повышает приоритет правой запятой.
                                                                                                                                                                @i = ('a', 'b', print 'c', 'd');
                                                                                                                                                                print "\n",@i;
                                                                                                                                                                # cd
                                                                                                                                                                # ab1

                                                                                                                                                                Only users with full accounts can post comments. Log in, please.