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

    +115

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    count c l = length $ filter (c==) l
     
    main = do 
            l <- getLine
            let
                    f = count '(' l
                    s = count ')' l
            in
            print $ f s (f==s)

    Посоны, как смешивать монадический код и не монадический?
    http://ideone.com/yRGDk
    Чистый код let in не хочет в монду.

    Запостил: HaskellGovno, 14 Мая 2012

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

    • показать все, что скрытоИначе хаскел в очередной раз слил.
      Ответить
    • in не нужно писать, хоть бы синтаксис сначала осилил чтоли
      http://ideone.com/ayTvb
      Ответить
      • Спасибки.
        Ответить
      • А с чем связано putStrLn $ show f ++ " " ++ show s ++ " " ++ show (f==s) ? Почему print такой ниосиляторный, что приходится писать кучу кода?
        Ответить
        • Потому что фактически все к строке приводится. Если устроит, можно просто: print (f, s, f == s)

          Есть Text.Printf.printf - только не сказать, что безопасный.
          Ответить
          • >Есть Text.Printf.printf - только не сказать, что безопасный.
            Что? И тут крестопроблемы? Даже в хаскеле не безопасный printf? :(
            Ответить
            • А может, это все-таки проблема, by design присущая printf? Компилятор же не обязан знать, что в строке формата, а от нее зависят допустимые аргументы.
              Ответить
              • а ещё строка может быть не константой, а вычисляться или приходить извне
                Ответить
              • > printf - только не безопасный
                > проблема, by design присущая printf
                http://liveworkspace.org/code/a07ddf05c9d21c04343c22defe1da10a
                cout << format("%1% %2% %3% %2% %1% \n") % "11" % 22 % 33.3;
                Ни чего не падает. Все безопасно. ЧЯДНТ?
                Ответить
                • А теперь замени на "%1% %2%\n". Только не говори, что не компилируется.
                  Ответить
                  • http://liveworkspace.org/code/1f3c7120d9b6f42d74862dcce56df516


                    Нет никакого неопределённого поведения. Просто получим исключение. Всё безопасно. А что там у хаскела? Небось память попортит?
                    Ответить
                    • > Небось память попортит
                      лолчто?
                      Prelude Text.Printf> printf "%d %d \n" 1 2 3
                      1 2
                      *** Exception: Printf.printf: formatting string ended prematurely
                      Prelude Text.Printf> printf "%d %d %d \n" 1 2
                      1 2 *** Exception: Printf.printf: argument list ended prematurely
                      Ответить
                    • Безопасно, не в смысле что память портит, а что конкретная проблема отлавливается до запуска, если вместо слишком общего printf использовать код по ситуации. Если написать в стиле, приведенном roman-kashitsyn - до исключения не дойдет.

                      http://hackage.haskell.org/package/safe -- примерно в этом смысле.
                      Ответить
                      • В D и Nemerle есть типобезопасные printf.
                        Так что Хаскель и тут в очередной раз соснул.
                        http://ideone.com/JoaZy
                        using System;
                        using Nemerle.IO;
                         
                        printf("Value = %d", 2 + 2)
                        результат: успешно	     время: 0.07s    память: 13496 kB     возвращаемое значение: 0
                        
                        ввод: нет
                        вывод:
                        Value = 4


                        http://ideone.com/BH0pW
                        printf("Value = %d", 2 + 2, 5)
                        prog.nem:4:1:4:7: error: too many arguments for printf macro
                        ввод / вывод	 показать все скрыть все
                        # 1:   скрыть   clone   2 minutes 52 seconds ago
                        результат: ошибка компиляции


                        http://ideone.com/WQj1U
                        printf("Value = %d", "s")
                        prog.nem:4:1:4:7: error: expected int, got string in type-enforced expression: System.String is not a subtype of System.Int32 [simple require]
                        ввод / вывод	 показать все скрыть все
                        # 1:   скрыть   clone   6 seconds ago
                        результат: ошибка компиляции
                        Ответить
                        • Только не нужно мне сразу загонять телегу, что мол подходящий инструмент нужно выбирать под свою задачу и Хаскель не подходит для вывода текста через printf и поэтому нужно выбирать другой инструмент для этого. :-7
                          Ответить
                          • Э, ты не понял: printf не подходит для типобезопасного вывода, Haskell тут не при чём
                            Ответить
                            • >Э, ты не понял: printf не подходит для типобезопасного вывода
                              Лолчто? Код выше видел? Всё абсолютно типобезопасно. А хаскелюшачка эту типобезопасность не осилил, точнее осилил, но очень слабо на уровне амёбы.
                              Ответить
                              • И как этот макрос хэндлит строки форматирования, неизвестные на этапе компиляции, т.е. составленные в рантайме? Подозреваю, что никак. В реальной жизни я видел составление строк форматирования по неким метаданным довольно часто. Если уж ОЧЕНЬ нужна проверка типов, лучше уж реализовать свой DSL для форматирования строк с проверкой типов и всем, что тебе ещё там нужно.
                                Ответить
                                • >И как этот макрос хэндлит строки форматирования, неизвестные на этапе компиляции, т.е. составленные в рантайме?
                                  Для этого есть "printf" не являющийся макросом, который все типы проверит в рантайме. Тут как бы по другому то нельзя.

                                  > лучше уж реализовать свой DSL
                                  Ты лучше реализуешь свой кривой говновелосипед с ошибками ради пары сформатированных строк? Не нужен.
                                  Ответить
                                  • > этого есть "printf" не являющийся макросом
                                    Use another printf, Luke. ok.

                                    > ради пары сформатированных строк
                                    ради пары строк меня вполне устроит show и print, или, на в крайнем случае, "опасный" (лол какой опасный) printf
                                    Ответить
                          • > prog.nem:4:1:4:7: error: too many arguments for printf macro
                            Вы хотите сказать, что использование костыля (макрос для, казалось бы, базовой функции) неким чудесным образом обеляет printf и превращает остальные языки в жалкую приставку для вашего ника? Не могу сказать, что ваши силлогизмы слишком радуют стройностью (если вам показалось, что это эвфемизм - вы не ошиблись).

                            Если вы решили, что опускаться до макросов - приемлемо, то уж кушайте и template haskell - http://www.haskell.org/haskellwiki/Template_Haskell#Printf .

                            Только не нужно мне сразу загонять телегу, что мол непортабельно[^1], и раз Хаскель - то нельзя пользоваться метапрограммированием, и поэтому нужно выбирать другой инструмент для этого. :-7
                            [^1]: риску предположить, что хаскель будет пораспространеннее D & Nemerle, так что GHC-гвозди здесь адекватны
                            Ответить
                            • Не годно:
                              http://ideone.com/dgCHU
                              Could not find module `PrintF'
                              Только не нужно мне говорить, что раз эта возможность есть, то я могу написать свой велосипед с квадратными колёсами и пользоваться им. Тем более в стандарте языка возможности использовать макросы нет. А использовать компиляторспецифик расширения {-# LANGUAGE TemplateHaskell #-} - убого.
                              Ответить
                              • Только не нужно мне говорить, что ты не осилил скопипастить содержимое, что ниже в отдельный модуль.

                                > Тем более в стандарте языка возможности использовать макросы нет.
                                Вы так говорите, будто уже привели ссылочку на стандарт для Nemerle.

                                > {-# LANGUAGE TemplateHaskell #-} - убого.
                                А как вы определяете, что убого, а что нет. Не на слух случайно?

                                Рад за вас, что объемы ваших полушарий таки позволяют сидеть на двух стульях, принимая макросы, и одновременно, отвергая template haskell.
                                Ответить
                                • > ты не осилил скопипастить содержимое

                                  Зачем это копипастить, если там реализована убогая поделка без полной поддержки нормальных флагов форматирования, а среди поддерживаемых типов только s и d. Этот модуль даже не стоит того, чтобы обсуждать. Я и то бы лучше написал.
                                  Ответить
                                  • > Я и то бы лучше написал.
                                    Если неплохо знаешь хаскель - то уж вбрасывай потоньше, чем let vs let ... in

                                    Можно еше Printf-TH посмотреть.
                                    Ответить
                            • В Nemerle макросы - не костыль как в С, они там основной инструмент реализации.
                              Ответить
          • Бля в хаскелл тоже воткнули это опасное говно printf?!
            Пиздец.
            Ответить
            • КСЖ, в хаскеле есть еще и наипаснейший FFI, МВУ!!1
              Ответить
        • Потому что ты дебил.
          putStrLn $ unwords [show f, show s, show $ f==s]


          И не нужно тут printf.
          Ответить
          • >И не нужно тут printf.
            Лол. Да ты похоже какой-то тугой. А что если я хочу вывести форматированный вывод с нужным числом знаком после запятой и вставив необходимые символы\слова, а не только пробелы как с unwords, между форматированными элементами? Да и вообще ты какой то говнокодер - 3 раза повторил show вместо одного.
            Ответить
      • Я бы тоже не догадался - а почему in не нужно? Чем оно мешало / зачем 2 разных? С виду - очередной маразм.
        Ответить
        • do - можно считать edsl, и там свой let, распостраняется на нижелещий код (afaiu, чтобы лесенка не образовалась):

          do let ... ; ... --> let ... in do ... (вроде такая трансляция do-сахара)
          Ответить
          • Честно? - нихрена не понял из вашего объяснения, но пытался. Почему не понял: let существует еще в надцати языках, из близких родственников, let может отличатся некоторыми вещами, например, может быть разрешено и запрещено ссылаться на другие переменные в объявлении переменных (я хз как в этом смысле в Хаскелле, документация молчит, а пробовать влом). Либо есть различие между let и letrec - т.е. если замыкание, к которому относится let будет вызвано повторно, то будут ли пересозданы связывания, или нет. Хаскелл вроде утверждает, что let у него это letrec (а обычного let нету...).

            Я бы мог понять, если бы in играло какую-то роль в этом различии (но, очевидно, оно никак на это не влияет) - на что влияет, я так и не понял - но больше всего похоже, что это какая-то внутренняя война Хаскелля самого с собой изза идиотического синтаксиса и чего-то там не срослось опять. Хз вобщем.
            Ответить
            • Да, это letrec - определения в let-блоке хаскеля взаимно-рекурсивны.

              let ... in ... - выражение, но просто так выражение в do-синтаксис не адаптировать (там они должны иметь тип m a, где m-соотвествующая монада). С помощью подобной трасляции как раз это и получается (и let получается "урезанный" - область видимости нижележащая do-конструкция, соотвественно и "in" - избыточен).
              Ответить
              • Но и просто let никто-не отменял, например можно добавить: "let a = 7 in print a" в привенный код (и это будет обычный let, a не do-let).
                Ответить
              • Ну как и предполагалось - какая-то внутренняя дилемма и война самого с собой нафиг никому не интерсная и безвыигрышная - только для того, чтобы создать больше правил без причины.
                Нафиг нужен вообще do блок, если с ним столько проблем? Нафиг нужно вкладывать столько смысла в пробельные элементы, если 100500 раз было наглядно доказано, что на whitespace код очень тяжело читается... но ежики, кактусы...
                Ответить
                • Непонятно, почему столько негатива в адрес этого замечательного языка. По мне так в CL намного больше костылей, чем в Haskell. Haskell язык может сильно расширить кругозор, в нём сплетено так много необычных идей и концепций. Он изменил мой взгляд на мир. К чему все эти лучи ненавести? Никто ведь не заставляет на нём писать. Не нравится - пройдите мимо.
                  Ответить
                  • Никто не говорит про идеи и концепции. Исключительно синтаксис критинический. И в этом смысле я уже говорил, CL страдает от совсем других проблем (в плане синтаксиса), но, по крайней мере количество непонимания у человека его изучающего минимально. Т.е. для того, чтобы научится читать программы на CL - недели за глаза и за уши хватит, потому что язык простой.

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

                    Есть такая вещь, как "путь наименьшего удивления". Т.е. например, let-in существует в HOPE, ML (и потомках), Miranda (собственно, Хаскелль ее наследник) - но ни в одном нету двух вариантов let и let-in. И человек, немного знакомый с другими языками естесственно удивится "разнообразию" и начнет искать причину, и еще больше удивится, когда окажется что причина - исключительно в идиотизме авторов.

                    Из всей этой группы языков, я первым познакомился с Эрлангом - там есть свои заморочки, как и везде, но после пары недель код на нем не вызывает удивления. Следующим был Хаскелль - для меня это до сих пор клинопись, только желания разбираться больше нет. CaML по сравнению выглядит прямо аж спасибо автору хочется сказать за то, что не похож на Хаскелл. Мне иногда проще найти доку по CaML и по ней попытатся угадать, что делает Хаскелль, чем понимать белеберду на самом Хаскелле.

                    А комментирую потому, что изза этой дряни к другим, хорошим языкам складывается предвзятое мнение (типа того же ML).
                    Ответить
                    • Вы просто не приседаете со штангой мой рабочий вес 90 кг
                      Ответить
                    • > безо всякой на то причины
                      Хм.. а где еще (из юзабельных языков) pure core, то бишь чистые функции, отделены от остального кода?
                      Ответить
                      • А зачем это вообще нужно? Это бесполезное упражнение исключительно теоретического характера. На практике гораздо важнее производительность и простота, и тем более простота в понимании. Мне пришлось немного попрограммировать на Эрланге для настоящего работающего проекта - отсуствие нормальной возможности хранить состояние программы или какой-то ее части - это недостаток который никаким отсуствием побочных эффектов не компенсировать. Это на столько плохо и приводит к таким хреновым архитектурным решениям, что вся кривизна ПХП меркнет в сравнении.

                        Особенно, когда не остается никакого выхода, кроме как записывать большие структуры в файлы и при необходимости их оттуда читать. Или держать открытм сокет написаный на другом, вменяемом языке и его использовать для хранения. Про работу с базой данных лучше не заикаться даже. Это на столько криво реализовано, что плакать хочется.
                        Ответить
                        • > зачем это вообще нужно?
                          https://secure.wikimedia.org/wikipedia/en/wiki/Referential_transparency_(computer_scien ce) :
                          This can help in proving correctness, simplifying an algorithm, assisting in modifying code without breaking it, or optimizing code by means of memoization, common subexpression elimination or parallelization.

                          > отсуствие нормальной возможности хранить состояние программы
                          Прямо-таки отсутствие? А как же (помимо чистой State-monad) : IORef / STRef / MVar / TVar или даже persistent с бэкендами в виде баз данных. Или они не нормальны, ибо подразумевают монадический доступ.

                          > и тем более простота в понимании
                          Срочно все в маши^Wplan9. Нельзя же все писать на одном уровне детализации, а значит и простоты. И должны же в CS быть ветки с теоретическим уклоном. Может вам еще и proof-assistant (Сoq / Agda / Epigram / whatever - о всех у меня весьма смутное представление) подавай, чтоб с полпинка можно было осилить.

                          > Про работу с базой данных лучше не заикаться даже.
                          Для относительно низкоуровнего доступа может и HDBC хватить. Если хочется чего-нибудь поприятнее - есть HaskellDB, но там template haskell и все сопутствующие прелести. А какие там особые проблемы, поделитесь для расширения кругозора (с бд-интерфейсами хаскеля я знаком поверхностно)?
                          Ответить
                          • > Как на счет [...] - бесполезный хлам, это в принципе не возможно в Хаскелле (да и в любом похожем языке), либо заставляет придумывать всякие уродкие решения, типа той же State монады. Например, ваше приложение должно работать с базой данных - я даже как-то по этому поводу на stackoverfolow спрашивал, так вот, соединение с базой никаким образом нельзя "сохранить" - любой другой модуль который захочет получить какие-то данные из базы - не важно в какой точке приложения / на каком слое он находится должен каким-то образом хранить сам ссылку на это соединение. Это не просто маразм, а в большинстве случаев просто не возможно. Т.е. data-abstraction layer в принципе нет возможности построить, т.как никакой абстракции не получится.

                            > Срочно все [...] - Хаскелл очень сложен в понимании изза плохой структуры, не очевидный (не возможно понять что именно делает код, если не знать во что он превращается компиляторм / не попробовав запустить). С языками для доказательства теорем - Лисп, собственно, был пионерм в этой области в смысле символического исчисление. И был на столько лучше и универсальнее всякого говна типа Coq, но есть мудаки старперы, для которых их средневековые закорючки важнее универсальности и понятности.
                            Ответить
                            • > не возможно понять что именно делает код, если не знать во что он превращается компиляторм

                              пипец, правила преобразования do-блоков в монадические операторы просты до безобразия, их описание вместе с примерами и детальным объяснением занимают всего пару страниц в RWH. Ядро языка очень мало, почти все операторы (включая столь нелюбимые вами (.) и ($)) определены в терминах самого haskell.
                              Ответить
                              • Какая разница что вам кажется простым? - они не нужны в принципе вообще никогда - и мудак, тот кто их придумал.
                                Все эти закорючки - такой же дибилизм. Кстати, интересный момент, Хаскелль приподают в Японии примерно как Паскаль в странах бывшего союза - Японцам очевидно выучить еще сотню-другую пиктрограм - как раз плюнуть, для них это наверное типичное домашнее задание.
                                Я за свою жизнь выучил кучу идиотских никому не нужных символов и алфавитов - и когда очередной дибил предлагает выучить еще сотню "для удобства" хочется такого мордой об клавиатуру линотипной машины, пока алфавит, сука, не выучит.
                                Ответить
                                • я искренне ненавижу учить закорючки, вообще УЧИТЬ. я просто неспособен на это. я могу только ПОНИМАТЬ.

                                  Я начал изучать haskell сразу после прочтения SICP, и не имел опыта работы с функциональными языками, кроме разве что со Scheme.

                                  Изучать начал по RWH. Проблем с синтаксисом у меня не было. Вообще. По мне всё выглядит логично и понятно, иначе бы я просто не смог осилить синтаксис в силу своей неспособности к заучиванию.
                                  Ответить
                                  • Да, потому что у каждого человека есть предел, сколько символов он может заучить наизусть. Если знать кириллицу + латиницу + сопутствующие типографские символы - добавить к этому еще набор пиктрограм - копейки, и не заметно. Мне как бывшему полиграфисту работавшему на разных языках пришлось кроме этого выучить ивритские закорючки (на самом деле то, на чем сейчас пишут на иврите - это арамейские символы, но я и настоящие ивритские знаю), и арабские, и когда-то нужны были японские фонетические азбуки, и язкыки средиземья :) и еще много всякой узкоспециальной херни, которую не хочется перечислять. Так вот, на каком-то этапе приходит понимание того, на сколько это все не эффективно и не универсально. А "патриотов" которые держатся за свой набор закорючек, и ни за что не согласятся использовать более универсальную технику хочется "мочить в сортире" не потому что они идиоты, а потому что они еще и другим жизнь портят заставляя подстраиваться под их идиотизм.
                                    Ответить
                        • Основная проблема с функциональных языков - они, как правило, требуют подходов, отличных от тех, которые нам вдалбливают со школьной скамьи, т.е. порог вхождения весьма высок.

                          Математическая аналогия: абстрактная алгебра, теория категорий и топология довольно трудны для освоения из-за своей абстрактности, но они позволяют делать более общие выводы и находить закономерности, недоступные более "прикладным" разделам. Но это не означает, что более детальные и прикладные разделы не нужны, и уж тем более не означает, что все разделы нужно запихнуть в абстрактную алгебру.

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

                          Я (пока) не знаю erlang, поэтому ничего не могу сказать про удобство использования состояния в нём, но я на 95% уверен, что "хреновые" архитектурные решения, принятые в силу "отсутствия нормальной возможности хранить состояние" были скорее симптомами неосиляторства, чем ограниченности возможностей языка. В haskell, к примеру, есть реализация STM (вроде бы ничего лучше для хранения состояния в многопоточной среде ещё не придумали).
                          Ответить
                          • Да, конечно, это всегда проще обвинить человека, который закончил Беркли, а потом еще и тель-авивский универ и проработал 30 лет с базами данных / инфраструктурой с ними связаной, да еще и к тому же почетный профессор в тель-авивском универе в том, что не осилил. (это я не про себя, я в этом проекте на правах обычного исполнителя был). Просто когда на той же Яве такие вещи делаются не задумываясь - тут это не то что не тривиально, а вообще не выполнимо / через жопу.
                            Ответить
                            • Можно писать на сишке хоть всю жизнь, но если ты не работал с функциональными языками раньше, то весь твой опыт лишь мешает тебе.
                              Ответить
                              • Так вот именно, я работал, да еще и в настоящем проекте - я думаю, мало кто здесь может сказать о себе то же самое. И говорю это не из теоретических соображений, а из того, что было увидено на практике.
                                Ответить
                                • Нихочу никого обидеть, но у нас в "настоящем" проекте сейчас работает куча индусов, и на джаве они пишут так, что я скоро начну "плакать кровавыми слезами", а архитектурные решения матёрых архитекторов вызывают у меня баттхёрт.

                                  Из этого ровно ничего не следует.
                                  Ответить
                          • Нет, основная проблема функциональных языков в том, что они не применимы в принципе к большому роду задач, особенно, задач, которые связаны со слежением за состоянием и реакцией на него. Функциональные языки хорошо использовать для компиляторов, алгоритмов поисковых машин и т.п. - там где домейн полностю заранее известен и детерминистские алгоритмы будут себя "хорошо вести". Для написания программы, которая должна реагировать на ввод настоящего пользователя, которая "живет" в мире с неопределенностью, который нет возможности полностью категорически описать функциональные языки не приспособленны, как детерминистский алгоритм не сможет никогда вычислить пи. И всегда, когда сталкиваются с таким проблемами предлагают какие-то инвалидные обходные пути типа performUnsafeIO и ему подобных.
                            Ответить
                            • 1. I use XMonad, and I am happy with it.

                              2. Таки я собрал YI, в принципе вещь удобная, с емаксовскими биндингами дружит. Правда, там нет аналога столь горячо любимого мной org-mode.

                              3. > которая должна реагировать на ввод настоящего пользователя
                              Вспомнилось по теме
                              http://habrahabr.ru/post/140719/
                              Ответить
                              • > Таки я собрал YI
                                Небось ~/.cabal под пол-гигабайта, тоже собирал, но почти не пользовался.
                                Ответить
                              • Да, потому что любая вещь сделанная через жопу доставляет удовольстие своей уникальностю. Монады вообще не нужны, это обходной путь, нужный, чтобы как-то заставить неправильную теорию выглядеть рабочей. Ни один нормальный человек ни за что бы не стал их использовать в другом языке (не смотря на то, что реализовать их можно хоть в Яваскрипте).
                                Ответить
                                • > заставить неправильную теорию выглядеть рабочей

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

                                  По мне так люди, которым нравится haskell ведут себя в этом споре гораздо достойнее. Во всяком случае, никто из них не создаёт ники наподобие ThisLanguageGovno или UserNameGovno. И не брызжет слюнями лучами ненависти.

                                  Такое ощущение, что кто-то бьёт вас по голове, заставляя учить хаскелл. К чему эти бессмысленные холивары? Мне всё равно, нравится он вам или нет. Мне нравится, я нахожу в нём то, что ищу больше всего - новые идеи и подходы.
                                  Ответить
                                  • В смысле монад - нет, ни разу, никто не мешает их реализовать в Яваскрипте, просто это никому не нужно. И от порядка вычислений это вообще не зависит.
                                    То что их придумали еще не значит, что они имеют какую-то практическую ценность. В контексте Хаскелля вся их практическая ценность - это "заставить" реальность соотвествовать убогой теории. А когда теория таки оказывается абсолютно нежизнеспособной, даже с костылями - то наконец-то здравый смысл побеждает, и используют unsafeIO или как его там.

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

                                      Откуда инфа? Почему так происходит? Можете рассказать подробнее?
                                      Ответить
                                    • > феерическое говно для того, для чего его рекламируют

                                      Расскажите об этом Ericsson с их распределёнными системами. Я, кстати, писал на сишке SCCP сервер под OSE Delta для них. Вот уж где феерическое говно было.
                                      Ответить
                                      • Так я именно изза того, что Эриксон язык для этого использует и написал о том, что зря использует. Мало ли почему они решили, что оно пригодно для этого.
                                        На эту тему есть смысл почитать Питера Норвига и Стюарта Рассела про новые подходы к АИ. Не в том смысле, что есть какая-то глубинная связь между созданием сложных систем, а в том, что там есть определенные аналогии, и на пальцах показывается почему "идеальной, математически выверенной" программы в принципе не написать. Там был такой пример, когда человек переходит парковую аллею, и в то же время из авиалайнера пролетающего над парком падает багаж - и нет больше пешехода. Т.е. в реальном окружении предсказать все событя не представляется возможным, и пытаться добиться 100% корректности - это пытаться объять необъятное. Собственно, аргументация сводится к тому, что любая программа по определению работает в стохастическом окружении, где нельзя (и даже вредно) предполагать такую возможность как 100% осведомленность об окружении. Такая осведомленность возможна только в каких-то искуственно созданных оазисах, типа игры в шашки.
                                        Ответить
                                      • Аналогично, Эрланг построен на том, что "все предсказуемо" и все нужно знать заранее. Как один из результатов - состояния окружения считаются не важными (т.как считается, что они предказуемы, и вообще не интересны). Это приводит к тому, что нет никаких нормальных инструментов для того, чтобы хранить информацию об окружении (опять же, пример с подключением к базе данных). В Эрланге для того, чтобы держать открытым подключение нужно написать функцию постоянно вызывающую себя рекурсивно и ждущую сигнала от других процессов. Соответственно, это приводит к тому, что либо запросы и ответы приходится пересылать между процессами (затратно), либо функция обслуживающая соединение вырастает до нереальных размеров (для того, чтобы рассылать и принимать только минимально необходимую информацию). Когда это небольшой сервер с умеренной нагрузкой - это не заметно, а когда это популярный сервис на Фейсбуке с десятками или сотнями тысяч пользователей - это никак не скейлится и начинаются проблемы...
                                        Ответить
                                        • Так вроде и них политика "Let it crash", т.е. пешеход всё равно рано или поздно помрёт (не прибьёт кирпичём так машиной задавит), надо иметь грациозно зареспавнить свеженького.

                                          Прочитаю Programming Erlang Джо Армстронга, и мы вернёмся к этому разговору.
                                          Ответить
                                          • Нет, это не имеет отношения к тому, о чем я говорю. Это какие-то агит-листовки ниочем. Смысл в том, что для решения некоторых задачь обязательно необходимо какое-то преставление о состоянии "мира" программы. Типичный пример - рандом, но это самое простое. Иногда нужно знать (и помнить) всякие нюансы из истории пользователя, из истории самой программы и т.д. Это на столько естесственно для всяких "не чистых" языков, что никто особо не обращает внимания (активна/неактивна кнопка, под каким логином зашел пользователь). Но когда этого вдруг нету работа с данными превращается в пытку - кешировать нельзя, нужно все время извращаться придумывая обходные пути как бы так сорхантиь меньше данных и как бы сделать это централизовано (при том, что физических ограничений на память нет - просто обслуживание каждого большого объекта - это столько головной боли, что волей-неволей делается все, чтобы только этого избежать.) Соответсвенно появляются идиотские решения - типа хранить все объекты вместе в одном потоке, и обращаться к ним по-очереди, или записывать их куда-нибудь на диск, а потом от туда доставать.
                                            var foo = { bar: 100 };
                                            foo.bar = 200;

                                            превращается в такую пытку, что в итоге на оптимальные решения забивают и пишут как удобнее, а не как лучше.
                                            Ответить
                                          • Тоесть, чтобы на примере прочувствовать ситуацию: есть у вас чат-сервер, и есть у вас список всех участников чата, ни, предположим, 1000 человек. Список заполнен объектами, каждый с полями имя/фамилия и еще надцать простых свойств, всяческим статусами типа время отправки последнего сообщения, с кем сейчас беседует и т.п. И тут в чат заходит еще один пользователь, нужно его добавить в список - а списки-то не мутабельные. Скопировать и выбросить старый на помойку? - кроме того, что очень плохо с точки зрения производительности, так еще и всякие статусы потеряются, а еще и рассинхронизация, а еще и если где-то вдруг была ссылка на старый объект... и тут начинаются пляски с бубуном.
                                            Ответить
                                            • Не мне вам говорить, что добавление элемента в функциональный список - операция O(1). Удаление - позатратней (можно использовать зипперы, так расходы памяти больше, но модификация структур не требует копирования всех элементов, они популярны в Clojure, используются в вышеупомянутой XMonad).

                                              ejabberd как-то работает же, вроде никто не жалуется.
                                              Ответить
                                              • Да не важно, я слово список использовал как "список пользователей" - это вообщe может быть хеш таблица. Не в этом суть. Его весь выбросят при любом добавлении пользователя - когда это сервер с одновременным онлайном 10К круглые сутки и новым пользователем каждую десятую долю секунды - никому не захочется весь список выбрасывать и перезаполнять по новой.

                                                А работает - ну дык Фейсбук на ПХП - и работает, че там, даж норм работает, практически бесперебойно и вообще.
                                                Ответить
                                                • Почему весь? Например в тех же деревьях надо обновить около log(N) элементов при вставке.
                                                  Ответить
                                                  • Как почему - написано же не мутабельный - как его можно неполностью поменять?
                                                    Ответить
                                                    • Как, как, пересоздаем log(N) элементов которые должны поменяться и проставляем в них ссылки на куски старого дерева.
                                                      Ответить
                                                  • Еще раз, вы вообще не понимаете о чем речь - дело не в сложности, время потраченное на вставку, пусть бы оно даже было NP-неполным ни в какое сравнение не идет с необходимостю заменить полностю всю структуру при малейшем изменении. То, что вы там чего-то вставили и вернули новую структуру, в которой использовали части старой - молодец! Только вот теперь все процессы, которые висели с захваченными значениями из старой структуры работают с каким-то мусором - и им всем нужно сообщить новые значение. Это превращается в подобие нейронной сети - с той только разницей, что ее никто не хотел писать, все, что было нужно - переустановить статус пользователя из "онлайн" в "занят".
                                                    Ответить
                                                    • Ок, я так понимаю проблема не в том как поправить саму структуру, а в том как разослать ее изменения всем кто с ней работает?

                                                      На самом деле, если бы другие процессы ВНЕЗАПНО увидели новые данные - было бы еще хуже. Это та же история, что и писать многопоточку на С без использования блокировок.

                                                      Мне кажется эта проблема общая, а не только ФЯ.
                                                      Ответить
                                                      • Да вы хоть я даже не знаю... справку пользователя что-ли отркойте...
                                                        Пример:
                                                        A - какой-то элемент из списка B
                                                        func_a(A) ->
                                                            receive
                                                                foo_changed ->
                                                        	    %% do_something чего-то делает с A на основании foo
                                                        	    %% сейчас мы уже не уверены в том, что в A есть значение
                                                        	    %% которое можно использовать, поэтому мы обращаемся к
                                                        	    %% процессу, который нас оповестил, чтобы получить новое значение.
                                                        	    know_all_process ! {get_new_foo, pid},
                                                        	    %% но ждать же как-то надо, поетому забиваем вместо A что угодно:
                                                        	    func_a('whatever');
                                                        	{new_foo, [important object]} ->
                                                        	    %% наконец-то получили новое значение!, теперь можно продолжать работат
                                                        	    %% спокойно.
                                                        	    func_a(do_something([important object]));
                                                            end.
                                                        func_b(B) ->
                                                            receive
                                                                add_some_foo ->
                                                                    %% получили сообщение о том, что что-то надо добавить в B
                                                        	    listener_id0 ! foo_changed,
                                                        	    . . .
                                                        	    listener_id100 ! foo_changed,
                                                        	    %% сделали замену и перезапустили процесс.
                                                        	    func_b(do_something_else(B));
                                                        	    %% получили сообщение от какого-то процесса, который хотел
                                                        	    %% обновиться, и выслали ему то, чего он просил.
                                                        	{get_new_foo, pid} ->
                                                        	    pid ! some_part_of(B),
                                                        	    %% и пошли слушать изменения дальше.
                                                        	    func_b(B);
                                                            end.

                                                        Я не тестировал, и это скорее псевдо-код, но вполне верно описывает то же самое, что в каком-нибудь Яваскрипте выглядело бы примерно как
                                                        var foo = { bar: 100 };
                                                        foo.bar = 200;

                                                        Вообще без какого-либо преувеличения. При чем код на Эрланге, будет плохо расширяемым потому, что слушателей изменения свойства еще как-то нужно будет добавлять.
                                                        Ответить
                                                        • Ну не знаю, обычно вместе с эвентом об изменении состояния посылают старое и новое значение состояния... И ФП тут вроде как совсем не при чём.
                                                          Ответить
                                                          • Ну как сказать, причем :) Тем что иммутабельную структуру и правда можно передать полностью вместе с ивентом. В отличие от мутабельной, которую, при том же размере, передавать накладно, т.к. придется ее на всякий случай скопировать (перед передачей или после - неважно).
                                                            Ответить
                                                        • Может быть, подойдет такой вариант функции А:
                                                          func_a(A) ->
                                                              receive
                                                                  foo_changed ->
                                                                  %% do_something чего-то делает с A на основании foo
                                                                  %% сейчас в А конечно же есть старая версия данных, но
                                                                  %% мы знаем, что они устарели, поэтому мы обращаемся к
                                                                  %% процессу, который нас оповестил, чтобы получить новое значение.
                                                                  know_all_process ! {get_new_foo, pid}
                                                                  %% и ждем ответа от него
                                                                  receive 
                                                                      {new_foo, [important object]} ->
                                                                          %% наконец-то получили новое значение!,
                                                                          %% теперь можно продолжать работать спокойно
                                                                          func_a(do_something([important object]));
                                                                  end
                                                              end.


                                                          А вот как с этим кодом связан пример на js я не понимаю ;( После выполнения foo.bar=200 все слушатели магическим образом узнают об этом?
                                                          Ответить
                                                          • > После выполнения foo.bar=200 все слушатели магическим образом узнают об этом

                                                            на всех нодах, ага :) Наш собеседник, видимо, рассматривает случай, когда все живут в одном адресном пространстве и модифицируют там данные. А ведь всем давно известно, что конкуррентное программирование в таком стиле является таким суровым трешем, что монады со стрелками курят в сторонке.
                                                            Ответить
                                                          • ФП как раз при чем, потому что в нормальных языках рантайм заботится о том, чтобы значения самопроизвольно никуда не исчезали, а в ФП нужно изгалятся, чтобы они оставались.
                                                            В Яваскрипте слушатели не нужны - любая функция, которая захочет получить новое значение foo.bar просто к нему обратится и прочитает. Просто Эрланг этот этап еще не осилил, и нужно за него доделывать.
                                                            > Вместе с эвенотом посылать [...] - да, конечно, а вы в курсе, что это копирование по значению? Т.е. зафигачить в каждый процесс, которому нужно статус одного человека, или там фамилию его всю базу данных? Это афигеть какое изящное архитектурное решение! count(sql_querry("select * from users")) не напоминает?
                                                            Ответить
                                                            • ололо, посылать сообщение USER_CHANGED и заставлять всех выяснять, что же именно поменялось, вместо того, чтобы послать USER_NAME_CHANGED со старым и новым значениями - офигенно изящное решение.

                                                              И да, ваш подход с разделяемым состоянием является полной лажей при работе в распределённой неоднородной среде, на которую и нацелен erlang. А эффекты на страничках с его помощью делать никто и не собирался.
                                                              Ответить
                                                              • > USER_NAME_CHANGED
                                                                можно ещё
                                                                USER_CHANGED (field: "NAME", was: "Mark", become: "Markus")
                                                                Ответить
                                                                • Это - как раз типичная ошибка новичков - что происходит в итоге - одна функция начинает обслуживать массу разнообразных запросов и превращается в длиннющую портянку с кейсом на каждый вариант запроса. Естественно, каждая новая модификация добавляет головной боли по тестированию, при чем тестирования становится все больше и больше. В итоге получается god object который уже не контролируем, все ошибки в приложении случаются именно там, и любая даже самая незначительная ошибка приводит к тотальному выходу из строя всей программы.
                                                                  Так что спасибо за попытку, но вам еще опыта не хватает советы давать.
                                                                  Ответить
                                                                  • > вам еще опыта не хватает советы давать

                                                                    Забавно слышать это от человека, ратующего за глобально разделяемое состояние. Это хоть как-то работает с STM при работе на нескольких ядрах, но map/reduce на этом не построишь. Ок, отложу текущую книжку и почитаю "Programming Erlang", всё равно давно собирался. Но что-то мне подсказывает, что инженеры Ericsson получше вас разбираются, какой язык им нужно использовать для построения сложных распределённых отказоустойчивых систем.
                                                                    Ответить
                                                                    • Теплое с мягким... А про состояния - почитайте, что по этому поводу думает Гай Стил (тот самый, который в соавторстве Scheme спроектировал).
                                                                      http://dreamsongs.com/ObjectsHaveNotFailedNarr.html
                                                                      Ответить
                                                                      • знаю я, кто такой Гай Стил, он ещё и JLS помогал писать. И мне, по большому счёту, всё равно, что он написал по поводу состояния, ибо я работал практически со всеми существующими моделями распределения, видел решения и проблемы, которые они вызывают, и имею своё мнение по этому поводу.

                                                                        Глобальное состояние, один поток, нет блокировок - Redis. Быстрый как дьявол, но при масштабировании возникает много проблем, поэтому нормальный кластер мы увидим не скоро.
                                                                        Глобальное состояние, много потоков с блокировками - жуткий треш, написать такое приложение правильно почти невозможно, нужно быть гуру и знать много магии и заклинаний. Типичная Java. Масштабируется, но нужно много рукописных штук.
                                                                        Глобальное состояние, много потоков, STM - Clojure. Есть оверхед, но облегчает многопоточное программирование примерно так же, как GC облегчает обычный труд программиста. Масштабируется, но опять же только ручками.
                                                                        Распределённое состояние, легковесные потоки (акторы) - Scala, Akka, Erlang. Надёжно, прекрасно масштабируется, но до определённого момента оверхед перекрывает преимущества. Руками писать не много, почти всё на себя берёт рантайм.
                                                                        Ответить
                                                                        • Эрланг масштабируется? Руками писать не много? Это шутка такая? Эрланг - это писанины по сравнению да с чем угодно в разы больше. Хуже наверное только на ассмеблере (и то я так говорю, потому что никогда ничего практического на ассемблере не писал). Долгосрочная работа программы на Эрланге - это самое нерациональное использование ресурсов из всех вообще возможных подходов.
                                                                          О каком распределенном состоянии идет речь? В Эрланге нет вообще никаких нормальных инструментов для инкапсуляции состояния - откуда такие мысли появляются? Кто-то написал рекламную статью? - ну так мало ли, чего там написано. Я уже одного такого доверчивого видел, год промучался, слава богу ушел - вспоминаю, как в страшном сне. Вроде и команда была не самая худшая, да и человек с опытом и все такое - сервер на Эрланге за год моего с ним знакомства может дней 5 проработал подряд максимум. А так, обычно, каждое утро были разборки почему всю ночь сервер лежал. Это уже прям до истерии доходило. Любой индус-старшекласник на Яве бы слепил то же самое, и работало бы с меньшими накладками.
                                                                          ФП не приспособлены решать задачи в изменяющемся стохастическом окружении, либо они должны "жертвовать принципами" (нужными только фанатам), после чего выясняется, что кроме этих ненужных принципов, ничего там полезного и не было.
                                                                          Ответить
                                                                          • Говорю же, не читаю я рекламных буклетов, и не вам судить об уровне моего профессионализма. Почитаю книжку, напишу простенький идеоматический серверок (благо приходилось уже делать это на сишке и на джаве, знаю, какой это гемморой) и посмотрю на стабильность работы. Отзывы моих друзей - программистов (прагматиков, кстати) об эрланге пока только сугубо положительные.

                                                                            > Руками писать не много
                                                                            имеется в виду для реализации именно масштабирования
                                                                            Ответить
                                                                        • Кстати, непридуманная история. Когда я пришел работать в контору, которая разрабатывала этот самый чат на Эрланге, через какое-то время я там случайно обнаружил, что на той же машине, где с такими страданиями и усилиями пытались запустить сервер на Эрланге спокойно себе работал Джаббер сервер на Питоне который фактически и обслуживал всех посетителей чата, кто залогинился через Фейсбуковкий чат (практически все). И по объемам пересылаемой информации и сложности выполняемой работы в разы превосходил Эрланговую часть.
                                                                          Его написал человек, который был восновном ответсвенным за ЯваСркипт, а Питон видел впервые в жизни (использовался Twisted). Т.е. написал его "случайно" - ну попросили - сделал, типа работает. Я когда понял на сколько нашему Эрланговому серверу далеко до того, что было сделано в полпинка на Питоне - ржал до колик.
                                                                          Ответить
                                                                          • Жаль, что на ресурсе пока не водятся матёрые эрлангщики, способные подтвердить или опровергнуть ваши громкие заявления.
                                                                            Ответить
                                                                          • Хотя знаете, с учётом моего опыта в телекоммуникациях, заявление о хорошем сервере на питоне, написанным адептом жабаскрипта, вызывает, конечно, не ржачь до коликов, лишь лёгкую ухмылку.

                                                                            У Ericsson очень жёсткие требования к системам, и обработка сетевого трафика поднята на уровень state-of-art. Я видел всё это изнутри, и знаю, о чём говорю.

                                                                            Failover с различными схемами репликации на случай выхода из строя аппаратуры, системы обновления ПО без остановки обслуживания, службы распределённых транзакций, real-time база данных.

                                                                            Траффик не должен останавливаться ни на минуту. Если сгорает плата, активируется другая, причём клиент даже не потеряет соединения. Жёсткие требования к производительности, при добавлении фич performance degradation недопустим. На подготовку специалиста, не знающего системы, уходит 2-3 месяца.

                                                                            Наш сервер был написан на C, хотя для работы нужно было знать архитектуру всей системы. И знаете, сервер мало чем отличается от программы на эрланге: бесконечный цикл, получающий сигнал, а дальше switch по номеру сигнала, извлечение аргументов и вызов нужного обработчика.

                                                                            Процесс не должен хранить лишь минимум локального состояния, иначе при его падении репликант не сможет восстановить это состояние. Состояние хранится в отказоустойчивых контейнерах.

                                                                            Реализация системы исполнителями, конечно, иногда хромает, но в плане архитектуры и требований к системе трудно предъявлять какие-то претензии.

                                                                            И да, поток трафика так велик, что к моменту моего ухода заканчивалась разработка кластера из 72 серверов, способного прикидываться, в переводе на tcp/ip терминологию, одним хостом.

                                                                            Если уж кто и понимает толк в распределённых отказоустойчивых системах, так это инженеры Ericsson (кстати, классные ребята).

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

                                                                              Возможно в среде, специально подготовленной для работы с Эрлангом, где все окружение подходит (например, сохранять нужные данные куда-нибудь отдельно от самой программы - дешево, типа как во встроенной базе данных, и получать их из хранилища, опять же дешево) можно приспособиться - но при том, что имелось в наличие - около 30 арендованых серверов с обычным набором ПО рассчинаным на веб разработку ничего такого не имелось. И в этой ситуации Эрланг не юзабельный по сравнению с чем угодно, именно потому, что сам данные хранить не умеет. Мы пытались как-то научить его работать с Memcached - потому что нам второре было нужнее, но ничего хорошего из этого не вышло.

                                                                              Еще из "фактов" про язык - отладчик никакущий, сравним по убогости с каким-нибудь Firebug отладчиком или что-то такое. В порядке шутки - выполнение не останавливается в точке останова. Останавливается только процесс, который содержит точку останова. В такой ситуации отладить работу с сокетом - цирк да и только. Профайлера памяти нет в принципе, о том, что происходит в программе приходится догадываться используя инструменты общего характера (есть fprof но он меряет только скорость работы).

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

                                                                                произвёл беглый обзор языка

                                                                                вроде бы у каждого процесса в erlang есть "process dictionary" - внутренняя хэш-таблица процесса, выступающая в роли хранилища мутабельного состояния процесса.

                                                                                Т.о., не разрешено лишь разделение данных между процессами (что вполне логично, учитывая проблемы, связанные с многопоточным программированием), а сам erlang довольно далёк от той чистоты, которую предлагает Haskell, и к которой у вас столько претензий.
                                                                                Ответить
                                                                                • Ну так это только к своему процессу можно обратиться - чем это поможет? Это то же самое, что держать значения в аргументах функции этого процесса, просто интерфейс другой.
                                                                                  Ответить
                                                                                  • Объясните, пожалуйста, почему система акторов с локальным состоянием и интерфейсом передачи сообщений не изоморфна системе объектов с внутренним состоянием, доступным только через вызовы методов (как, например, в Java).
                                                                                    Ответить
                                                                                    • Потому, что в Яве вы в большинстве случаев передаете ссылки на объекты.
                                                                                      Ответить
                                                                                      • Ясно. Т.е. если можно передавать структуры в сообщениях, то концептуально - ничем.

                                                                                        Кстати, в последнее время замечаю за собой тенденцию передавать на вход методам интерфейса иммутабельные объекты, содержащие информацию, необходимую для работы сервиса. Фактически и получается строгая инкапсуляция и завуалированная передача сообщений.
                                                                                        Ответить
                                                                                        • >Кстати, в последнее время замечаю за собой тенденцию передавать на вход методам интерфейса иммутабельные объекты
                                                                                          Заметил это за собой давно.
                                                                                          Ответить
                                                                                        • Фигасе "концептуально ничем". Это разница как между NP-полный и NP-трудный. Со стороны может показаться, что они очень похожи, но на практике... :) Ну да, практически одно и то же, передать ссылку на подключение к базе данных, или создать еще однo - а че, результат-то в принципе один и тот же!
                                                                                          Ответить
                                                                                          • я и в джаве подключения никому не даю: получил один раз на нужном уровне, всем остальным велкам через абстракцию
                                                                                            Ответить
                                                                                            • Да, конечно, тоесть вы всякий раз, как посылаете запрос к базе создаете по новому подключению? Или функция, которая владеет подключением в бесконечном цикле за ним следит - чтобы случайно не закрылось? Та ни в жизнь не поверю.
                                                                                              Или вы может быть все-таки создаете свойство со ссылкой на подключение, и обращаетесь к этом свойству повторно, когда возникает такая необходимость? - вот последнее, это как раз то, что нет возможности сделать в Эрланге.
                                                                                              Ответить
                                                                            • Да, а на Эрланге я писал чат бота, ну не то, чтобы очень умного, он просто пересылал сообщения в локальном чате нашего тестового сервера, автоматически подключался / отключался менял статусы и все такое.
                                                                              Ответить
                                                            • Хм, ок. Функция обращается к foo.bar и получает значение 100, затем она делает некоторые вещи, и снова обращается к foo.bar, а там 200. У функции от этого происходит разрыв шаблона, и она уходит на покой, в удачном случае вместе со всей программой. Т.е. чтобы функция могла непротиворечиво поработать с foo.bar ей нужно его либо заблокировать, либо скопировать во временную переменную.

                                                              >Вместе с ивентом послать [...]
                                                              А почему нет? Структуры в эрланге иммутабельны, их пересылка бесплатна (мы заплатили при их "модификации").
                                                              Ответить
                                                              • Ни за что вы не заплатили: при пересылке все что пересылается дублируется еще раз - иногда реально дешевле еще раз из базы данных (типа Memcached) прочитать, чем передавать из процесса в процесс.
                                                                Процессы в Эрланге - это "развод". Их очень дешево создавать, но как только приходит время их для чего-нибудь полезного использовать оказывается офигеть как дорого - сразу все желание пропадает.
                                                                Ответить
                                                • Вы, видимо, не понимаете функциональные структуры данных. Как правило, в них используются совсем другие алгоритмы. Они эффективны за счёт разделения данных, т.е. данные дублируются лишь частично (и обычно эта часть незначительна).
                                                  Это не приводит к противоречиям как раз за счёт иммутабельности структур.

                                                  Пример - Data.Map из Haskell. При добавлении в таблицу новой пары ключ-значение происходит дублирование лишь небольшой, как правило, пренебрежимо малой части данных.

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

                                                      На эрланге пока не писал, но из моего опыта со Scala, где используется похожая модель акторов, следует, что каждый актор должен нести ответственность за свой функционал, и лавинообразное обновление данных при смене статуса выглядит подозрительно.

                                                      Но, разумеется, вашего проекта я не видел и могу чего-то не знать. В Scala всё же можно использовать мутабельные структуры при желании.
                                                      Ответить
                                                    • Только как мутабельные структуры помогут при обновлении данных в зависимых компонентах, которым нужно послать сообщение для обновления - вообще неясно.
                                                      Ответить
                                                      • ИМХО никак, их еще и придется защищать блокировками или делать временные копии.
                                                        Ответить
                                                        • Ну, каждый актор живёт в своём потоке и данными ни с кем не делится (у него всё, так сказать, ThreadLocal). Поэтому блокировки вроде не нужны.

                                                          Актор - это, по сути, правильная интерпретация объекта в ООП: синхронно общается с другими объектами через очередь сообщений.
                                                          Ответить
                                                          • Ну если мутабельная структура не выходит за пределы потока то да, согласен, блокировка не нужна. Но тогда ее или ее части нельзя передавать другим. Придется делать копии.
                                                            Ответить
                                                            • Да, сообщения содержат иммутабельные объекты, и, всего скорее, рантайм решает, отдать объекты как есть (если получатель в том же адресном пространстрве), или сериализовать их в поток для передачи по сети.
                                                              Ответить
                                    • >В смысле монад - нет, ни разу, никто не мешает их реализовать в Яваскрипте, просто это никому не нужно
                                      А jQuery это монада или нет? Хотя ясно что используется оно совсем не в хацкельных целях - для рассовой чистоты функций.
                                      Но все же идея монад, как неких абстрактных стратегий для вычислений цепочек операндов вполне жизнеспобона

                                      >Агрессия - признак баттхёрта.
                                      Не всегда. Зачастую агрессия и треш используются умышленно, для увеселения публики.
                                      Ответить
                          • > абстрактная алгебра, теория категорий и топология
                            Что можете посоветовать почитать по ним?
                            Ответить
                            • На лоре поинтересуйся, там накидают.
                              Ответить
                    • А ещё тупая запись вызова функции через пробел. Такой хуйни нету ни в императивщине, ни в математике (под которую якобы хаскелл косит).
                      Ответить
                      • Это чтобы каррировать удобнее было, количество лямбд сильно сокращается
                        Ответить
                        • Да пох, напишут add(2) (а лучше - add(2, _)) вместо add 2, зато понятнее, что почём.
                          Ответить
                          • > Да пох, напишут add(2) (а лучше - add(2, _)) вместо add 2, зато понятнее, что почём.
                            Вот кстати в Nemerle так и есть:
                            http://ideone.com/KEcLr
                            #pragma indent
                            using System;
                            using Nemerle.Collections.List;
                             
                            def Add(x,y)
                                    x+y;
                             
                            def r = Map($[1..10], Add(5, _));
                            def r = Map(r, 5*_);
                            Console.WriteLine(r);
                            Ответить
                            • http://ideone.com/fn0j3
                              #pragma indent
                              using System;
                              using Nemerle.Collections.List;
                               
                              def Add(x,y)
                                      x+y;
                               
                              def r = Map($[1..10], Add(5, _)); 
                              def Add1 = Add(1,_); 
                              def r = Map(r, Add1); 
                              def r = Map(r, 5*_); 
                              Console.WriteLine(r);
                              Ответить
                              • Почему Map первым аргументом берёт коллекцию, а вторым - функцию? Испокон веков было наоборот.
                                Ответить
                                • Потому что Nemerle может и так:
                                  $[1 .. 10].Map(5+_);

                                  Синтаксический сахар это.
                                  Ответить
                              • Кстати, а умеет ли Немерле на ходу генерировать новую функцию Add(5, _) с сигнатурой int->int (выделяя под неё память в сегменте кода), которая оптимизирована под фиксированный параметр 5 и которую можно передавать по указателю, как функцию с сигнатурой int->int?
                                Ответить
                                • Немерле наверняка просто создаёт новый экземпляр некого класса типа Function<Int, Int>, а низкоуровневой оптимизацией будет заниматься JIT.
                                  Ответить
                      • Если бы каррирование было так нужно в математике - появилось бы. BTW, на функане иногда приводят бесскобочную запись.
                        (И запись в виде отображения f: X -> Y -- находит свой образ в сигнатурах).
                        Ответить
                        • > Если бы каррирование было так нужно в математике
                          Так оно там изначально и появилось, только запись там немного другая

                          В Scala вон для каррирования сделали функции с несколькими наборами аргументов. По мне так запись в Haskell удобнее и нагляднее.
                          Ответить
                  • >Haskell язык может сильно расширить кругозор, в нём сплетено так много необычных идей и концепций.
                    >Он изменил мой взгляд на мир.

                    А вот можно поподробней - какие именно там революционные идеи и концепции, которых больше нигде нету.
                    Ответить
                    • Срач must go on?
                      > которых больше нигде нету.
                      я не говорил, что этих идей и концепций нигде больше нету, они просто образуют суровый замес

                      Иммутабельность, чёткое разделение чистого кода и кода с побочными эффектами, концепция "всё - выражение", ленивость всех вычислений (ввод/вывод тоже ленивый, кстати), строгая статическая типизация (по началу реально удивляешься, когда программы работают сразу же после того, как начинают компилироваться), pattern-matching, внедрение математических концепций в язык, мощная и удобная система модулей. Type Classes меня тоже очень впечатлили (в clojure сделали аналоги - протоколы).
                      Ответить
                      • >Срач must go on?
                        Не срача ради, но токмо в просвещения целях.

                        Так а вот что конкретно привлекло в языке и взорвало мозг? Или всё и сразу.
                        Ответить
                        • Привлекала краткость и выразительность кода (в этом месте @wxvxw смеётся до коликов), строгость. Мозг взрывает обилие нового материала и необходимость переосмысления того, что делаешь в обычной жизни на автомате.
                          Ответить
                        • Ещё до определённого момента мозг взрывают монады и присущая им атмосфера мистификации, хотя на самом деле всё строго и довольно просто. Мне понравилось вот это объяснение:
                          http://ivan-gandhi.livejournal.com/1874069.html
                          Правда, всё усложняется при появлении State и транформаторов.
                          Ответить
                          • Спасибо за ответ, точнее за два.
                            Ответить
                            • Пожалуйста. Хотя особого профита в жизни от ФП я пока не получил, о времени, потраченном на изучение этого матана не жалею. На самом деле писать функциональные программы - большое удовольствие.
                              Ответить
                              • Я уже говорил выше, но всё-таки скажу слово в защиту монад. И применимости их не только в Хацкеле.

                                >В смысле монад - нет, ни разу, никто не мешает их реализовать в Яваскрипте
                                Нам нужно сделать асинхронный вызов. Найти например id человека, а потом сделать другой вызов - по этому id получить деталировку итд.
                                js-способ - вложенные друг в друга callbackи.
                                Монадический же подход - когда результат одного асинхронного вызова передается в другой, разворачивает и упрощает код.
                                Ответить
          • http://s8.postimage.org/y3na0bc0z/haskell_fail.png

            Кстати, я вот не знал, что такое afaiu, а гугл - он все знает.
            Ответить
            • Улыбнуло, впрочем есть утилита (одноименная с командой):
              $ wtf afaiu
              AFAIU: as far as I understand
              Ответить
    • показать все, что скрытоКстати, тему можно минусовать. Здесь мой калл.
      Ответить
    • Govnokod.ru - изучаем Хаскелл вместе.
      Ответить
    • Не минусуйте, держите на плаву, чтоб ТС видел свой калл :)
      Ответить
    • Я вижу императивное говно. Чистый Хаскелл такой чистый.
      Ответить
      • haskell это на самом деле два языка одном: pure core и do-сахар для монадических операторов, который заставляет императивный по природе код (считай с клавиатуры ввод без побочных эффектов ололо) выглядеть действительно как последовательность действий.

        Haskell не исключает код с побочными эффектами (иначе его нельзя было бы использовать в принципе), он просто призывает программиста максимально отделять чистый код от кода с побочными эффектами (так, чтобы даже компилятор мог понять, где какой).
        Ответить
        • >Haskell не исключает код с побочными эффектами (иначе его нельзя было бы использовать в принципе)

          Ну не будем так категоричны. Например юниксовые утилиты типа sed, grep, tail вполне могут работать без побочных эффектов, принимая на stdin данные, и возвращая ответ в stdout. Так что код без побочных эффектов использовать можно, но, конечно, далеко не всегда.
          Ответить
          • таки они пишут в пайпы
            Ответить
            • Ну это потому, что они написаны на императивном языке. А на функциональном они могли бы принять параметром список символов и вернуть на выходе список символов.
              Ответить
              • тогда их, наверное, можно было бы рассматривать как модули более крупной программы, осуществляющей IO, "собираемой" программистом в интерпретаторе из компонент.
                А вообще да, архитектура "фильтры и потоки" функциональна по своей природе.
                Ответить
          • sed в этом списке лишний
            Ответить
            • Почему? Чем его выход не зависит от входа и опций? Если не считать, конечно, случаев когда он сам читает файлы.
              Ответить
              • упс, промахнулся, см.
                http://govnokod.ru/10265#comment138049
                Ответить
              • Ага, имел ввиду и запись, и чтение. Есть еще гнутая /e.
                Ответить
      • Я вижу ошибки трейс. Я слышу неосиляторов лай.
        Ответить
      • Надо признать, что императивное говно и выглядит в хаскеле как говнище.
        Ответить
    • Лучший срач на ГК.ру, я считаю.
      Ответить
      • Это из-за того что по треду мазали говномне до-диез, не кресты, и даже не пасцаль, а хацкель?
        Ответить
        • Были же треды, показавшие флеймопригодность хацкеля
          (а если присутствуют воинствующие любители лишпа - вообще задорно).
          Ответить
        • Ну как бы да - покусились на святое, на небыдло-хаскелл, вопроцение всего антиговнокодерского. Это же ломание всех стереотипов!
          Ответить
          • /r/ поливание говном Ады
            или Оберона-2, хотя-бы
            Ответить
            • Про Оберон на rsdn.ru было, аргументация защитников мне показалась не очень убедительной.
              Ответить
        • Ну, главным образом тут Ерланг говном полили, в достачной степени чтобы отбить охоту даже пробовать его.
          Ответить
          • Хацкель, Ирланг - какая разница. Главное - у кого бутхурт.
            Ответить
    • ну и срач вы тут развели
      Ответить
      • 144 комментария - слабовато
        Ответить
        • Ну ты и дурак, читать не умеешь, написано же, что 157, лол
          Ответить
          • Лол, ты читать что ли не умеешь? Уже как минимум больше 161.
            Ответить
      • Годный срач. Узнал для себя много нового. Например, что я кэннот инту функциональщину. И мне это нравится.
        Ответить

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