Первоклассный объект как объект языка, а не как сущность из ООП
тут надо отметить, что любой объект как сущность ООП является первоклассным объектом языка, в том числе функция. В некотором смысле, можно рассматривать первоклассные функции как частный случай.
Поэтому нет особой необходимости использовать термин формальной чистоты, поскольку он уже замещен более сильным понятием. И тогда ничего плохого нет в том, чтобы вольно трактовать чистоту. Короче говоря, читайте книги, друзья, и практикуйтесь, чтобы не делать ляпов, изобретая собственную «терминологию» из-за непонимания существующей!
Ага, что позволено Юпитеру, то не позволено быку. Я не могу потребовать, чтобы мне дали внятное определение функционального языка, а руководству секты Хаскеля разрешено трактовать чистоту вольно. А всё почему? Потому что они - великие создатели Хаскеля, а я - всего лишь den73.
А где остальные пункты? Ты выкинул из пяти 4 пункта и доколупался к пятому, который действительно сильно зависит от реализации. В JS достаточно знать что функция, один фиг параметров можно передавать сколько и каких душе угодно. В каком-нибудь ML-like надо знать сигнатуру.
И теперь ответь: ты троллишь, разводишь демагогию, занимаешься членомеркой или просто тупишь?
Всё равно сегодня не работается, поэтому отвечу: Яр тут вообще не при чём. Речь идёт о кривизне терминологии.
Ну не знаю, неужели ни у кого нет собственного мозга, чтобы понять, что опасно одним и тем же словом обозначать две разные вещи, что хаскеллисты исказили смысл понятия чистоты до того, что аж Монка сумели заморочить, что понятия недоопределены. Мне ни один человек ни разу не ответил в явной форме ни да, ни нет.
Вот давайте заменим названия цветов: жёлтый тоже будем называть зелёным. Удобнее станет? Ясно, что так никто в здравом уме делать не будет. А почему тогда два независимых понятия (чистота и первоклассность) обозначают одним словом и это коробит только меня?
Я вот не пойму, вы когда открываете свои «умные» книжки, сразу верите всему, что там написано? Не проверяете на непротиворечивость? Кричите «аллилуйя, я наконец-то приобщился к великому сокровенному знанию»? Т.е. труд осилить понятия настолько велик, что звоночек не звенит, что написано-то говно? Или радость познания настолько велика, что звоночка не слышно?
Меня вот не мехмат, а курс геометрии в школе научил тому, что такое «доказательство» и что такое «определение». И когда я гляжу на понятие ФП, я вижу, что понятия-то нет, есть каша в голове. Довольно тяжело смотреть, как эта каша варится у всех моих собеседников, и никто не видит, что это каша, не пытается от неё дистанцироваться.
Впрочем, это дело ваше.
Ведь совершенно очевидны дыры в логике здесь.
То же касается и функциональности Си. Если брать критерий поддержки чистых функций контролем компилятора как главный (а иного смысла не может быть), то да, Си более функциональный, чем CL. Если брать ваше мутное определение «first class citizen», то можно поспорить. Но тогда, кстати, можно поспорить и о методах создания. Я не понимаю, почему это зависит от языка. В Лиспе я могу создать функцию по исходнику, введённому в консоли. В языках без eval это невозможно сделать (разве только написать интерпретатор). Давайте включим это в понятие «first class», и тогда резко С++ выпадет из обоймы.
Ты выкинул из пяти 4 пункта и доколупался к пятому, который действительно сильно зависит от реализации.
Ну вот смотри: для уборки в сортире нужно:
помыть пол
почистить ёршиком унитаз
протереть сиденье
поставить новый рулон туалетной бумаги, если надо
Сделано три дела из четырёх. Убрано ли в сортире?
Естественно, если в определении из пяти пунктов 4 пункта в порядке, а один пункт не в порядке, то и всё определение не в порядке. Я думал, что любому человеку старше третьего класса школы это очевидно. Неужели ты такой тупой, что тебе и это надо объяснять? Я не верю, честное слово.
Но конечно, я не считаю Си функциональным языком. Я всего лишь с его помощью тестирую границы определения функциональности и пытаюсь показать, что это определение неадекватно сути вещей.
Не знаю, чего ты так прицепился к понятию «чистоты»? Ну, называется язык «чистым функциональным»? Что с того? По мне так вполне корректное название.
В haskell главное - ссылочная прозрачность. А неформально говорят: «вот это чистое значение, а это - уже вычисление, возможно в императивной монаде». И всем все понятно.
Хотя на самом деле, функции, возвращающие вычисления IO и выполняющие побочные эффекты, например, меняющие состояние или работающие с файлами, вполне сами формально могут быть чистыми. Потому что они возвращают эффект (действие) как значение (вычисление), а не исполняют сам эффект. Эффект исполняется уже рантайм-системой или библиотекой. Возвращаемый эффект же действительно зависит только от входных параметров и более ни отчего. Сколько раз ни вызови такую функцию, всегда получишь эквивалентый эффект (в виде вычисления). Однако, результат исполнения эффекта вполне может зависеть от окружающего мира, но это уже не важно.
Тут есть элемент косвенности, небольшой трюк, но именно этот трюк позволил сделать язык ленивым (через ссылочную прозрачность), ради чего во многом язык и задумывался. Это много позже уже haskell оказался отличным инструментом для практики (для тех, кто его освоил).
Ну, непривычно в начале. Потом все встает на свои места и кажется вполне логичным и единственно правильным.
В haskell главное - ссылочная прозрачность. «вот это чистое значение, а это - уже вычисление, возможно в императивной монаде».
Так нормально. Но тогда получается, что из термина «чисто функциональное» сделали рекламный слоган, не имеющий реального смысла, но якобы показывающий уникальность Хаскеля (я не говорю о том, есть она или нет, в чём она состоит и т.п., но данная реклама - ложь, поскольку произведена подмена понятия). А в жизни пользуются новой терминологией, построенной в отдалении от старой (а старую испоганили до полной неюзабельности). С какой стороны не подойди - секта и манипулирование сознанием.
Эффект исполняется уже рантайм-системой или библиотекой. Возвращаемый эффект же действительно зависит только от входных параметров и более ни отчего. Сколько раз ни вызови такую функцию, всегда получишь эквивалентый эффект (в виде вычисления). Однако, результат исполнения эффекта вполне может зависеть от окружающего мира, но это уже не важно.
Ты пошёл по следам Монка, наверное, таково ваше учение. Я не знаю Хаскель, чтобы провести анализ понятий, что понимается под словом «эффект», «вычисление» и «эквивалентный». Я только могу сказать, что «это уже не важно» - это из серии «ныне житейское оставим попечение» (из «Иже, иже, херувимы»). Т.е. я и это не могу понять. Того, что я выяснил раньше, вполне достаточно, чтобы судить о том, что был вполне нормальный термин чистоты, и его испоганили.
Ладно, вы все точно врёте и это очевидно, но вернёмся к этому вопросу, когда и если я дочитаю книжку про Хаскель.
Пока что сделаю небольшую ретроспективу эпической битвы:
- сначала была попытка свалить ответственность с языка на рантайм. Это просто смехотворно
- когда это не сработало, вы отступили от функциональной чистоты пустили в ход «ссылочную прозрачность». Ссылочная прозрачность имеет определение, опирающееся ещё на 2-3 других понятия, которые тоже где-то должны быть определены. Это принцип гидры: сруби одну голову - вырастут три. Сколько там голов в запасе? Я не Геракл, чтобы прорубаться к истине такими трудами.
Это похоже на веру православную: грядёт царствие небесное, но когда конкретно оно грядёт, было запрещено судить после 1666 года, когда оно очередной раз не грянуло (или как это? Не пригряло? В общем, не наступило).
Т.е. сколько бы времени не прошло, никогда нельзя опровергнуть веру православную. А вот Хрущёв сказал конкретно: следующее поколение советских людей будет жить при коммунизме. По факту неисполнения сего пророчества коммунизм потерял доверие и пал.
Так вот, объяснение одного непонятного понятия новым непонятным понятием является другим способом безконечно избегать разоблачения. Вместо оси времени используются уровни вложенности определений. Конечно, в данном случае дерево должно иметь корень (или ветви), и рано или поздно вывод на чистую воду неизбежен, если идти в этом направлении.
Хорошо то, что хаскеллисты бросили позиции, занятые на понятии «функциональная чистота» и расписались в том, что его испортили. Эту битву я выиграл. Выиграть же войну я не могу, т.к. не имею ресурсов разбираться сейчас во всех понятиях, на которые опирается ссылочная прозрачность. Если я начну о них судить, меня будет правильно обвинить в воинствующем невежестве. Поэтому я ограничусь установкой трофея на факте порчи понятия «функциональной чистоты».
Нужно заметить, что выбить признание о том, что понятие первоклассности не определено, мне так и не удалось. Вы частично признали, что с первоклассностью не всё в порядке, но белый флаг так и не выбросили, а взамен решили полечить меня от троллинга, тупежа и иных моих грехов. Т.е. я всё же дошёл до вашего чувствительного места, но додавить не смог.
Очень мало кому хватает мужества публично признать свою ошибку, кстати, так что я не удивлён этой неудаче.
Далее, мне кажется, я начинаю понимать, что вы имеете в виду.
Может быть, что есть какое-то другое понятие (не функциональная чистота), которое действительно содержательно и которое прихожане Хаскеля называют функциональной чистотой. Конечно, императивная программ ни к чёрту не может быть ленивой (или это будет плохая программа), но так скажем, при её преобразовании можно использовать ленивые элементы между императивными. Впрочем ,любой нормальный компилятор С++ делает то же самое без всякого теорката.
Если окажется вдруг, что в Хаскеле введена какая-то нотация, которая позволяет как-то удобно с этим работать, тогда вас можно частично амнистировать, но помнить о сектантской сути Хаскеля и разоблачать её нужно в любом случае.
Подождём до момента, когда и если я дочитаю книжку про Хаскель, и при случае вернёмся к этому вопросу.
P.S. прошу понять меня правильно, я ни на кого лично не нападаю. Есть некий «образ мысли прихожанина секты Хаскеля», я общаюсь с людьми, познавшими Хаскель, чтобы выявить этот образ мысли и атаковать его. Это может выглядеть и восприниматься как атака на личность, но это лишь атака на миф.
Я имел дело с различными сектами, которые влияют на жизнь человека более глубоко, чем Хаскель (и можно сказать, даже в некоторых из них некоторое время состоял). В целом понятно, что изучить образ мысли сектанта возможно, а вот поменять его - практически невозможно. Так что это не более, чем небольшой экскурс в психологию религии, не стоит думать, что я здесь реально пытаюсь чего-то достигнуть.
Хотя на самом-то деле, я конечно, пытаюсь что-то достигнуть, т.к. программисты - это люди, у которых разум должен перевешивать. Т.е. кажется, что если ты видишь у человека перекос (пользование некорректными понятиями, порочный круг в определениях и т.п.) то программисту достаточно на это указать и всё автоматически будет исправлено.
Но этого не происходит.
Мы наблюдаем более одной религии в программировании (религия статической и динамической типизации, религия ООП, религия лиспа, религия С++), в которой, очевидно, люди отчасти теряют способность здраво мыслить. Впрочем, то же происходит и в политике: интеллектуала и компьютерщика вполне можно развести на тот или иной «майдан». Или, скажем, теория Дарвина. Мне никогда и никому не удалось доказать, что она логически необоснована и построена точно как религия. Хотя если бы можно было заставить человека абстрагироваться от личного отношения и взглянуть на логическую схему построения доказательств, то необоснованность выглядела бы очевидной.
Наверное, возможность сочетания в одной голове строгого логического мышления, нужного для программирования, и мифов, достойно исследования психологов и социологов, но я ни тем, ни другим не являюсь, поэтому просто прошу не считать мои нападки нападками на вашу личность, вот и всё.
Извините, если кого-то обидел.
Также я не считаю религиозных людей ущербными. Религиозность - это часть природы человека и во мне она тоже есть. Поэтому, если я говорю о секте Хаскеля, я не пытаюсь этим никого унизить.
Мне эта секта была в своё время обидна тем, что отнимала внимание у моей секты CL, теперь меня она раздражает столь явным насилием над понятиями, но в целом она безвредна и я постараюсь преодолеть негативное к ней отношение. Наверняка в Хаскеле есть и какие-то полезные идеи.
Естественно, если в определении из пяти пунктов 4 пункта в порядке, а один пункт не в порядке, то и всё определение не в порядке.
И 5-й в порядке, просто сильно зависит от реализации: есть «самопознавание» (что за термин дурацкий, было приличное определение - забыл, склероз) или нет. Для JS достаточно получить тип «Function», для других языков - нет. Что не устраивает? Не понятно откуда ноги растут? Банально: получить «не идентифицированный объект» и определив, что это функция - вызвать. В JS и так контроль всех параметров лежит на самой функции.
Неужели ты такой тупой, что тебе и это надо объяснять?
Я уже ответил. Дальше спорить не буду - сам для себя решай. Если тебя устраивает порочный круг в определении, когда понятие определено через само себя, то это твоя проблема, не моя.
Проблема не очень большая, можно договориться по каждому языку, но тогда получается, что «функциональные языки - это те, которые люди договорились считать функциональными», т.е. некий ad hoc список. Для математики это более чем странно. С одной стороны, трудно постижимый теоркат с монадами, а с другой, в таких простых и ясных вещах не могут порядок навести. Т.е. это не я пытаюсь придумать свою терминологию, а реально существует дефект в общеиспользуемой терминологии.
Поскольку и в понятии функциональной чистоты тоже дефект, внесённый хаскелистами, и в использовании одного слова для двух ортогональных свойств, каждое из которых по отдельности имеет значительную ценность, тоже есть дефект, то в целом качество понятийного аппарата можно оценить как низкое.
А мне говорят: ты игнорируешь суть, устроил клоунаду, навязываешь свои понятия, троллишь, тупишь и т.п. Нет. Это я просто показал, что есть проблема в понятиях, и каждый пункт по отдельности кем-то из моих собеседников признан. В целом вы не признали, что терминология плохая, ну и не надо. Для себя это я и сам могу просуммировать, а вы можете продолжать жить в мире, где с этим понятием всё ок, если вас это устраивает.
Если тебя устраивает порочный круг в определении, когда понятие определено через само себя, то это твоя проблема, не моя.
Эта проблема кривого определения и твоего упрямства. Замени 5-й пункт на наличие интроспекции и расслабься.
Поскольку и в понятии функциональной чистоты тоже дефект, внесённый хаскелистами...
Это проблемы хаскеля. Во всех остальных языках - просто отсутствие «сайд-эффектов».
А мне говорят: ты игнорируешь суть, устроил клоунаду
Ну так оно так и есть :)
Это я просто показал, что есть проблема в понятиях
Да, «стройной математической» теории, отлитой в бетоне стандарта ISO нет, что не мешает пользоваться пусть и слегка размытыми понятиями большинству. Ты же, создаётся впечатление, на почве размытости понятий пытаешься отрицать и само «явление», и его «положительные эффекты».
Замени 5-й пункт на наличие интроспекции и расслабься.
Терминология - это то, о чём люди договариваются. Я с кем буду договариваться? Сам с собой? Здесь просто надо остановиться на том, что понятие недоопределено.
Ты же, создаётся впечатление, на почве размытости понятий пытаешься отрицать и само «явление», и его «положительные эффекты».
Отнюдь. Хотя есть такой социальный феномен: понятие недоопределено, поэтому его по-настоящему мало кто понимает, а вдали маячат страшные монады с теоркатом. Поэтому легче запугать простого PHP-кодера, снизить критичность отношения, раздуть хайп и втолкнуть в языки нечто новое, написать методички (ведь из-за кривизны понятия собственный мозг PHP-кодера не может быть включён - его заклинило ещё на этапе определения понятий). Функциональщина вовсю лезет в мейнстрим, и ещё неизвестно, какие слёзы будут лить разработчики, когда она войдёт в полную силу.
Может получиться то же, что получилось с ООП, когда из кривой понятийной базы выросла порочная практика и это в течение где-нибудь 20 лет наносило ущерб развитию программирования (и до сих пор ещё это не закончилось).
Проблемы Хаскеля - это проблемы всех. Clojure и вроде бы Rust из него что-то копируют. Настолько, что перед изучением Clojure советуют изучить Хаскель. Хаскель - это флагман ФП.
Это проблемы хаскеля. Во всех остальных языках - просто отсутствие «сайд-эффектов».
Да нет же никаких проблем! Как раз в haskell наглядно всем показали, что практически все функции, даже те, что создают побочные эффекты и оперируют изменяемым состоянием, можно эффективно определить как формально чистые. Уже неоднократно здесь расписывался механизм, и мною, и монком.
Это настолько простая идея, но почему-то в головах некоторых программистов никак не может ужиться, потому что отличается сильно от того, к чему они привыкли... Очень непривычно, действительно. Но это факт. Так делается. Так уже сделано!
А секрет очень простой. Не совершать самих действий, а возвращать соответствующую функцию, которая совершит потом эти действия. Функция же у нас элемент первого класса в языке. Почему бы и нет? Малюсенький простой такой логический шаг, но так трудно некоторым дается его понимание, что караул просто!
В результате все происходит так же, как в обычных языках. И мир во время меняется, и сетевые соединения обрабатываются.
Формально, во время связывания возвращаемого действия с текущим вычислением через монадическую связку (>>=). Синтаксический сахар в виде нотации do это делает очень изящно. Код внешне выглядит похожим на обычный код, как в тех же Си++.
Текущее вычисление должно исходить из специальной переменной main. Иначе вычислением не будет исполнено.
По факту, в обычных случаях компилятор убирает все лишние атрибуты, и код получается таким же по эффективности, как если бы мы писали на Си++, к примеру.
Особый случай, это когда мы возвращаем вычисление IO, но сразу не применяем. В таком случае оно применится там, где будет опять же включено в вычисление через монадическую связку.
Интересный момент заключается в том, что одно и тоже вычисление IO можно применять многократно. И каждый раз эффект будет исполняться заново.
А лучше прочитать книгу по haskell. Только до конца!
Строго говоря, не существует определения того, что такое «функциональный язык». Но есть договоренность считать таковым язык, который способствует написанию программ в функциональном стиле. Сразу замечу, что этот стиль не стоит противопоставлять императивному. Оба стиля могут сосуществовать в рамках одного кода.
Императивный стиль - это когда программа представляет собой пошаговое описание действий, которое нужно совершить.
Функциональный стиль - это когда мы смотрим на программу как на вычисление некоторой функции, которая может быть композицией других более простых функций. А композиция, чтобы быть предсказуемой, банально нуждается в том, чтобы количество побочных эффектов было ограничено.
Что касается clojure, то там безусловно стремятся к сокращению побочных эффектов по возможности, а также язык способствуют написанию программ в функциональном стиле. Поэтому язык clojure заслуженно считается функциональным. Напомню, формального определения не существует
тогда у вас любой процессор реализует функциональный язык, без всех этих теоретических изысков и фокусов с монадами. Без операций ввода/вывода на одной и той же программе - один и тот же результат.
Смысл утверждения был в том, что «интересные» концепции clojure взяты из Хаскеля, где они выражены более прямо, и что иногда, читая доку по Clojure без контекста Хаскеля сложно понять, о чём вообще идёт речь.
Пусть меня товарищ заигнорил и не может ответить, но я всё же прокомментирую:
В результате все происходит так же, как в обычных языках. И мир во время меняется, и сетевые соединения обрабатываются.
В обычных языках это тоже происходит: грязные функции - грязные, а чистые - чистые. Отличие только в том, что нет границы между ними (а в Oracle - есть).
Код внешне выглядит похожим на обычный код, как в тех же Си++.
В С++ тоже код внешне похож на код С++, более того, он и есть код на С++.
Текущее вычисление должно исходить из специальной переменной main. Иначе вычислением не будет исполнено.
В С++, если функция не вызвана из main прямо или косвенно, то она не будет исполнена. То же самое, без монад и теорката.
Особый случай, это когда мы возвращаем вычисление IO, но сразу не применяем. В таком случае оно применится там, где будет опять же включено в вычисление через монадическую связку.
Особый случай - это когда мы создаём функцию, но сразу её не вызываем. В таком случае она будет вычислена там, где она будет вызвана из других функций по потоку исполнения. То же самое, но без монадических связок.
Интересный момент заключается в том, что одно и тоже вычисление IO можно применять многократно. И каждый раз эффект будет исполняться заново.
Интересный момент заключается в том, что одну и ту же функцию можно вызвать из main несколько раз, например в цикле. И каждый раз побочный эффект будет исполняться заново.
Т.е. написано много слов, но никакого существенного отличия от императива не названо. То же самое, только с лишними сущностями.
А вот вопрос про невозможность мемоизации грязных вычислений (которым они принципиально отличаются от чистых) ни один из пользователей Хаскеля не ответил. Лучше было меня назвать клоуном, чем ответить на этот вопрос. Вопрос так и остаётся повисшим в воздухе.