Змея / Говнокод #13688 Ссылка на оригинал

0

  1. 1
a < 5 and a or 5

Вы все еще думаете, что сочетание and'а и or'а это тернарник? Тогда мы идем к вам :)

http://ideone.com/qC0TyS

Запостил: bormand bormand, (Updated )

Комментарии (82) RSS

  • Хех, минусуют т.к. все уже знают, что это нихера не тернарник?
    Или минусуют, наоборот, те, кто думает, что я зазря эту конструкцию охаиваю? 🙂

    Нате вам тогда на закуску говнофикс, по методике со stackoverflow:
    (a < 5 and [a] or [5])[0]
    И люди на полном серьезе предлагают юзать эту хуиту как тернарник... Куда катится мир...
    Ответить
    • И даже на сайте ibm есть этот хак 🙂
      http://www.ibm.com/developerworks/linux/library/l-prog/index.html
      Причем тут даже не предупредили про подводный камень.

      А еще они там пропагандируют циклы делать в виде рекурсии... что питону вообще противопоказано, ибо он не умеет в tail-call optimization (намеренно не умеет, чтобы бектрейсы были полные и красивые).
      Ответить
      • хвостовая рекурсия успешно раскручивается в цикл

        Ведь простое лучше сложного)

        Вообще дао у питона очень верное
        Ответить
        • > хвостовая рекурсия успешно раскручивается в цикл
          Ну да. Они эквивалентны. Поэтому некоторые компиляторы, типа gcc умеют превращать хвостовую рекурсию в цикл.

          В питоне так не делают исключительно для красивых бектрейсов. И это, имхо, правильно. Один фиг это не ФЯП, такой как хаскель, в котором рекурсия это основа мироздания, а самый обычный императивный язык.
          Ответить
      • Вроде есть декоратор какой-то для хвостовой рекурсии, а вообще лиспоблядки соснули.
        Ответить
        • Там, если не путаю, брутальный хак, чуть ли не с декомпиляцией кода.
          Уж лучше явно развернуть.
          Ответить
  • А в чем собственно проблема? Я чет ничего неожиданного не заметил.
    Ответить
    • > А в чем собственно проблема?
      Посмотрите по ссылке на ideone вывод при a = 0.

      > неожиданного
      Ну да, результат вполне ожидаем. Вот только нубы бездумно юзают эту херню как тернарник, и потом неожиданно налетают на этот ожидаемый результат 🙂
      Ответить
      • Ну это тоже ожидаемо: 0 или 5, при том, что известно, что 0 эквивалентно False...
        Ж.скрипт так же работает, например.
        Ответить
        • Ну ожидаемо, да. Ожидаемо, что это не тернарник, а хреновая попытка его эмулировать 😉 Ожидаемо, что эта "абстракция" течет как проржавевшее ведро.

          У тернарника ведь определение: вычисляет левую часть, и возвращает ее результат, если условие истинно; вычисляет правую часть и возвращает ее результат, если условие ложно.

          > Ж.скрипт так же работает, например.
          Угу. На лиспе вроде тоже так можно?

          P.S. В общем суть в чем - не надо рекламировать эту херню, как замену тернарника. А если кто-то и рассказыват нубу об этом хаке - то пускай не поленится рассказать и про подводный камень. В питоне до 2.4 тернарника нет, и точка. А в жс есть нормальный.
          Ответить
            • > Нет, в Лиспе все числа = T.
              А or и and возвращают сами значения, или настоящие T и nil?

              UPD: Хотя да, там же false это только nil...
              Ответить
              • А кто это предлагал в качестве тернарника? Тут жеж явно нeсовпадение, тернарник не учитывает какой-там результат был у второго выражения.

                Есть такое понятие, как generalized boolean. Если функция описана, как возвращающая generalized boolean, тогда она может вернуть все, что формально является подклассом T, нe обязательно именно T.
                Ответить
                • > А кто это предлагал в качестве тернарника?
                  Питонисты 🙂 В питоне же относительно недавно появился их thenValue if cond else elseValue, вот они и выеживались как могли.
                  Ответить
                  • >относительно недавно
                    >Python 2.5 was released on September 19th 2006
                    Ага, недавно. Видимо, он просто некоторым людям так понравился, что они его юзают, даже не задумываясь о последствиях.
                    Ответить
                • > формально является подклассом T
                  Кстати, я туплю, или в лиспе все кроме nil является подклассом T?

                  > все, что формально является подклассом T
                  Ну вот в яваскрипте и питоне не совсем так. Там в спеках конкретно указано, что и когда оно возвращает. Т.е. там не какое-попало значение, считающееся true, а именно последний из рассмотренных аргументов and/or. И если бы там была такая свободная формулировка, как вы привели - этот or/and хак бы не родился, или сразу бы сдох как использование UB'а 😉
                  Ответить
                  • Если постараться, то можно... например, есть define-symbol-macro, и можно что-нибудь определить как nil... просто чтобы навредить кому-нибудь. Но из практических соображений вряд ли кто-то захочет что-то такое сделать.
                    Ответить
                    • > Но из практических соображений вряд ли кто-то захочет что-то такое сделать.
                      Ну, кстати, пустой список () это же алиас для nil (или наоборот), так что уже умудрились объявить 😉
                      Ответить
                      • Это скорее встроенный reader-macro, но принцип тот же, да.
                        Ответить
              • Зачем в лиспе тернарник? лисп сам как один большой тернарник
                Ответить
                • Действительно, там же (if cond thenVal elseVal) 🙂 Туплю сегодня.
                  Ответить
                • Зачем вообще тернарник? Дети, запомните, тернарник - это сахар. Он не особо и нужен.

                  Если в языке нету короткого паттерн-матчинга, или убогие свитчи(подвид:сишкоблядские), то только тогда полезно .
                  Ответить
      • >все равно какой-то костыль.
        Неужели в хацкиле как-то по другому?
        По мне лучше вынести в функцию:
        ter(a < 5 , (lambda: a) , (lambda: 5))

        А всё зло оттого что люди готовы пойти на любое преступление лишь бы чтобы не писать обычный, императивный if или for, ибо так-то скучно, немодно и вообще тупо... Тяга к "умному" коду до добра не доводит.

        Ну и отчасти конструкты не возвращают значения.
        Ответить
          • Не лениво. Выполняются обе ветки.
            Если конкретный случай, как тут и передается посчитанное значение, то вполне.
            Ответить
            • Не знаю питона, выражаю идею для ленивости:
              ter(a < 5, 'a', '5');
              ter(bool cond, string left, string right)
                  if cond
                      eval('return ' + left)
                  else
                      eval('return ' + right)
              Ответить
              • Строками... ну это что-то совсем из области фантастики 😉 Что-то мне подсказывает, что скопы будут корявые. Т.е. переменную a оно будет искать не там где надо, а внутри ter, и благополучно его там не найдет.
                Ответить
                • Из области фантастики - зато лениво. Гугление по python eval подсказало, что туда надо передавать какие-то global и local, но фиг его знает. Не даром у меня код обёрнут в гринколор. Да и не только со скопами будут траблы. Сработает ли вообще return внутри eval, и куда вернёт если да.
                  Ответить
              • Отлично, проверку / посветку синтаксиса убиваем совсем (даже по сравнению с тем, что есть). Уж лучше лямбды.
                Ответить
                • Вам видимо плохо видно зелёный цвет. Если не дальтоник - то попробуйте что-нибудь с этим сделать.
                  Ответить
                    • В фаерфоксе походу блинк тоже убили, как и в других браузерах ;( У меня теперь не то что код, а вообще ничего не мигает: тест.
                      Ответить
                      • Люди, кто знает как граватар настроить? на остальных сайтах работает - тут нет
                        Ответить
                        • Проверь, что в кабинке в личных настройках включен граватар.

                          Больше ниче не посоветую, мне граватар не светит. Во-первых домен, на котором висит это мыло, не принимается граватаром. Во-вторых я тупо забыл, на какое мыло тут зарегана учетка 😉
                          Ответить
                            • За несколько минут до этого была собака 😉 Может просто подождать пока кеши просрутся?
                              Ответить
                              • У меня и щас собака отображается. Я должен быть гопокот
                                Ответить
                                • Кот там, кот. Жди пока кеши обновятся (или почисти сам).
                                  Ответить
        • > Неужели в хацкиле как-то по другому?
          В хацкиле вообще банальный тернарник:
          if cond then thenValue else elseValue
          Ответить
          • В смысле ленивое выполнение, когда надо вычислить кусок кода из лямбды, а не непосредственное значение.
            Ответить
            • А, вон вы о чем. Ну костыль тут в сочетании and/or/lambda, а не в использовании лямбды для лени 🙂 Использование лямбды для лени это вполне нормальная практика, и наверное, вообще единственная для языков кроме лиспа.

              > По мне лучше вынести в функцию
              Если уж писать отдельную функцию, то в ней можно сделать человеческий if:
              def iif(cond, thenF, elseF):
                  if cond then:
                      return thenF
                  else:
                      return elseF
              
              iif(a<5, (lambda : a), (lambda : 5))
              Ответить
              • >то в ней можно сделать человеческий if:
                Именно. Да можно сделать джве функции: iif и lazyIif.

                Это то об чем говорилось выше: в языках с довольно развитой системой макросов или способов композиции кода тернарник не нужен вовсе. Поскольку не составит труда сделать свой средствами языка.
                Ответить
              • От чего же?
                Прозрачная запись, никаких хаков. А что еще, если не это?
                Ответить
                • Это же какая-то вывернутая наизнанку неупорядоченная питушня.
                  Сначала делаем, потом думаем, потом исправляем ошибки, если додумались до false.

                  Просто квантовая интегральная питушня <x|ψ|y> выходит.
                  <then|if|else>
                  Ответить
                  • Дело привычки, не более.
                    Остановись, если прибежал, иначе - беги
                    Если прибежал - остановись, иначе - беги

                    По-сути одно и тоже, только акценты расставлены по другому. Высказывание, где основное действие идет первым (x if y else z), будет понятнее в контексте программы, в том случае, если основное действие это продолжение алгоритма, а проверка условия - цикл или исключение. Так что все зависит от того как программист пишет, как привык писать и читать код. Читаем мы блоками, высказываниями, поэтому такая конструкция просто непривычна для тех, кто долго использует if x then y else z. Это все субъективно.
                    Ответить
                    • Привычка - дело серьёзное.

                      По мне - так тут как-то несимметрично относительно операндов-кандидатов-на-возвращение.
                      Если и использовать такой подход, то красивее он бы смотрелся в математическом смысле в выражениях вида
                      y = x, a<b | y, a>2 | z, a>4 | t, default
                      Ответить
                      • Пожалуй так и есть.
                        y = x if a<b else \
                            y if a>2 else \
                            z if a>4 else \
                            t

                        Это фактически копипаста из статьи "Тернарная условная операция" википедии, отредактированная под ваше условие.
                        Честно говоря, мне непонятно почему для таких ветвлений подходит, а как самостоятельная x if y then z - уже не нравится. По поводу симметричности не согласен =) A<- if ->B
                        P.S. Извиняюсь, если код "поехал", предпросмотра не имею.
                        Ответить
                        • Мне уже это "else" перед \ не нравится. И "t" тут особенное. Выделяется на фоне остального.
                          А в моём примере x, y, z и t стоят каждая в своём выражении, которое для всех одинаково.

                          Не надо это понимать, это
                          >>> Дело привычки

                          > По поводу симметричности не согласен =) A<- if ->B
                          В общем-то да. Ещё бы вместо then и else запилить <x|ψ|y> .
                          Ответить

Добавить комментарий

Где здесь C++, guest?!

    А не использовать ли нам bbcode?


    8