Неофициальный путеводитель по мозгу Рича Хики

Original author: flyingmachine
  • Translation
Блог Flying Machine Studios
6 декабря 2012 года
перевод статьи The Unofficial Guide to Rich Hickey's Brain



Частично, мое удовольствие от изучения Clojure возникло благодаря знакомству с мыслями Рича Хики о программировании. У Рича есть свой взгляд на фундаментальные концепции программирования, ясный и последовательный, и я думаю, что каждый программист смог бы выиграть, используя его. Каждый раз, когда я смотрю одно из его выступлений, у меня складывается ощущение, что кто-то взял и привел мой ум в порядок.

В этой статье (а, возможно, и в будущих) я постараюсь упорядочить и каталогизировать уникальную точку зрения мистера Хики. В конечном счете, я бы хотел получить краткое резюме его идей. Я надеюсь, что это приведет к появлению удобной для поиска справки для тех, кто пишет на Clojure, и доступного введения для тех, кто Clojure не использует.

Весь последующий текст основан на выступлении Рича Хики «Are we there yet?»

Вступление


Современные ООП-языки — Ruby, Java, Python, и т.д. — содержат фундаментальный изъян — они привносят непредвиденные сложности, основываясь на неточной модели внешнего мира и реальности. Несмотря на то, что в них существуют явные определения следующих понятий, эти определения неверны:

  • Значение (Value)
  • Состояние (State)
  • Идентичность (Identity)
  • Время (Time)
  • Поведение (Behaviour)

Ниже, мы будем противопоставлять точки зрения ООП и Функционального Программирования (далее ФП) по каждому из этих пунктов. Но для начала, давайте рассмотрим модели реальности, которые лежат в основе ООП и ФП — это именно то фундаментальное различие, которое приводит к применению столь разных подходов в определении вышеописанных понятий.

Метафизика, программирование и вы: Сравнивая ООП и ФП


Как правило, когда разговор заходит о метафизике, то вещи начинают терять четкую форму, но, к счастью, в этом есть определенный смысл.

Как учит нас Wikipedia, метафизика пытается как можно более широко ответить на два основных вопроса:

  • Что там?
  • На что это похоже?

Рич Хики поясняет разницу между метафизикой ООП и ФП на примере ответа на вопрос «Что есть река?».

Объектно Ориентированное Программирование


Согласно метафизике ООП, река это то, что на самом деле существует в реальном мире. Знаю, знаю, я даже слышу как вы спрашиваете: «Да, и что?», но, поверьте, точность этого заявления не давала спать многим философам.

Хитрость в том, что река постоянно меняется, и её воды никогда не перестают течь. В терминах ООП мы бы сказали, что у реки есть изменяющееся (mutable) состояние, и оно (состояние) постоянно колеблется.

Факт того, что состояние Объекта Река и Объектов в целом никогда в реальном мире не бывает постоянным, тем не менее не мешает нам рассматривать их в качестве фундаментальных строительных блоков наших программ. Более того, это выставляется преимуществом ООП — не важно, как меняется состояние — вы взаимодействуете с жестко описанным интерфейсом и все работает ровно так, как вы того ожидаете. Объект может меняться, но для всех наблюдателей он продолжает оставаться ровно тем же самым объектом.

Это соответствует нашему интуитивному восприятию окружающего мира. Электроны в моей чашке кофе перемещаются, но на вкус это все еще кофе, как я и ожидал.

В конце концов, в ООП объекты думают. Они действуют друг на друга. И опять, это соответствует нашим представлениям о мире, где изменения — это результат действий одних объектов на другие. Объект Человек толкает объект Дверь и перемещается в объект Дом.

Функциональное программирование




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

«Река» это не вещь сама по себе, а понятие, которое мы накладываем на последовательность связанных с ним явлений. Эта концепция очень полезна — я не буду возиться с пояснением этого, — это всего лишь концепция.

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

Эти частицы не действуют друг на друга, и они не могут быть изменены. Они не могут ничего делать. Изменение не является результатом действия одного объекта на другой, изменение является результатом процесса, применяемого к неизменяемой частице. Сказать, что что-то изменилось, это все равно что произнести: «О, это новая частица в этом потоке частиц». Это все равно что сказать, что HEAD указывает на новый коммит в Git-репозитории.

Ну ладно, хватит с метафизикой! Теперь опишем более полезные темы, начиная со Значения.

Значение (Value)


Это очевидно, что числа 3, 6 и 42 являются значениями. Числа постоянны, неизменны.

Так же должно быть очевидным и то, что ОО-языки не имеют правильного определения для значений в таком смысле. Как указывает Рич Хики, вы можете создать класс, экземпляры которого состоят из неизменяемых частей, но у вас нет высокоуровневой концепции, которая бы в целом выражала класс как неизменяемое значение.

Это одна из основных причин головных болей при использовании ООП. Сколько раз вы рвали на себе волосы, в попытках выяснить, как был изменен атрибут объекта? На самом деле, в объектно-ориентированных языках нет встроенного механизма для того, чтобы определить — устойчиво ли состояние объекта или нет.

Это одна из причин, почему конкурентное программирование такое тяжелое. Даже в однопоточных приложениях это проблема, и это то, из-за чего мы вынуждены писать обширные наборы тестов. Вы не можете быть уверены, что вызов метода на объекте Парик никоим образом не приведет к изменению объекта ОчкиХипстерские.

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

Идентичность (Identity)


В выступлении мистер Хики говорит:
«Самая большая проблема в том, что мы путаем две вещи. Мы высказали идею о том, что нечто, что изменяется во времени и есть наш объект, вещь.»

В ФП мы оперируем простым именем, которое мы дали последовательности связанных частиц. «Река» соответствует последовательности R1, R2, R3 и т.д., произведенной процессом «течения» реки. Существует прямая аналогия с HEAD в git — это просто имя, которое указывает на фактические значения. В ООП нет такого различия.

Или, как он сам говорит:
«Соответствие это связь мнимого объекта с серией причинно-связанных значений (состояний) с течением времени. Это метки, которые мы используем для именования временных отрезков.»


Состояние (State)


В ООП не существует четкого определения состояния. Может быть это «значение всех атрибутов объекта прямо сейчас». И это вынужденное «прямо сейчас», потому что нет никакого языкового механизма, позволяющего заглядывать в прошлое.

Это становится более понятным, если вы проведете сравнение с понятием идентичности в ФП. В Хиксианской вселенной, Состояние является определенным значением в определенный момент времени. (Для меня, это определение действительно расставило все по местам.)

Время (Time)


В ООП нет реального представления для времени. Все происходит «прямо сейчас». Это то, что приводит к проблемам в конкурентном программировании.

Напротив, в мире ФП, который мы изучаем, понятие времени хорошо определено. Время это субпродукт процесса именования (идентификации) состояний.

Поведение (Behavior)


Наконец, поведение. Мне особо нечего писать здесь — наверное, я еще понаблюдаю за выступлениями, но я все же приведу фразу мистера Хики, приглашающую вас задуматься:
«Нет никакого поведения. Когда вас ударила молния, кто себя „ведет“?»

Может это то, что сподвигло Steve Yegge написать «Execution in the Kingdom of Nouns»

Конец


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

Примечания переводчика


Статья не совсем свежая, но мне показалось достаточно интересной, а в комментариях к оригинальному посту, наверное, еще интереснее. К сожалению, перевод дискуссии выходит за рамки моего участия.
Share post

Similar posts

Comments 46

    0
    Спасибо за статью. Ею Вы ещё больше подстегнули таящееся желание изучить какой-нибудь функциональный язык.
      +13
      У изучения ФП-языков есть один скрытый минус: после изучения ФП-языка ООП-языки начинают несколько раздражать.
        +3
        Звучит устрашающе, но я пожалуй рискну)
          +4
          Рискуйте. Чем больше подходов вы изучите, тем лучше будете орудовать по отдельности каждым из ним. Есть хорошая программерская пословица на тему холивара ООП vs ФП: «замыкания — объекты для бедных, объекты — замыкания для бедных». Все суть одно и тоже, только акценты расставлены в разных местах. ФП позволяет взглянуть на тоже самое под другим углом, и по большому счету, совсем не обязательно пользоваться именно ФП-языками, чтобы выражать код в функциональном стиле.
          +3
          Вы, как и автор статьи путаете мягкое с холодным.
          Нельзя противопоставлять процедурное и функционально программирование. Это просто два разных подхода для решения насущных задач. И то что на протяжении десятилетий они существуют вместе, как бы намекает об этом.
          Есть много задач которые элегантно решаются с помощью, например Erlang'a, с другой стороны если начать его использование повсеместно, то появляется куча головной боли, которой с применением ОО-подхода не было бы.
          Многие, кто приступает к изучению функциональных языков, видят как хорошо, порой, задачи из реального мира ложаться на код. Однако забывают про ограничения ФП. Например в реальном мире есть монитор и принтер, которые являются «разделяемыми ресурсами» как и воздух и земля по который мы ходим. И вот тут начинаются проблемы =)
          Выхода два: или пользоваться ОО-языком для решения задач с большим количеством сайд-эфектов, или изобретать монады
          Так что каждой задаче — свой инструмент.
            0
            Не путаю. Просто в моем случае лаконичность плохо сочетается с однозначностью.
            Ниже я уже описал более подробно свое мнение о споре ФП vs ООП.

            Более подробно мой комментарий, на который вы ответили, можно рзвернуть следующим образом:
            «После изучения языков с поддержкой фич из ФП-парадигмы и асоциируемых с ней (таких как pattern matching, удобные immutable структуры данных, акторы, type inference, удобное создание обобщенных методов, наличие большого количества ужже созданных обобщенных методов, отсутствие null, удобное создание лямбд, etc) языки, не предоставляющие удобной поддержки большинства этих фич, вызывают раздражение.»

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

            Возьмем тот же C#: все хорошо. Есть лямбды, extension методы, LINQ, var. Но как же иногда не хватает val, pattern matching и case class из scala.
              0
              Вот насчёт паттернматчинга спорить не буду, его действительно нехватает и это бесспорно очень удобная штука.
              Но лямбды, лист компрехеншн и прочие функциональные приёмы давно перекочевали в ОО-языки. Своим прошлым комментом я просто хотел сказать что в функциональном программировании тоже есть много чего что «бесит» и чем пользоваться неудобно.
                +1
                Своим прошлым комментом я просто хотел сказать что в функциональном программировании тоже есть много чего что «бесит» и чем пользоваться неудобно.


                А что вас конкретно бесит в фп и чем там неудобно пользоваться?
                  0
                  Ниже ответил, процитирую тут
                  1. Из-за оптимизации хвостовой рекурсии стэктрейсы (и без того запутанные) становятся сложно-читаемыми
                  2. Геморой с сайд-эффектами
                  3. Постоянный вопрос «А есть ли у меня в данном участке кода все необходимые данные? Чёрт, надо их прокинуть через несколько вызовов, совершенно других функций или использовать какой-нибудь другой манёвр с бубном»
                  4. Редко, но очень «метко» вы можете залипнуть в логи и даже остановить сервант, потому-что где-то любимая вами рекурсия вышла из-под контроля и сожрала весь проц/память
                    0
                    Спрашиваю не просто так, а действительно интересно.

                    Из-за оптимизации хвостовой рекурсии стэктрейсы (и без того запутанные) становятся сложно-читаемыми


                    Не замечал ни в Common LIsp-е, ни в clojure. Можете привести пример?

                    Геморой с сайд-эффектами


                    Можете немного поподробнее?

                    Постоянный вопрос «А есть ли у меня в данном участке кода все необходимые данные? Чёрт, надо их прокинуть через несколько вызовов, совершенно других функций или использовать какой-нибудь другой манёвр с бубном»


                    Это согласен. Просто нужно учитывать, что при использовании фп языка меняется не только синтаксис, но и парадигма программирования. В этом то и смысл.

                    Редко, но очень «метко» вы можете залипнуть в логи и даже остановить сервант, потому-что где-то любимая вами рекурсия вышла из-под контроля и сожрала весь проц/память


                    Что значит «рекурсия вышла из-под контроля »? Это же ваш код — как написали, так и работает. При чем тут фп?
                      0
                      Не замечал ни в Common LIsp-е, ни в clojure. Можете привести пример?

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

                      Геморой с сайд-эффектами

                      Можете немного поподробнее?


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

                      Что значит «рекурсия вышла из-под контроля »? Это же ваш код — как написали, так и работает. При чем тут фп?


                      Даже если вы пишете код в одиночку:
                      — вы не застрахованы от ошибок
                      — кода становится больше, энтропия возрастает
                      — вы многое можете забыть в коде который вы писали полгода назад

                      Ну а в реальной жизни код пишется командой и энтропия ещё сильнее возрастает.

                      А вообще ни кто не застрахован от ошибок, но зависший сервер — это слишком высокая цена, в питоне например вам надо сиииильно постараться чтобы сделать такое,
                      Кроме того, понять из-за чего именно и в какой момент произошло зацыкливание, не самая тривиальная задача.

                      P.S. не думал что мой коммент вызовет столько вопросов. Всё что я хотел сказать — выбирайте инструмент соответствующий задаче, ФП идеально подходит для одних задач ПП — для других, есть задачи, которые можно реализовать и так и так, с определёнными оговорками. Нет универсального подхода для всего! Все же снают что у серебрянных пуль начинка чаще всего, пардон, из говна. У любого программиста должны быть на вообружении оба подхода и он должен уметь грамотно применять их для решения конкретных задач вот и всё.
                        0
                        Не вижу смысла копипастить сюда километровый лог, неужели это не очевидно? Одно дело, если вы видите в стэктрейсе полную картину происходящего, и совсем другое если некоторые кадры отсутствуют из-за оптимизации.


                        Значит, у вас были проблемы со стэктрейсом в ерланге? Т.е. это какая-то другая конкретная проблема вас и ерланга, не имеющая отношения ни к ФП вообще, ни к другим функциональным языкам? А проблему вы решили? Спрашивали на stackoverflow, например? Что вам ответили?

                        Геморой с сайд-эффектами

                        Можете немного поподробнее?



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


                        Т.е. в вашей программе на ерланге вы используете много мест с сайд эффектами, что привело к тому, что вам неудобно на этом языке контролировать сложность программы? При чем тут ФП?

                        Даже если вы пишете код в одиночку:
                        — вы не застрахованы от ошибок
                        — кода становится больше, энтропия возрастает
                        — вы многое можете забыть в коде который вы писали полгода назад

                        Ну а в реальной жизни код пишется командой и энтропия ещё сильнее возрастает.


                        Я не понял, к чему это. Пропущу.

                        А вообще ни кто не застрахован от ошибок, но зависший сервер — это слишком высокая цена, в питоне например вам надо сиииильно постараться чтобы сделать такое,

                        Я не понял как взаимосвязана страховка от ошибок и питон.

                        Кроме того, понять из-за чего именно и в какой момент произошло зацыкливание, не самая тривиальная задача.


                        В смыле, для вас рекурсивные алгоритмы являются проблемой и неискоренимой причиной ошибок?

                        P.S. не думал что мой коммент вызовет столько вопросов.


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

                        ФП идеально подходит для одних задач ПП — для других, есть задачи, которые можно реализовать и так и так, с определёнными оговорками. Нет универсального подхода для всего! Все же снают что у серебрянных пуль начинка чаще всего, пардон, из говна. У любого программиста должны быть на вообружении оба подхода и он должен уметь грамотно применять их для решения конкретных задач вот и всё.


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

                          0
                          Ох… я не буду продолжать холиварить, сапиэнти сат
                          Вы очевидно теоретик, и с практикой редко сталкиваетесь, так же очевидно что вы пишете код в одиночку а не работаете с большой командой командой
                          Тут спорить бесполезно делайте как вам нравится
                            0
                            Ох… я не буду продолжать холиварить, сапиэнти сат

                            Правильное решение.

                            Вы очевидно теоретик, и с практикой редко сталкиваетесь, так же очевидно что вы пишете код в одиночку а не работаете с большой командой командой

                            Чудеса да и только.

                            Тут спорить бесполезно делайте как вам нравится

                            Тут читают молодые люди, которые «находятся в поиске». И такие посты как ваш оригинальный комментарий могут их смутить (по себе помню). Поэтому имхо спорить с подобным полезно.
                              0
                              Я рассказал о своём конкретном опыте, вы же теоритизируете в вакууме. Думаю для молодых разработчиков полезнее практический опыт.
                                +1
                                Я рассказал о своём конкретном опыте, вы же теоритизируете в вакууме.

                                Значит, ваши обобщенные рассуждения в первых комментариях были недоразумением? Ок.

                                Думаю для молодых разработчиков полезнее практический опыт.

                                То, что вы описали, не может являться для кого бы то ни было «практическим опытом». По вашему описанию с побочными эффектами и прочим видно, что вы не хотите мучиться, изучать, менять свое императивное мышление. Напротив, в вас родилась, судя по слову «бесит», ненависть к ФП и ерлангу в частности. Плохой пример для подражания.
                                  0
                                  Охх… да вы жирный троль то)))
                                  Слово «бесит» употребили вы, меня оно покоробило и я сделал вам замечание
                                  Сначала в общем, потом разжевал всё как для младенца.
                                  По вашим комментам видно, что вы имеете мало опыта в разработке и много опыта в болтологии. Ещё раз повторю — вы троль, да ещё и опасный, так как располагаете большим количеством свободного времени. И кормить вас я больше не собираюсь.
                                    0
                                    Слово «бесит» употребили вы, меня оно покоробило и я сделал вам замечание

                                    Вот пруф. Не позорьтесь.
                                    Сначала в общем, потом разжевал всё как для младенца.

                                    Да, вы хорошо разжевали свой fail с ерлангом и фп.
                                    По вашим комментам видно, что вы имеете мало опыта в разработке и много опыта в болтологии. Ещё раз повторю — вы троль, да ещё и опасный, так как располагаете большим количеством свободного времени.

                                    Вы в третий раз проявляете чудеса телепатии. Может отбросите эзотерику и займетесь самообразованием?
              +1
              Выхода два: или пользоваться ОО-языком для решения задач с большим количеством сайд-эфектов, или изобретать монады


              Ваш вывод неверен. Вы ошибаетесь, разделяя программирование с побочными эффектами и функциональное программирование. ФП и побочные эффекты — вещи перпендикулярные. Есть отдельное понятие pure functions, с помощью которых реализуется программирование без побочных эффектов. Например, в хаскеле соблюдается «чистота» (монады нужны), а в той же схеме или clojure — нет (необходимости монад нет).

              Вы, как и автор статьи путаете мягкое с холодным.
              Нельзя противопоставлять процедурное и функционально программирование. Это просто два разных подхода для решения насущных задач.


              Разделять процедурное программирование и фп можно и нужно. Различие между данными подходами колоссальные. ПП это императивное программирование, где весь код представляет собой пошаговое изменение глобального/локального состояния программы. ФП — это композиционное/декларативное программирование с помощью функций (с побочным эффектом или нет). ПП это высокоуровневое продолжение ассемблера. ФП идет из математики. Эффективное ФП возможно благодаря таким свойствам ФЯ, как функции высокого порядка/функции — граждане первого класса, рекурсия (с оптимизацией хвостовой рекурсии), замыкание. Поверьте, разница между ФП и ПП подходами к решению просто громадная.

              Однако забывают про ограничения ФП. Например в реальном мире есть монитор и принтер, которые являются «разделяемыми ресурсами» как и воздух и земля по который мы ходим. И вот тут начинаются проблемы


              В тексте есть вывод про ограничения, но нет аргументов и примеров.
                0
                Вы не очень внимательны =)
                Противопоставлять != Разделять

                «Поверьте, разница между ФП и ПП подходами к решению просто громадная»

                Вы видимо издеваетесь))) Я и не говорю что разницы нет, и верить мне вам не за чем так как я использую питон и эрланг в продакшене и разница для меня очевидна =). А вы, зачем-то копипастите текст из википедии))

                Странно что вы спрашиваете меня про ограничения ФП, если вы писали что-то сложнее «hello-world»
                1. Из-за оптимизации хвостовой рекурсии стэктрейсы (и без того запутанные) становятся сложно-читаемыми
                2. Геморой с сайд-эффектами
                3. Постоянный вопрос «А есть ли у меня в данном участке кода все необходимые данные? Чёрт, надо их прокинуть через несколько вызовов, совершенно других функций или использовать какой-нибудь другой манёвр с бубном»
                4. Редко, но очень «метко» вы можете залипнуть в логи и даже остановить сервант, потому-что где-то любимая вами рекурсия вышла из-под контроля и сожрала весь проц/память
                Если этого вам мало могу продолжить уже конкретно по Эрлангу.
                  0
                  1. Из-за оптимизации хвостовой рекурсии стэктрейсы (и без того запутанные) становятся сложно-читаемыми

                  Оптимизированная хвостовая рекурсия — это stateless запись цикла. Вы же не будете городить полноценную рекурсию вместо цикла только для стектрейса?

                  2. Геморой с сайд-эффектами

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

                  Постоянный вопрос

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

                  любимая вами рекурсия вышла из-под контроля и сожрала весь проц/память

                  Что характерно с этой проблемой я сталкивался и на не ФП языках. Вот только именно в ФП языках с ней борются наиболее активно. Единственный язык. в котором можно действительно не бояться рекурсии — scala (@tailrec гарантирует хвостовую оптимизацию).

                  Давайте по эрлангу. Я его не знаю. но с концепцией акторов знаком.
                    0
                    Вы видимо издеваетесь))) Я и не говорю что разницы нет, и верить мне вам не за чем так как я использую питон и эрланг в продакшене и разница для меня очевидна =).


                    Нисколько. Можете прочитать вместо «разделять» «противопоставлять».

                    А вы, зачем-то копипастите текст из википедии))


                    Сам набрал. Никуда при этом не подглядывал. Тема то старая.

                    1. Из-за оптимизации хвостовой рекурсии стэктрейсы (и без того запутанные) становятся сложно-читаемыми
                    2. Геморой с сайд-эффектами
                    3. Постоянный вопрос «А есть ли у меня в данном участке кода все необходимые данные? Чёрт, надо их прокинуть через несколько вызовов, совершенно других функций или использовать какой-нибудь другой манёвр с бубном»
                    4. Редко, но очень «метко» вы можете залипнуть в логи и даже остановить сервант, потому-что где-то любимая вами рекурсия вышла из-под контроля и сожрала весь проц/память


                    Ответил выше.

                    Если этого вам мало могу продолжить уже конкретно по Эрлангу.


                    Не писал на нем ничего. Но надеюсь, вы сможете сформулировать проблему безотносительно к конкретному фп языку. Или у вас именно ерланг вызвал проблемы?
                      0
                      Вы сказали что бесит вас в ПП подходе, я сказал что бесит меня в ФП подходе, постарался выделить не специфичные для эрланга моменты. А если брать сам эрланг, то до знакомства с ним в «боевых» условиях я встречал множество хвалебных отзывов о нём, некоторые товарищи даже утверждали что на этом языке можно написать всё что угодно гораздо проще и быстрее чем на чём-то ещё. Теперь подобные высказывания у меня ни чего кроме смеха не вызывают.
                      Итак о том что меня бесит в эрланге:
                      1. Очень мало готового кода, для решения повседневных задач, очень часто приходится городить велосипеды. Особенно умиляют ответы на стэковерфлоу из серии
                      — «Как сделать эту очевидную штуку?»
                      — «Элементарно, дорогой друг, надо всего-то написать вот эти тридцать строк кода и всё»
                      а то что это из коробки доступно чуть менее чем везде очень доставляет
                      2. Жуткий геморой с рекордами — этот очевидный костыль за 20 лет ни кто не исправил, работать с ними очень неудобно
                      3. После питона меня раздражает консоль ерланга, в которую я не могу так просто засунуть кусок кода и поиграться с ним, но это наверно субъективно, хотя всё равно не очень удобно.
                      4. Патерн актор хорош для построения инфраструктуры или для создания системы с готовым ТЗ, которая будет работать продолжительное время без сильного изменения логики, в реально веб аппликейшене, всё очень часто и порой радикально меняется и в какой-то момент понимаешь что больше думаешь о том «как это сделать» чем о том «что собственно надо сделать» Ну и в общем решать все проблемы одним паттерном — глупо.
                      5. Геморой с utf, в коде невозможно нормально с ним работать.
                      6. Строки — листы интов. Отдельная песня

                      Не хочу, чтобы создалось впечатление, что я ненавижу эрланг)) У него есть оочень много сильных сторон
                      1. Машины на разных концах планеты я легко и прозрачно могу заставить работать вместе, не задумываясь о протоколах и безопасности, если последнее меня беспокоит, я легко могу настроить коммуникации между нодами как мне нравится
                      2. Супер мощная, умная и быстрая виртуальная машина, (видимо поэтому появился elixir)
                      3. Паттернматчинг, особенно с бинарями, оочень удобно
                      4. Комуникация между потоками при помощи «записочек» =), единственный минус — дедлоки, но это скорее редкость и в основном по глупости, в остальном одни плюсы.
                      5. Легковесные потоки

                      Это далеко не полный список, просто то что сразу могу вспомнить.

                      Ну и лично моё мнение erlang — язык для создания инфраструктуры, он был задуман и долгое время использовался исключительно для данной цели и он делает это на 5+
                      Это не универсальный язык, и использовать его для «всего» — это как отвёрткой в зубах ковырятся — вроде можно, но оочень неприятно. Хотя надо отдать должное, в опенсорсе он не так давно и, я думаю, по прошествии какого-то времени большую часть проблем пофиксят.

                      И на десерт, на лурке классно сказано (прошу прощение за мат):
                      Любители выебнуться писать на Эрланге хвастаются тем, что могут наплодить кучу потоков, работающих быстрее света, но мы-то знаем, что за все это время они наплодили чуть менее, чем нихуя программ.
                      lurkmore.to/Erlang

                        0
                        Вы сказали что бесит вас в ПП подходе,

                        Когда?

                        я сказал что бесит меня в ФП подходе, постарался выделить не специфичные для эрланга моменты.

                        А вы не думали, что это специфичные проблемы связаны только с вами, вашим знанием ФП и вашим опытом использования ерланга? Думаю, некорректно на таком материале делать обобщенные утверждения про все ФП.
                          0
                          Вы — троль и у вас явно много свободного времени,
                            0
                            Ну что вам еще сказать, правда?
            0
            Спасибо за перевод интересного материала, даже несмотря на то, что я не согласен со статьёй ))

            1) Мы не можем представить всё как работу с неизменяемыми данными. Насколько я знаю, Haskell пытается отделить работу функций с побочными эффектами (т.е. изменяющих состояние системы) с помощью монад, но избежать использования таких функций никто не может.

            2) Я не представляю такого процесса, который бы нельзя было выразить в терминах ООП. Просто ФП выражает это немного по-другому, но тут уж дело вкуса, как мне кажется. И всё-таки современная физика описывает мир в терминах объектов и их взаимодействий (т.е. существуют и объекты, и процессы)

            3) Когда вас ударила молния, то мне как раз понятно, кто и как себя ведет. Молния передает свою энергию телу человека, клетки которого под воздействием сообщенной энергии… и т.д.

            4) Для работы со значениями, такими как числа, строки и прочие неизменяемые данные, и в ООП, и в ФП существуют константы.

            А ФП я и сам люблю, правда к сожалению ничего для продакшена пока писать не приходилось, пока только использую как хобби.
              +6
              Вы не против подискутировать не с автором и не с переводчиком?

              1) Мы можем представить почти все как работу с неизменяемыми данными. Это уже очень удобно. Пока я не попробовал ФП я не представлял насколько это удобно.
              Но всегда остается небольшая часть, которую сложно представить как работу с неизменяемыми данными. В этом случае есть как минимум 2 подхода:
              1. Все еще представляем это как работу с неизменяемыми данными. Получаем функции, «изменяющие вселенную». Простейший пример: получение следующего случайного числа, возвращающее не только само число, но и новый генератор (повторный запрос случайного числа у старого генератора вернет то же самое число).
              2. Отступление от «чистоты». Мы все еще пользуемся всеми преимуществами ФП, но в некоторых местах отступаем от концепции ФП. Эти отступления мы ограничиваем каким-либо local scope (например актор в scala), так что они не распространяют негативного воздействия.


              2) ФП можно выразить в терминах ООП (см scala). Тут вопрос концепции. И любую программу можно написать в машинных кодах. И как физик вам говорю: современная физика выражается в терминах данных и операций над ними. И большая часть кода физических библиотек все еще на фортране =).

              4) Вообще-то не константы, а immutable переменные. Просто ФП вводит более строгую идеологию относительно того, что должно быть immutable (не только числа и строки, а вообще все).

              И не стоит начинать спор ФП vs ООП. ФП с ООП не соперничают. ФП может существовать без ООП или сосуществовать с ООП в одном языке.
              Вопрос стоит ставить таким образом: «ФП vs не ФП».
                0
                Вы не против подискутировать не с автором и не с переводчиком?
                Я только за)

                1) Совершенно согласен. Но это ведь не прерогатива ФП.
                1. Не очень оптимально, очень похоже на попытку соблюсти принципы ФП любой ценой
                2. Согласен

                2), 4) Трудно поспорить

                В результате мы приходим к тому, что нет никакой серебряной пули, и что гораздо выгодней совмещать подходы, чем доказывать всем, что ООП/ФП рулит. Всё как обычно )
                  +1
                  Точно так же мы могли бы обсуждать процедурное программирование vs ООП.
                  ООП вполне реализуется на процедурных языках при помощи конвенций, библиотек и небольшого объема ручной работы.

                  ООП — это не запись первого аргумента перед названием метода через точку. И это даже не иерархия классов.
                  ООП — это 3 простых принципа и можно было бы сказать, что «гораздо выгодней совмещать подходы». Но если держать в головен эти принципы постоянно, если эти принципы впитать так, чтобы они казались единственно верными — тогда и получим плюсы ООП.

                  Так и с ФП. Если считать, что immutable, конечно, не плохо бы использовать. Да и отделение действий от данных тоже иногда полезно… И так далее. То плюсов мы не получим.
                  Пюсы ощутимы только когда создание mutable-объекта — это целое событие, необходимость которого надо обосновать. Когда слово «монада» становится близким и родным. Когда все или почти все действия описываются в обобщенном виде. Когда язык действительно поддерживает набор ФП и околоФП плюшек — только тогда мы получим плюсы ФП.

                  А до тех пор будет «Всё как обычно».
              +2
              хочу ещё)
                +1
                Буду следить за блогом автора, постараюсь перевести, если появится продолжение.
                • UFO just landed and posted this here
                  0
                  Неплохо было бы и английский выучить. Конкурентное программирование, скорее всего — concurrent, то есть — параллельное программирование.
                    +11
                    Я с вами не соглашусь. Во-первых, даже в английском языке понятия parallel programming (computing) и concurrent programming существуют, простите за каламбур, параллельно. Во-вторых, в переводах на русский (и не только в переводах, а и в оригинальных статьях) термин «конкурентное программирование» используется. Возможно потому, что по-смыслу хорошо отображает суть процесса — конкуренция процессов/потоков за ресурсы.
                    0
                    parallel programming (computing) и concurrent programming в английском — синонимы. То, что в русском есть термин конкурентное программирование ничего не меняет. В статье слово concurrent совершенно точно обозначает — параллельный.
                      +6
                      Это не синонимы.

                      Parallel programming — это, например, если вам надо перемножить 10 пар чисел, то вы запускаете 10 потоков, которые это выполняют, но при этом действуют независимо, друг другу не мешают (как известно, параллельные прямые не пересекаются)

                      Concurrent programming — это работа разных потоков над одними и теми же данными, при этом необходимо их как-то синхронизировать, упорядочивать доступ к данным и т.д.
                        0
                        Это и есть — синонимы. Близкие по значению, но отличающиеся некими оттенками смысла. В любом случае в статье слово concurrent употребляется в смысле параллельности а не конкуренции.
                          +3
                          Не соглашусь. immutable переменные и stateless объекты интересны именно в контексте конкуретного программирования. Суть в том, что потоки даже теоретически не смогут помешать друг другу, так как нет разделяемого состояния, раз уж нет ни какого состояния.
                            0
                            Конкурентность может быть без параллелизма.

                        0
                        У оригинальной статьи отличный первый комментарий, достойный отдельной статьи.

                        Там и некоторые неточности указаны, да и вообще соображения на тему «функциональщина нас спасет, или это такой же хайп, который был при популяризации ООП».

                        Рекомендую.
                          +3
                          Хайп по поводу ООП очень сильно качнул маятник в сторону этого самого ООП, что привело к тому, что очень многие люди, накушавшись «ООП» (я не зря в кавычки взял), пришли к выводу, что многие вещи можно делать гораздо проще, а маятник набирает скорость в обратном направлении.

                          Сколько в больших проектах «классов», которые *Util, со public static методами? «Классы», в которых нет ничего, кроме данных. «Классы» из конструктора и одного метода. И т.д.

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

                          «Sometimes, the elegant implementation is just a function. Not a method. Not a class. Not a framework. Just a function.» — twitter.com/ID_AA_Carmack/status/53512300451201024
                          +2
                          Какой-то метафизический шлак, абсолютно неаргументированные тезисы типа «в ООП этого нет или это реализовано говено, а в ФП это реализовано круто». Примеры! Я хочу примеры, хочу реальные случаи из практики, а не интерпретация вырванных из презентации Хикки мыслей. Без примеров из реального мира статья похожа на «бла-бла-бла».

                          P.S. Ничего против ФП не имею.
                            0
                            Согласен. Мне тоже не понятно, что сим хотели донести Хики/пересказчик/переводчик. По-моему, взявшийся пересказывать его сам ничего не понял.
                            > У Рича есть свой взгляд на фундаментальные концепции программирования, ясный и последовательный…
                            :)
                            +1
                            Если в ООП не заложено сохранения состояний, то его и не будет… Не вижу никакой проблемы реализовать историю состояний на ООП. Если это, конечно же, нужно для задачи…

                            Параллельное программирование в объектном стиле проблематично потому, что все наработанные методологии, паттерны и библиотеки как правило в принципе не учитывают такой параметр как время. А без этого не может быть никакой истории состояний со всеми вытекающими отсюда последствиями…

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

                            За использование подобного в коде, кое-кто кое-кому отрубит руки по самые локти и в общем-то будет прав…

                            Поэтому еще раз: С параллельным программированием в ООП сложно не потому, что парадигма кривая, а потому, что в существующих реализациях ООП работа со временем и соответственно с состояниями никак не предусмотрена…
                              0
                              Заголовок доставил. По чьему ещё мозгу можно попутешествовать? :)

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