1. Куча / Говнокод #11423

    +121

    1. 1
    (reverse (butlast ...))

    Родное :)

    Запостил: wvxvw, 16 Июля 2012

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

    • Говно в том, что работает вдвое медленнее, чем (cdr (reverse ...))?
      Ответить
      • я вообще удивлён, что wvxvw использует reverse, а те nreverse
        Ответить
        • А вдруг в этой задаче исходный список нельзя портить?
          Ответить
          • butlast же новый сконструирует, nreverse переиспользует эти ячейки вмето того, чтобы новые создавать, исходный список не изменится.
            А вообще я к тому, что он не любит функциональный код.
            Ответить
            • А, вы про изначальный вариант - там да, nreverse вполне подойдет. А в моем (cdr (reverse ...)) - нет.
              Ответить
      • Угу. И, да, нужен был новый список. Странно, что тема так быстро набрала положительную ауру, я даж и оглянуться не успел :)

        Ох, так у меня и (defun butlast! () ...) есть! :Р
        Ответить
        • А (defun butthead! ...) есть?
          Ответить
          • http://wiki.guildwars.com/wiki/Headbutt

            Только он бесперспективный вообще его можно разве что некро-бомберу, но для них есть лучшие элитные скилы.
            Ответить
      • /me порывается откомментить, что мол в хаскеле и так нормально, но, вспомнив нелюбовь тс к нему, не решается.
        Ответить
        • Ну кстати, в теории, разница будет и там...

          А вот практика - вариант с tail . reverse потребляет процентов на 12% меньше памяти:
          Prelude> sum $ (tail . reverse) [1..100000]
          4999950000
          (0.16 secs, 18141096 bytes)
          Prelude> sum $ (reverse . init) [1..100000]
          4999950000
          (0.16 secs, 20616380 bytes)
          Ответить
          • >А вот практика - вариант с tail . reverse потребляет процентов на 12% меньше памяти:
            зачем копетанишь?
            А вообще странно, что скорость у второго варианта не меньше
            Ответить
          • т.е. переворачивание списка из каких-то несчастных 100к целых требует 20Мб памяти?
            Ответить
            • Так это не требуемая память. А сумма всех запросов к аллокатору.

              Т.е. запросто может показать и 20гиг, при том, что ни в какой момент времени программа не потребляла более мегабайта.
              Ответить
              • но ведь разместив список 1 на 100к элементов и сделав из него список 2 на 100к элементов, это чудо должно попросить у аллокатора не более 2*(100к*размер ноды + обвязка для объекта "список")

                допустим 64-битная система, целое и указатель хранятся в 8 байтах, список двунаправленный (врядли стоит надеяться, что там массив, верно?), значит на элемент 24 байта, итого 2*(24*100к + небольшое K для объекта "список") выходит около 5Мб, кто съел еще 15?
                Ответить
                • Посмотрел более подробную статистику в откомпилированной программе: пиковое потребление - 1.6 метра (как раз на 2 односвязных списка по 100000 нод, состоящих из 32битного указателя и 32битного инта). У аллокатора было запрошено в сумме 9 метров (тот запуск с 20метрами это все-таки была интерпретация).

                  Вот эти 7.4мб скорее всего ушли на thunk'и для ленивых вычислений, которые в хаскеле создаются тоннами. Надо бы посмотреть подробную раскадровочку в профайлере - но сегодня лень.
                  Ответить
          • Prelude> sum $ (tail . reverse) [1..100000]
            4999950000
            (0.13 secs, 21013984 bytes)
            Prelude> sum $ (reverse . init) [1..100000]
            4999950000
            (0.08 secs, 17709816 bytes)
            Prelude>
            Ответить
          • Подождите, это же сто тысяч а не миллион? Или я что-то не понимаю?
            (defun range (from to)
              (labels ((%range (to so-far)
                         (if (> from to) so-far
                             (%range (1- to) (cons to so-far)))))
                (%range to nil)))
            (time (reduce #'+ (cdr (reverse (range 1 100000)))))
            Evaluation took:
              0.013 seconds of real time
              0.012001 seconds of total run time (0.008001 user, 0.004000 system)
              [ Run times consist of 0.004 seconds GC time, and 0.009 seconds non-GC time. ]
              92.31% CPU
              35,844,066 processor cycles
              6,401,216 bytes consed
              
            4999950000
            Ответить
            • При правильном подходе разница между языками небольшая
              http://tinyurl.com/cyuprke
              Лисп даже в среднем больше памяти жрёт.
              Ответить
              • Так я же про конкретный пример спросил. При чем тут тесты чего-то другого? Я же не делал это специально для того, чтобы выиграть в скорости (тот же nreverse будет мало того, что меньше памяти занимать, так еще и быстрее, range можно делать по несколько элементов за раз вместо по одному, родовой плюс можно заменить конкретной его разновидностью и т.д. и т.п.)
                Ответить
        • Просто потому, что такой интуитивно понятный и легко читаемый функциональный код:
          (funcall
           ((lambda (fn)
              ((lambda (x)
                 (funcall fn (lambda (a b)
                               (funcall (funcall x x) a b))))
               (lambda (x)
                 (funcall fn (lambda (a b)
                               (funcall (funcall x x) a b))))))
            (lambda (x)
              (lambda (a b)
                (if (cdr b) (funcall x (cons (car b) a) (cdr b)) a))))
           nil '(1 2 3 4 5))

          работает всего самую малость медленнее чем такой убогий и запутанный:
          (cdr (reverse '(1 2 3 4 5))
          Поэтому нужно использовать именно его!
          Ответить
          • Вы так говорите, как будто
            (cdr (reverse '(1 2 3 4 5))
            - не функциональный код.
            Ответить
            • В нем недостаточно вай-комбинаторов, карринга и замыканий.
              Ответить
              • Вы так говорите, как будто функциональный код обязательно должен состоять из каррированных замыканий вай-комбинаторов...
                Ответить
                • Он кстати не каррированый, и меня это очень раздражает, т.как феншуй нарушен (вай-комбинатор вызывает функцию с двумя аргументами, но это не универсально, и тут-то как раз бы и хотелось применить каррирование, чтобы можно было сколько угодно аргументов!

                  Так если писать программы без вай-комбинаторов, каррирования и замыканий на Хаскеле - получится тот же Си под редакцией очень креативного эстето-полиграфисто-неневистника.
                  Ответить
              • Если вы считаете, что функциональный код должен быть очень сложным, вы ошибаетесь. Кстати, каррирование и замыкания - это очень удобно и просто.
                Ответить
                • См. мой ответ выше. Хаскелл не представляет никакой ценности, если эти все вещи из него убрать (разве что маленьких детей пугать заставляя запоминать всякие нелепые комбинации символов и значений, которые им назначены).

                  > Кстати [...]

                  Добавьте в код выше каррирование, так чтобы вай-вай-комбинатор мог вызывать функцию с произвольным количеством аргументов! Проще ж не бывает (и, пожалуйста, без прикрас, расскажите о том, сколько времени у вас это заняло).
                  К сожалению, для полноты эксперимента нам нужно будет существенно больше времени, т.как через год, когда вы забудете, что именно сделали, вернуться к этому же коду и понять, что именно он делает может занять ну, с полчаса, хорошо если.
                  Ответить
                  • Y-комбинатор вроде бы довольно редко используется.
                    Код выше на хаскеле выглядит так:
                    tail $ reverse [1, 2, 3, 4, 5]
                    -- or declare new function
                    revtail = tail . reverse
                    Лепить лямбды в haskell нужно очень редко (ибо каррирование).
                    Ответить
                    • > Y-комбинатор вроде бы довольно редко используется.

                      Смотря в какой ипостаси. В принципе к нему можно(?) отнести fixIO :: (a -> IO a) -> IO a.
                      А он уже нужен например для гуйни (когда обработчик, скажем, одноразовый и должен уметь отцепляться):
                      ret conn <- object `on` event $ handler conn

                      p.s. ret - сахар для "классового" mfix, в данном случае fixIO.
                      Ответить
                  • Вай-комбинатор, который может вызывать функцию с произвольным количеством аргументов...

                    Так?
                    http://ideone.com/kol8B

                    Сколько времени заняло... да собственно минут 5-10.
                    Ответить
                    • А где же тут каррирование? Функции принимают кучу аргументов... :/
                      Ответить
                      • > где же тут каррирование
                        КО: в комбинаторе
                        Ответить
                        • Так это не то, что требовалось.
                          Ответить
                          • >> Добавьте в код выше каррирование, так чтобы вай-вай-комбинатор мог вызывать функцию с произвольным количеством аргументов!

                            В представленой вами формулировке задача решена полностью.
                            Ответить
                            • Ну кроме "в код выше". Т.к. у меня с лиспом не очень, хотя в свое время и запиливал на нем тетрис.
                              Ответить
                          • Поясните, пожалуйста, что не так? Y-комбинатор есть. Он принимает функцию с любым количеством аргументов (там под ним как раз 2 примера с разным количеством).
                            Ответить
                            • Всё норм, но на примере факториала выглядит надуманно - функция test по-прежнему выглядит рекурсивно (пуст и опосредованно через аргумент)
                              Ответить
                              • > функция test по-прежнему выглядит рекурсивно (пуст и опосредованно через аргумент)
                                Хм. Так соль Y комбинатора как раз в пропихивании функции в качестве ее же первого параметра. Или я туплю?
                                Ответить
                              • http://ideone.com/dMtt3
                                Чтобы не выглядело рекурсивно ;)
                                Ответить
                            • В складывании порядок вычислений не важен, а в разворачивании списка - важен. Каррирование имелось в виду в функции разворачивания списка (где факт того, что функция вызывается рекурсивно позволяет сохранить все значения ячеек в стек и потом их забрать от туда в обратном порядке). Для складывания - все равно в каком порядке это делать, а для конкретной задачи - нет. В этом, вобщем-то и была ирония.

                              А то, что в Хаскелле функции от нескольких аргументов по-сути и так всегда карринговые - так как бы ну и что? Это можно расценивать как ответ в духе "а я могу использовать мега-крутую библиотеку, которая все умеет". Речь шла о понимании, как устроена библиотека, а не как ее можно использовать.
                              Ответить
                              • > а в разворачивании списка - важен
                                Вы о чем вообще? Какой порядок?

                                http://ideone.com/tM98r
                                Ну вот передал Y комбинатору функцию для переворачивания списка. Списки из 10млн элементов пережевывает без проблем.

                                > Речь шла о понимании, как устроена библиотека, а не как ее можно использовать.
                                Речь идет о том, что вы очень туманно ставите задачу.
                                Ответить
                                • Чёта мне кажется, что вАААй комбинатор совершенно не удобен. Он только удлиняет код.
                                  Ответить
                              • Напиши решение своей задачи на другом языке, а мы повторим. Пока я вижу, что задача раз за разом меняется, а мыbormand её каждый раз решаем, а вы чем то по прежнему не довольны и придумываете новую.
                                Ответить
                                • У задачи нет хорошего решения... как бы об этом и речь. В моем примере выше один из аргументов функции используется для накопления а другой для перечисления. В случае с каррированием такой номер не пройдет. То, что написал bormand не делает каррирования, функция по-прежнему вызывается с несколькими аргументами.
                                  Каррирование, это когда у вас из функции f(a, b) получается функция f(b)(g(a)), т.е. у вас есть только функции от одного аргумента.
                                  В Хаскелле это поведение всех функций по-умолчанию (частичное применение) и вам не нужно ничего специально делать, чтобы этого эффекта добиться, но реализовать этот эффект самому (чтобы наглядно объяснить что оно делает) - тяжело, а в конкретном случае - мне даже тяжело придумать как это сделать без всяких "нечесных" способов.
                                  Ответить
                                  • >но реализовать этот эффект самому (чтобы наглядно объяснить что оно делает) - тяжело
                                    Вы имеете ввиду какой-нибудь лисп? Тогда понятно.
                                    Ответить
                                    • Имею в виду Хаскелл, по моему так и на писал, или выделить подчеркиванием?
                                      Ответить
                                    • > Вы имеете ввиду какой-нибудь лисп
                                      На лиспе вообще невозможно написать нормальное каррирование. Ведь могут быть функции с необязательными параметрами и переменным числом параметров. Определить каррирование для таких функций невозможно. В частности, поэтому в хаскеле кол-во аргументов строго фиксировано.
                                      Но можно сделать вменяемый вариант, работающий только при ограничениях на характер потребляемых аргументов.
                                      Ответить
                                  • Т.е. решать эту задачу на хаскеле это читерство? Ок.

                                    Вот честные лямбдочки, каждая из которых принимает ровно 1 параметр.
                                    http://ideone.com/OJB5r

                                    P.S. Y комбинатор взят с RosettaCode и немного допилен под каррированные функции.
                                    Ответить
                                    • Подождтите, и вот что, вот этот ваш код он прямо такой супер-понятный? О чем жеж речь изначально была? В обычной ситуации, я бы такой код переписал даже не делая попыток прочитать.
                                      Решать конкретную задачу на Хаскелле - это читерство потому, что вы пользуетесь "встроенной" возможностью, работу которой требовалось объяснить / продемонстрировать. Точно такое же читерство, как если бы понадобилось объяснить устройство сборщика мусора, а вместо этого вы бы использовали язык со встроенным сборщиком мусора.
                                      Ответить
                                    • Да, и ваш комбинатор допилен ровно на столько, что может обработать каррированую функцию с двумя аргументами, А если их будет 3, а если больше? Будете для каждой такой функции по отдельному вай-вай-комбинатору добавлять? :)

                                      Но вообще, серьезно, демонстрация была предназначена показать плохую читаемость и понимаемость таких практик в общем случае, а не конкретно на то, чтобы запилить универсальный вай-комбинатор для каррированых функций.
                                      Ответить
                                      • > Да, и ваш комбинатор допилен ровно на столько, что может обработать каррированую функцию с двумя аргументами,
                                        Что-что? Да хоть со 100500:
                                        (lambda (next)
                                          (lambda (x)
                                            (lambda (y)
                                               (lambda (z)
                                                 ...))))

                                        Приведенный Y-комбинатор вполне съест любую каррированную функцию. Я не спорю, что вызов каррированной функции на лиспе смотрится ужасно. Но он же работает.

                                        > плохую читаемость и понимаемость таких практик в общем случае
                                        Ну правильно. Еще остается довести все до абсурда, и применить нумералы чёрча вместо чисел...
                                        Ответить
                                        • Лисп честно показывает ту акробатику, которую нужно проделать в уме для того, чтобы понять концепцию. То, что эта акробатика спрятана за ширмой в Хаскелле не делает ее более понятной.

                                          Что-то я очевидно не досмотрел в вашем комбинаторе, но на первый взгляд, все его отличие от канонического варианта было в том, что он добавляет один funcall сверх запланированного. Возможно я ошибся, т.как код очень тяжело понять :)
                                          Ответить
                                      • > А если их будет 3, а если больше?

                                        http://ideone.com/qDR1M
                                        Тот же самый Y-комбинатор примененный к функции с другим числом аргументов. Слив засчитан.
                                        Ответить
                                        • Ложь, наглая ложь! :) вы же добавили еще funcall - так каждый может. Это не тот же комбинатор, что и в предыдущем варианте.
                                          Но я уже вижу как код становится все понятнее и понятнее с каждой правкой!
                                          Ответить
                                          • > Ложь, наглая ложь! :) вы же добавили еще funcall - так каждый может.
                                            Если вы внимательнее посмотрите на код, я добавил funcall'ы не в сам комбинатор, а в вызов функции которую он возвращает.

                                            > Но я уже вижу как код становится все понятнее и понятнее с каждой правкой!
                                            Согласен ;)

                                            > Лисп честно показывает ту акробатику, которую нужно проделать в уме для того, чтобы понять концепцию.
                                            Вот только зачем мне проделывать эту акробатику и понимать концепцию каждый раз, когда я пишу код? Хватило бы и одного раза. Тот же ассемблер тоже помогает понять архитектуру, но люди почему-то стараются писать на языках более высоких уровней.
                                            Ответить
                                          • http://ideone.com/kLR9V
                                            Нате ;) Макрооберточки для каррированных функций. Чтобы вызовы и описание оных не смотрелось как говно.
                                            Ответить
                                • Это пример "решения" с каррированием (но, естественно, как и было заявлено, не хороший):
                                  (funcall
                                   ((lambda (fn)
                                      ((lambda (x)
                                         (funcall fn (lambda (a)
                                                       (funcall (funcall x x) a))))
                                       (lambda (x)
                                         (funcall fn (lambda (a)
                                                       (funcall (funcall x x) a))))))
                                    (lambda (x)
                                      (lambda (b)
                                        ((lambda (a)
                                           (if (cdr b)
                                               (nconc (funcall x (cdr b))
                                                      (funcall x (cons (car b) (car a))))
                                               (list (car b))
                                               ))
                                         nil))))
                                   '(1 2 3 4 5))
                                  Ответить
              • Уже тоньше.
                По сабжу: разве не плюс, когда есть альтернатива записать код в более близком виде к смысловой нагрузке?
                Ответить
                • Смысловая нагрузка? Да что вы говорите? Хаскел позволяет записать мысль в зашифрованном виде близком по форме к значкам придуманных шумерами и ассирийцами и плохо скопированными в средние века переписчиками далекими от понимания предемета.

                  При чем вся практически без исключения современная наука так выглядит. Вместо того, чтобы пользоваться универсальной и понятной системой записи ежики жрут кактус собранный из значков разных стран времен и народов, который они мало того что вслух по-человечески произнести не могут, так и изза того, что не могут используя эту же систему создавать новые сущности в необходимом количестве используют по-новой те же закорючки в новом контексте.
                  На фоне того, что человечество вообще достигло в теоретическом плане понимания языка, хранения и понимания информации, математические закорючки - неимоверный анахронизм. Его современное использование ничем не обосновано.
                  Чего там за примерами далеко ходить, моя профессор по дискретной математикe путалась в греческом алфавите и иногда называла маюскульные буквы неправильно, например гимму называла альфой, и хоть застрелись! Особенно полезное свойство, когда в контексте есть и то и другое.

                  А как на счет отличить фрактурную минускульную си от любой другой си, если вдруг у вас книжка на немецком, и набрана фрактурой?
                  В контексте иврита (в котором нет минускульных/маюскульных букв, зато есть огласовки) алеф-ноль читается как алеф-халом (о). И т.д.

                  Хаскел - это апогей этого кретинизма, когда не взирая ни на какие разумные доводы люди пытаются использовать римские цифры вместо арабских / восьмеричной / шестнадцатиричной системы.
                  Ответить
                  • Ну конечно, математическая нотация теперь корень всех зол.

                    Есть чёткие соглашения насчёт того, какие буквы что обозначают в конкретных областях, это негласный стандарт. Любой вменяемый редактор научного журнала пошлёт вас подальше, если вы будете обозначать греческими буквами натуральные числа.

                    Алефы вообще влезли в традиционно греко-римскую нотацию из-за рассово-верного еврея Кантора.

                    Профессора бывают разные. Когда мой научник полез в справочник за определением гиперболического синуса, я разочаровался в современной отечественной науке и с головой ушёл в промышленное программирование.
                    Ответить
                    • > Любой редактор ...

                      Только, давайте для начала разберемся. Я работал в издательстве 4 года, а до этого еще 6 учился на полиграфиста. И я думаю, что не пошлет, а очень даже посочувствует. Сужу не только по опыту, но исходя из имеющихся знаний и понимания теории, о которой у вас в лучшем случае очень расплывчатое предстваление, если вообще какое имеется.

                      Более того, прогрессивное человечество вполне даже в курсе проблемы, например, поэтому существуют такие проекты как "простой английский", lojban и т.п.

                      Подождите, значит алефы - это фигня, и на нее не нужно обращать внимание, а как на счет особых шрифтов и некоторых букв из этих шрифтов - например буква f из позднего французкого барокко (интеграл). Или, про что уже упоминалось, фрактурной си?

                      Существуют соглашения? Да ну? Я даже в контексте одного курса по дискретной математике насчитал три разных значка для записи разницы сетов. Три различных значка (но вполне вероятно их есть еще) для записи логического отрицания. А чего только может не значить запятая - тут просто кроме интуиции и счастливой случайности ничего не поможет разобраться.
                      Соглашений нет, никто ни с кем не соглашался, более того, никто даже не предпринимал серьезной попытки что-то с этим сделать.
                      Или, еще пример, те, кто учились в совке верят в то, что есть такой символ "делится на", а те, кто учился, например в штатах про такой значек (три вертикальные точки) ничего не знают, но зато у них есть неизвестный в совке значек "число делит другое" (записывается как вертикальная черточка). И где только не используется эта вертикальная черточка...
                      Ответить
                      • > например буква f из позднего французкого барокко (интеграл)

                        Интеграл к f не имеет никакого отношения. Это деформированная буква S (сумма). Говорим спасибо Лейбницу.
                        Ответить
                        • Известных математиков было много, и каждому захотелось вбросить свой вклад в развитие типографского дела.
                          Абсолютно не важно какую букву подразумевал Лейбниц когда задумывал интегралы. Важно то, что используется каллиграфическая f из чего-то смутно напоминающего рафинированый курсив Петрарки.
                          Ответить
                  • Действительно, вы мне открыли глаза.. Усложненная нотация в той же математике.
                    Нафига например тензоры, ведь: "некогда думать, надо матрицы расписать".
                    Ответить
                  • Ну и само собой: переход от конкретного примера к "закорючкам" вообще несколько надуман.
                    Разве tail . reverse, показанное [color=blue]bormand[/code] не читабельно?
                    Или вас "." смущает в контесте ЯП? Ну здесь, слава ТНБ, операторы не сильно отличаются от ф-ий, делаем линк и записываем:
                    tail `compose` reverse

                    Кстати, есть и такое, только вы аккуратно по ссылке ходите, ежели пойдете: http://hackage.haskell.org/packages/archive/base-unicode-symbols/0.2.2.4/doc/html/Prelude-Unicode.html
                    Ответить
                    • > Кстати, есть и такое
                      Привет из APL?
                      Ответить
                    • У меня нет никаких претензий к ЯП или к функциональным языкам в частности. У меня есть претензии к проектировщикам конкретного языка Хаскелл, которые придумали кретиническую систему записи, но как говорил Лев Николаевич Толстой (не помню дословно, но более-менее) то, что кажется непонятным и требует больших усилий на понимание, после прилагания этих самых усилий вырастает в ценности вне всякой пропорции, хотя приложенные усилия и ценность результата не связаны.

                      Я могу ошибаться, т.как давно читал, но, iirc это говорила Княжна Ольга то ли в беседе с Безуховым то ли в письме к кому-то. Но не суть.

                      ТНБ и иже с ними - не нужно, более того, вредно, т.как мешает а не содействует пониманию того же материала. Заставляет заучивать кучу закорючек. Вот вы тут пример привели. И вам кажется что это читабельно. Но, на самом деле, человек с опытом чтения разноплановой литературы прийдет в недоумение от вашего примера:
                      1. Ни один из популярных языков мира не расставляет слова в таком порядке (мозг нужно напрячь, чтобы переставить их в читабельную форму).
                      2. У обратных апосторофов есть куча значений (Баш / ПХП - системный вызов, экранирование, мета-кавычки и т.д.).
                      3. Эта форма ничего не говорит о порядке применения функций (вообще не понятно, функции это или нет).

                      Увидев текст выше вне контекста я бы интепретировал это как вызов системной утилиты compose (которая очевидно возвращает какие-то опции которые можно использовать с утилитой tail) и чтение из файла под названием reverse количество строк указанных в compose. С другой стороны: tail(reverse(x)) не оставил бы никаких сомнений в смысле интерпретации.
                      Ответить
                      • Не нравятся композиции - пишите (tail (reverse x)).
                        Ответить
                        • <ванга-мод> Сейчас вам скажут, что \ x -> ... непонятно что (частично я согласен), от "\" ожидается экранирование, а выносить в let или where иногда накладно.
                          Ответить
                          • Да, символ \ как эмуляция символа "лябмда" - это нечто.
                            Ответить
                      • > И вам кажется что это читабельно.
                        Не говорил, что сразу. Привычка нужна, да и редактор, подсвечивающий операторный вид ф-ии не помешает.
                        > 2. У обратных апосторофов есть куча значений
                        Кто первый встал, того и тапки?
                        > 3. Эта форма ничего не говорит о порядке применения функций
                        Чуть-чуть говорит: если помнить, что оператор, тогда логично, что это (∘). Можно было бы then = flip (.). Вроде так меньше однозначностей.

                        И всегда можно явно передавать аргументы, как указал bormand. point-free можно не придерживаться, но, имхо, если в меру - удобно.

                        > Увидев текст выше вне контекста я бы интепретировал это
                        Это скорее межязыковая проблема. Для backquote ведь общих соглашений? (в смысле по сравнению с + - et cetera).
                        Ответить
                        • Первыми встали французы в веке 16-17, так что Хаскелл тут явно в пролете.

                          Эта форма говорит что-то ограниченному кругу ограниченных людей, нормальным людям она не говорит ни о чем. Это попытка сохранить никому не нужную традицию вопреки здравому смыслу (необходимости понимания тебя другими людьми).

                          Так я и пишу (tail (reverse x)) только Хаскелл мне для этого не нужен. Более того, мне более приятен язык, который не допустит херни с разными вариантами написания, потому что я хочу не только свой код читать, но и код других людей тоже.

                          Особо хотелось бы взять и уебать г. Декарта за "поинт фри" - это кажется была его идея не писать значек умножения между множителями. При всех его заслугах перед математикой, столько говна в типографию как математики не привнесли даже музыканты.
                          Просто для сравнения: страница рукописи на заре моей юности стоила 5 шекелей у студента и 10 у машинистки. Страница рукописи с шахматными диаграммами, нотами и прочей херней - от 50 шекелей. Математические формулы - обычно просто посылают нахуй, простите, но именно так. Ни одна профессиональная машинистка по доброй воле не возьмется их печатать. (что уж и говорить о корректорах!)
                          Причины такой нелюбви банальны:
                          - нет никакой возможности автоматически проверить напечатанное ввиду эзотерической манеры письма.
                          - очень тяжело понять (даже просто прочитать вслух!) практически любую нетривиальную формулу.
                          - нет никакой возможности механически взаимодействовать с источником. Автор написанной херни должен в буквальном смысле вычитывать каждую строчку. Процесс просто мучительный.
                          - даже при наличии ЛаТеКса набор требует запоминания неимоверной кучи хаотически определенных пиктограм и последовательностей.
                          Ответить
                          • Математики разрабатывали нотацию не для того, чтобы её было удобно верстать, а чтобы она была понятной (для них), отражала структуру и занимала мало места (меньше писать от руки + больше помещается в область зрения + меньше чернил уходит).
                            Ваши претензии напоминают мне случай с Бетховеном: скрипачи пришли к нему пожаловаться, что им сложно играть произведения мастера.
                            Бетховен был в бешенстве: "Какое мне дело до ваших скрипочек, когда во мне горит вдохновение!".
                            Ответить
                            • И что? От этого музыку Бетховена чудесным образом стало легче играть? Что это доказывает?
                              Я говорю, что Хаскелл больше всего похож на неведомую средневековую херню, а вы мне говорите "а за то он похож на неведомую средневековую херню которую понимает несколько человек, которые разбираются в неведомой средневековой херне".

                              Да! Я с вами согласен, именно так и есть.
                              Ответить
                              • > И что?
                                А то, что вы воспринимаете математическую нотацию как вещь в себе, нотацию ради нотации. На самом деле это лишь механизм, способ передачи глубоких идей и закономерностей.
                                Мне абсолютно ВСЁ РАВНО, насколько сложно играть allegro ma non troppo девятой симфонии или allegretto седьмой или allegro assai 23 сонаты или presto agitato из 14 или <подставьте удачный музыкальный фрагмент>. Меня гораздо больше волнует сама музыка, чувства, которые она вызывает, нежели трудности, возникающие при её воспроизведении (уж поверьте, техничность в музыке - лишь вершина айсберга). Ноты, техника, скрипки, клавиши - это всё средство, механизм достижения высшей цели. И, чёрт возьми, Бетховен прекрасно умел достигать эту цель. А скрипачи... Да кого волнуют их трудности?

                                Вот и ваши жалобы на сложность нотации/синтаксиса у меня лично других эмоций кроме ЛОЛЧТО не вызывают.
                                Ответить
                                • К примеру со скрипачами. Скажем так, затраты музыканта на освоение инструментов общения не существенны по сравнению с затратами на исполнение / написание музыки.
                                  Есть очень немного областей человеческой деятельности в которых изучение инструмента (а не того, как добиться необходимого результата) представляют существенный процент. Такими областями являются, например, авиация (очень важно знать КАК управлять самолетом, а не куда лететь).

                                  Иногда такая расстановка приоритетов оправдана и не вызывает неудобств. Нет ничего плохого в том, что всего 0.01% людей будет летчиками или музыкантами, и не стоит тратить сил на разработку лучшей нотной записи или изготовление упрощенных самолетов.

                                  Но с математикой ситуация совсем не такая. Чем больше людей ей будут владеть и чем лучше - тем лучше для этих самых людей вне зависимости от рода деятельности. Это не наука для "избранных", где можно закрыть глаза на "исторически сложившиеся обстоятельства" и послать недовольных.
                                  Ответить
                                  • Запилим свою? Блекджек гарантирую.
                                    Ответить
                                  • Вы очень легкомысленны. Скрипку в общей сложности нужно осваивать лет 15-20, если не больше. На фортепьяно - звук готовый, а тут ещё нужно потеть и корпеть над звукоизвлечением.
                                    И уже оставшуюся половину жизни копить репертуарю
                                    Ответить
                            • Ее и писать-то не очень удобно. Вы все время говорите про "удобно", "читаемо" и остальные суперлативы никогда ни с чем не сравнивая. Я не знаю, может вы с утра как проснетесь сразу зубной щеткой в нос, а потом штаны через голову и сигаете из окна на работу - так вам и Хаскелл удобным кажется.
                              Но у этих слов есть практическая мера установленная экспериментальным путем: человек в среднем может запомнить Х слов, в кратросрочной памяти хранить У слов, произвести Н перестановок, предугадать К ситуаций и т.д. Это все, конечно, не константы, но диапазон более-менее известен и его можно вполне оценить доступными инструментами. Перeдачу информации в виде текста можно оценить в смысле удобства экспериментальным путем. О чем я выше и говорил. Математические формулы объективно плохой пример передачи информации, на шкале между узелковым письмом и нотами, но скорее ближе к узелковому письму.
                              Ответить
                              • Если вы считаете, что в haskell много сущностей, вы глубоко заблуждаетесь. Их всего 5: модули, типы, классы, экземпляры классов и функции (Java: пакет, класс, примитивный тип, массив, метод, статический метод, поле, аннотация, исключение, оператор, ...). Да, есть несколько синтаксических сахароз: do блоки, операторы, инфиксная нотация, let и where. $ и . объявлены стандартными средствами в Prelude, можете их не импортить.
                                Собственно, переубедить мне вас всё равно не удастся.
                                Ответить
                                • Это равносильно утверждению, что в С++ нет строк, а в Лиспе кроме универсального интерпретатора состоящего из read-eval-print - так вообще ничего нет.
                                  Есть язык со сложившимися практиками и набором идиом. А каким образом они в него попали - так какая разница?
                                  Когда я что-то говорил про сущности в Хаскелле? :/ эта тема меня никогда особо не интересовала / в этом смысле в нем нет ничего необычного / интересного.

                                  Все, что я говорл про Хаскелл касается исключительно системы письма и более ничего. Т.е. хуже Хаскелла существуют языки, например тут несколькими постами ниже, или XSLT тоже то еще моральное уродство. Просто иногда зло берет когда у человека без представления о читабельности и понятности хватает смелости выдвигать гипотезы и подавать их в качестве истины в последней инстанции.
                                  Ответить
                                  • > в этом смысле в нем нет ничего необычного
                                    То есть Type Classes для вас - обыденное дело, во всех языках полно такого хлама, Expression Problem давно побеждён, верно?

                                    > у человека без представления о читабельности и понятности хватает смелости выдвигать гипотезы
                                    Откуда сведения о моих представлениях? Почему ваши представления более авторитетны, чем, например, мои?
                                    Ответить
                                    • Опа, а в Питоне есть МЕТА-классы, как вам это?! А еще, а еще!...

                                      Нет, в этом нет ничего удивительного в том смысле, что у кого-то есть что-то одно, у другого - другое. В Хаскелле идиотская система сохранения состояния (монады), но кому-то она нравится. Она не достаточно плохая или хорошая, чтобы вызывать эмоции сопоставимые с эмоциями, которые вызывает его синтаксисом. Точно в таком же смысле как ПХП замечателен анархизмом и полным произволом создателей, что и вызвяет много эмоций. То, что это, наверное, единственный язык в котором есть всего один тип коллекций (ну из отностильно популярных) - не очень интересный факт на общем фоне.
                                      Ответить
                                      • > но кому-то она нравится
                                        Например, Гвидо, создателю Python

                                        > нет ничего удивительного
                                        Type Classes лично на меня произвели несравнимо большее впечатление, чем питоньи метаклассы. Сильнее меня впечатляли только лисповые макросы.
                                        Ответить
                                        • Приведи реальный пример лиспового макроса, который тебя впечатлил.
                                          Ответить
                              • Опять кто-то пытается играть "Венгерскую рапсодию" на скрипке, неканифоленным смычком...
                                Ответить
                                • На спинете - слабо?
                                  Ответить
                                  • лорнет, минет... Что такое "спинет"?
                                    Ответить
                                    • Старинный инструмент, разновидность фортепьяно. https://1.bp.blogspot.com/-OkeCH6521OA/VyHkaSwTGCI/AAAAAAAAAKU/NCndZ1d8NqQmySUGCnTxWs2RHwTK7js2gCLcB/s320/Pelham642011T12200.jpg
                                      Ответить
                                      • Я из фортепьян только рояли признаю. Вот, где мощь и красота! А пианино - это мебель, что-то вроде шефоньерки. Как и предмет интерьера по ссылке.
                                        Ответить
                    • Кстати, как оператор . композиции функций определён?
                      Как то так?
                      http://ideone.com/Cwbu8
                      Ответить
          • Зачем работает медленнее, чем такой убогий и запутанный?
            Ответить
            • Сперва - быстро, резво, затем - работает медленнее, глубокий и запуганный.
              Ответить
    • buttlast
      Ответить

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