LINUX.ORG.RU

Вышел 2-й выпуск журнала «Практика функционального программирования»

 , , ,


1

0

Вышел в свет второй выпуск журнала «Практика функционального программирования».

Центральная тема второго выпуска журнала — демонстрация применения функционального программирования в реальных, а не академических проектах.

Первые четыре статьи — Дмитрия Зуйкова, Дмитрия Астапова, Сергея Зефирова в соавторстве с Владиславом Балиным, и Алексея Отта — вытаскивают на поверхность «кухню» нескольких компаний. Статьи демонстрируют, что функциональные языки находят применение в промышленном программировании в самых разных нишах. Конечно, использование «нестандартных» языков накладывает на проекты некоторые сложно оценимые риски, и далеко не все из них рассмотрены в статьях. Но если статьи этого номера позволят развеять хоть часть сомнений, мифов и предрассудков и поднять дискуссию о применимости функциональных языков в промышленном программировании на новый уровень, мы будем считать свою задачу выполненной.

Статья Александра Самойловича рассматривает создание на языке Erlang игрушечного, но практичного проекта — рекурсивного многопоточного обходчика сайтов. К третьему выпуску журнала мы планируем подготовить ещё несколько статей про Erlang.

Завершающая статья Романа Душкина в большей степени ориентирована на теорию: она познакомит вас с концепцией алгебраических типов данных (АТД) в Haskell и других функциональных языках.

>>> Подробности

★★★★★

Проверено: maxcom ()
Последнее исправление: maxcom (всего исправлений: 1)
Ответ на: комментарий от anonymous

>Также, как и абсолютно функциональной программе.

Чегоооо!?

>Потому что на других не получится чисто функционально программировать.


"Чисто императивно" программировать вообще бы повесились. Вспомни ассемблер - вот это чисто императивный язык. И все изменения были в сторону убрирания императивности в языках более высокого уровня.

r ★★★★★
()
Ответ на: комментарий от anonymous

>ЗЫ. И этот человек защищает функциональное программирование - ты хоть узнай, что это такое, лол.

Это определение в очень простых словах для студентов первого курса - ака необразованных детей. Все равно что в ООП про классы говорить что классы это такая конструкция языка которая начинается словом class. В то время как папа Кей об этом думает что: "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things."

r ★★★★★
()
Ответ на: комментарий от r

> Это определение в очень простых словах для студентов первого курса - ака необразованных детей.

Суть оно вполне передает.

> "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things."

Не сильно отличается от святой троицы "Инкапсуляция, Полиморфизм и Наследование".

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Суть оно вполне передает.

Я не говорю что оно не передает сути. Просто над сутью пациент не хочет задумыватся. Когда ему говорят "оно об изменении состояния" - он говорит "нет это про наличие присваивания".

r ★★★★★
()
Ответ на: комментарий от tailgunner

>Не сильно отличается от святой троицы "Инкапсуляция, Полиморфизм и Наследование".

Ну последние 2 это не старый завет, а скорее адвентисты седьмого дня:)

r ★★★★★
()
Ответ на: комментарий от r

К стати учитывая что наследование уже почти предали анафеме - Кей может ходить и разводить руками на тему "это все равно не я придумал, это извратили мои идеи":)

r ★★★★★
()
Ответ на: комментарий от r

> Дык вот - ключевая фраза тут - "изменение состояния", а не "список шагов".

млять, я это уже 3 или 4 странички пытаюсь объяснить вам.

http://www.linux.org.ru/jump-message.jsp?msgid=4086949&cid=4090474

> Это ты придумал ей состояние. > Намек - изменение координат отлично описывается функциями - это даже

Я же говорю, у тебя все - сплошные гвозди^W функции.

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

Потому что там не реальные объекты, а абстрактные числа, у коих нет состояния (пойди отличи 42 от 42), и коих можно плодить в своем сознании миллионами.

> Нету никаких поинтеров и референсов в реальном мире. Кончай видеть мир через С++.

Млять, я тебе это и пытался объяснить, но ты - какой-то тугой. И к сведению - я ненавижу Си++ и яву.

> В первом случае это "новый объект" а во втором нет?

Зависит от ситуации, но в вообщем случае он там копируется.

> Твое заблуждение в том что ты думаешь что твоя интерпретация неких вещей как состояния - истинная.

Нет, не может быть способ моделировать алгоритм истинным или ложь, он может быть более естественным для человека, или менее естественным. Императивный способ - у нас есть состояния и мутабельность - как ты сам и сказал, естественнен для человека.

> Возьми в руки любой предмет находящийся рядом. Например карандаш. Это карандаш или деревяшка в состоянии обточенная с инжектнутым грифелем?

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

> Может ты еще и деструктивное присваивание деревяшке приведешь превратив ее в детский кубик? Слабо? Где начало и где конец?

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

> А яйца это точно яйца а кальций в состоянии круглая оболочка?

Это зависит, что для тебя важна, какая абстракция тебе важнее.

anonymous
()
Ответ на: комментарий от r

>>Также, как и абсолютно функциональной программе.

> Чегоооо!?

Ты не в курсе как в чисто-функциональном языке делать side-effects?

> "Чисто императивно" программировать вообще бы повесились. Вспомни ассемблер - вот это чисто императивный язык. И все изменения были в сторону убрирания императивности в языках более высокого уровня.

Да, но только не в сторону убирания императивности, а в сторону высокоуровневости.

anonymous
()
Ответ на: комментарий от r

> Это определение в очень простых словах для студентов первого курса - ака необразованных детей.

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

> В то время как папа Кей об этом думает что: "OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things."

Ну бывают разные модели ООП.

anonymous
()
Ответ на: комментарий от r

> К стати учитывая что наследование уже почти предали анафеме - Кей может ходить и разводить руками на тему "это все равно не я придумал, это извратили мои идеи":)

предали анафеме одновременное объявление данных класса и его методов. Если эти этапы разделить - получится очень даже неплохо. Наследование есть даже в том же хаскелле с помощью type classes, и вообще в хаскелле вполне себе ООП - не хватает только наследования данных (самого важного в ООП - на мой взгляд).

anonymous
()
Ответ на: комментарий от r

> Я не говорю что оно не передает сути. Просто над сутью пациент не хочет задумыватся. Когда ему говорят "оно об изменении состояния" - он говорит "нет это про наличие присваивания".

Пациент говорит про изменение состояния и identity, что тоже самое, что наличие разрушающего присваивания.

anonymous
()
Ответ на: комментарий от anonymous

>Потому что там не реальные объекты, а абстрактные числа, у коих нет состояния (пойди отличи 42 от 42), и коих можно плодить в своем сознании миллионами.

ОМГ!!! Ты почти дошел. Особенно что касается плождения в сознании. 42 на бумаге не отличается от яца в холодильнике.

>Млять, я тебе это и пытался объяснить, но ты - какой-то тугой.


Чего? Это ж ты гоовришь про референсы и измиенение состояния. К твоему сведенью деструктивное присваивание - это как раз про "референсы". Расскажи где оно в краденой яичнице.

>Зависит от ситуации, но в вообщем случае он там копируется.


Что значит "копируется"?

>. Императивный способ - у нас есть состояния и мутабельность - как ты сам и сказал, естественнен для человека.


Моделирование алгоритмов через мутабельность - неестественно. Неестественность проистекаев в том что декларативное описание - это дерево - то есть человек на каждом шаге знает для чего он это делает _глядя на дерево_. А в императивном описании - это линейный список императивов изменяющих глобальное состояние _и из взгляда_ невозможно сказать к чему все идет не дойдя до конца и не просчитав некое искуственное состояние памяти - вспомни ассемблер! Тебе кажется что ты знаешь только потому что в голове у тебя таки декларативное дерево которое императивно описывается - с конца, а не с корня. Потому тебе и надо эта искуственная память с состояниями - потому что если ты не сворачиаешь дерево в корень (где в каждом узле ясно для чего были данные из листьев и хранить их промежуточно нет необходимости), то ты сворачиваешь деревья с листьев не понимая на каждом шаге какие данные и для чего тебе понадобятся. Вот это и противоестественно - человек в здравом уме так не действует - он знает для чего он делает то или ное действие, потому и не надо ему промежуточная память для состояния - он знает какой очередной узел он хочет получить.

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


Давай любую модель с деструктивным присваиванием. Продолжим с яичницей.

>Если он изменился чуть-чуть, то это будет тот же объект, с измененным состоянием.


Что такое "чуть чуть"?

>И если происходит изменение этой вещи - это меняестя не весь мир, а только это вещь.


Какая вещь была твоя кровать до того как ты ее купил и как она изменилась? Руководствуясь твоей логикой деструктивного присванивания - вообще нельзя идентифицировать ни один обект - вся вселенная свелась к атомарному Xу который начал менять свои ствойства. Все вокруг - один объект "бытие"?:)

>Если происходит превращение одного объекта в другой - оно и в программировании точно также, один объект разрушается, появляется другой.


Объекты которые разрушаются и возникают - это концепции проистекающие из физической модели конечной памяти компьютера, минимальный размер которой 1 бит, в который единовременно можно уместить только 1 объект. И смысл эта концепция имеет _только_ в тех местах где ты работаешь с памятью именно так. В приведенном примере на хаскеле это не так. И потому нет никакого разрушения или создания объектов, и потому нет никакой разницы между heat x = x и heat Pat Cold = Pan Hot. Вся эта фигня про создание и деструкцию изза мозга съеденного именно этими языками с "указателями" и "референсами" и конечной моделью памяти с ручным управлением. Избавляйся.

r ★★★★★
()
Ответ на: комментарий от anonymous

>Ты не в курсе как в чисто-функциональном языке делать side-effects?

Это противоречие. Если это чистофункциональная программа - там нет сайд эффектов.

>Да, но только не в сторону убирания императивности, а в сторону высокоуровневости.


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

То что ты называешь "высокоуровневостью" и есть уход от императивности.

r ★★★★★
()
Ответ на: комментарий от r

> ОМГ!!! Ты почти дошел. Особенно что касается плождения в сознании. 42 на бумаге не отличается от яца в холодильнике.

Отличается, тем, что могу одновременно вычислять f1(42) и f2(42), и при этом я не могу одновременно варить и жарить одно и то же яйцо.

> Чего? Это ж ты гоовришь про референсы и измиенение состояния.

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

> Что значит "копируется"?

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

> К твоему сведенью деструктивное присваивание - это как раз про "референсы". Расскажи где оно в краденой яичнице.

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

> Что такое "чуть чуть"?

Чуть-чуть это в пределах одного класса абстракции.

> Какая вещь была твоя кровать до того как ты ее купил и как она изменилась?

А хер его знает, она была пиломатериалы и горстка болтов. Точнее даже ее не было, до тех пор, пока ее не сделали (собрали). Как только ее собрали - она попала в класс кроватей, также туда попало еще уйма других кроватей.

> Руководствуясь твоей логикой деструктивного присванивания - вообще нельзя идентифицировать ни один обект

Можно, и сделать это очень просто и интуитивно понятно - человек уже мыслит категориями и абстракциями классов. Причем в разных ситуациях объект - может быть суммой других объектов, может быть неделимой единицей, причем каждый обладают identity и mutability в рамках своей абстракции.

> - вся вселенная свелась к атомарному Xу который начал менять свои ствойства. Все вокруг - один объект "бытие"?:)

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

> Объекты которые разрушаются и возникают - это концепции проистекающие из физической модели конечной памяти компьютера,

это концепция мышления человека.

> минимальный размер которой 1 бит, в который единовременно можно уместить только 1 объект. И смысл эта концепция имеет _только_ в тех местах где ты работаешь с памятью именно так.

> В приведенном примере на хаскеле это не так. И потому нет никакого разрушения или создания объектов, и потому нет никакой разницы между heat x = x и heat Pat Cold = Pan Hot

А зачем тогда хаскелю GC :)? Да говорю же - запусти программу на хаскалле в машине с бесконечной памятью - и все равно там будет копироваться, причем не слабо. Ограниченность памяти тут не причем. (Еще разок - я понимаю, что такое фп - и какое оно из себя "абстрактное").

anonymous
()
Ответ на: комментарий от r

> Это противоречие. Если это чистофункциональная программа - там нет сайд эффектов.

Хаскелл pure-functional, там есть сайд эффеты, парадокс :). Вроде уже сошлись на том, что считать функциональным программированием.

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

Это высокоуровневость, а не функциональность. Избегание ненужного и автоматизация рутины - это достижение высокоуровневости, а не функциональности.

anonymous
()
Ответ на: комментарий от anonymous

> я не хочу, чтобы меня ограничивали в том, как я рассуждаю о проблеме,

отказ от функциональной парадигмы это само по себе очень большое ограничение

> и не загоняли меня в мир тесный мир функций, функторов и монад.

он не тесный

ugoday ★★★★★
()
Ответ на: комментарий от anonymous

> В функциональном программировании - все проще - там нет глобальных переменных, там не нужны мьютексы на разделяемые ресурсы, чтобы не дай бог не возникло взаимных блокировок или гонок, потому что там переменные не изменяются, потому, что там нет побочных эффектов

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

> В жизни все не так - выполнение процесса вора моей яичницы - она имеет побочный эффект - изменение ее состояния

Веришь-нет, но это тривиальным образом описывается в рамках ФП.

> Да, но императивная естественнее для человека.

Снова-здорова. :-( Для человека естественна декомпозиция задачи на подзадачи и синтез сложных алгоритмов из простых моделей поведения.

В рамках того-же примера с яишницей, повар, разбивая яйца, понимает зачем он это делает, как задача "разбить яйца" соотносится с обещей целью "сделать яишницу". Тогда как императивный повар должен тупо выполнять инструкции из рецепта в надежде, что в конце получится нечто съедобное. Грубо говоря, он не знает какое блюдо готовит до тех пор, пока не приготовит его окончательно и не попробует. Это фундаментально противоестественно для человека.

ugoday ★★★★★
()
Ответ на: комментарий от anonymous

>> Дело тут совсем не в мутабельности объектов. В том что основной целью шага алгоритма в императивном подходе является _создание сайд эффекта_. >Также, как и абсолютно функциональной программе.

Поясни.

ugoday ★★★★★
()
Ответ на: комментарий от anonymous

> Я же говорю, у тебя все - сплошные гвозди^W функции.

Гвозди это гвозди. А то, что их поведение удобно моделировать с помощью функций, совсем другой разговор.

Тебе бы не помешало чётко отделить в сознании _реальные_ вещи и их _представления_ в программе. Бо гвоздь в равной степени [не] является функцией, изменяемой структурой данных или имплементацией класса Гвозди, отнаследованного от класса ВсякиеМелкиеСтальныеШтуки.

> Потому что там не реальные объекты, а абстрактные числа, у коих нет состояния

А в твоей программе реальная яишница? о.О Тоесть можно вытащить дебаггером и сожрать? Чёрт, я кажется готов уверовать в императивную мощь.

ugoday ★★★★★
()
Ответ на: комментарий от anonymous

> не в сторону убирания императивности, а в сторону высокоуровневости.

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

ugoday ★★★★★
()
Ответ на: комментарий от anonymous

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

Это как, яичница знает, что её украл вор? Ты не замахаешься с такими зависимостями между объектами свои программы писать? Или приведи псевдокод, что ты имел в виду.

А насчёт отсутствия мутабельности - дык если мы пишем омлет = приготовить(яйца), то это означает, что у нас были яйца в прошлом, а сейчас стал омлет. Дык конечно состояние мира в прошлом - иммутабельно. Я бы на самом деле не отказался пожить в мире, где можно поменять что-то в прошлом - однако мы живем в другом. :)

pitekantrop ★★★
()
Ответ на: комментарий от ugoday

> отказ от функциональной парадигмы это само по себе очень большое ограничение

ограничивать только фп - вот это действительно ограничение.

anonymous
()
Ответ на: комментарий от anonymous

>Отличается, тем, что могу одновременно вычислять f1(42) и f2(42), и при этом я не могу одновременно варить и жарить одно и то же яйцо.

А зачем тебе жарить одно и тоже яйцо?

> я не мог не упомянуть референсы и изменение состояния, только потому что - это место, где они кардинально отличаются.


И это самое место которое не присутствует в реальности вообще ни в каком виде. Сколько у тебя ссылок на яйцо?:)

>Берется и копируется,


Тема копирования не раскрыта. Как проверить объект скопирован или нет? И какое это имеет значения в реальности где нет ссылок и созданий с деструкцией?

>ну дык я про эти самые рефересы и говорил в контексте императивщины,


То есть ты видишь что вся эта фигня искуственно проистекает из императивной модели и никакой человек в терминахх ссылок на яйца и деструктивных присваиваний яичницы не думает?

>Можно, и сделать это очень просто и интуитивно понятно


Человек интуитивно не мыслит состояниями и деструктивными присваиваниями.

>Нет, к такой модель скатывается как раз функциональное программирование.


Где?

>это концепция мышления человека.


Серьезно? Ну инстанциируй мне яйцо из класса яиц:)

>А зачем тогда хаскелю GC :)?


А ты этим в ручную рулишь? Так какая тебе разница как оно работает андеркавер? Там фон-неймановский императивный компьютер с конечной памятью.

>Ограниченность памяти тут не причем.


Еще как причем. В неограниченной памяти нет проблем с освобождением ресурсов - и как следствие с "удалением объектов".

>Еще разок - я понимаю, что такое фп - и какое оно из себя "абстрактное"


"Абстрактное" - это то что ты в другой мессаге назвал "высокоуровневым". Зачем мне мслить в терминах создания и удаления обектов или ссылок в пасяти? Что это мне даст в общем случае?

Наш мозг съеден программой обучения которая основана на императивном подходе - потому нам и кажется что ссылки, new/delete и прочая фигня естественны. А они нефига неестественны - это гавно в котором мы вынуждены вариться потому что с этим уж работаем. И если бы его не было - было бы лучше.

r ★★★★★
()
Ответ на: комментарий от anonymous

>Хаскелл pure-functional, там есть сайд эффеты, парадокс :)

Нет - парадокс это только потому что ты почему-то считаешь монады - не частью функционального программирования.

>Это высокоуровневость, а не функциональность.


Это избавление от императивности.

>Избегание ненужного и автоматизация рутины - это достижение высокоуровневости, а не функциональности.


"высокоуровневость" это бузтермин типа 3g. Ничего общего с реальностью - но удобно писать в рекламных проспектах. Зачем в С функции? Потому что они удобное императивных блоков кода меняющих внешнюю память. А почему это удобно доказывается в том числе на чистой математике про чистые функции.

r ★★★★★
()
Ответ на: комментарий от pitekantrop

> А насчёт отсутствия мутабельности - дык если мы пишем омлет = приготовить(яйца), то это означает, что у нас были яйца в прошлом, а сейчас стал омлет. Дык конечно состояние мира в прошлом - иммутабельно

Доо. В той записи, которую ты привел, в настоящем будут существовать и омлет, и _неповрежденные_ (иммутабельные, да) яйца, из которых он приготовлен. Более того, из одних и тех же яиц ты сможешь приготовить сколько угодно омлетов %)

Чорт, вот не хотел же лезть в эту дурацкую кулинарную дискуссию :/

tailgunner ★★★★★
()
Ответ на: комментарий от pitekantrop

>ык конечно состояние мира в прошлом - иммутабельно.

Ну вот! Я концепцию времени приберегал для особого случая, а ты все расказал:))

r ★★★★★
()
Ответ на: комментарий от anonymous

>ограничивать только фп - вот это действительно ограничение.

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

r ★★★★★
()
Ответ на: комментарий от tailgunner

>В той записи, которую ты привел, в настоящем будут существовать и омлет, и _неповрежденные_ (иммутабельные, да) яйца, из которых он приготовлен.

Только там где есть понятие ссылок. Посмотри на мою хаскельную яишницу. Например в тот же нагрев сковороды:

heat Pan Cold = Pan Hot

Как у тебя возникнет две сковороды без введения понятия ссылок?

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

r ★★★★★
()
Ответ на: комментарий от r

>голове никаких ссылок нет - люди такими категориями не мыслят.

К стати тут можно отметить что программистов даже жестко тренируют мыслить такими категориям натаскивая на разных двунаправленных списках и прочих бинарных деревьях - и требуется некоторое время чтобы концепция ссылки и "динамических структур в памяти" угнездилась в голове человека.

r ★★★★★
()
Ответ на: комментарий от pitekantrop

> Это как, яичница знает, что её украл вор?

Что значит знает? Как яичница может что-то знать?

> Ты не замахаешься с такими зависимостями между объектами свои программы писать?

Нет.

> Или приведи псевдокод, что ты имел в виду.

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

> А насчёт отсутствия мутабельности - дык если мы пишем омлет = приготовить(яйца), то это означает, что у нас были яйца в прошлом, а сейчас стал омлет.

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

> Дык конечно состояние мира в прошлом - иммутабельно. Я бы на самом деле не отказался пожить в мире, где можно поменять что-то в прошлом - однако мы живем в другом. :)

У реальных предметов есть история, у функциональных - нет.

anonymous
()
Ответ на: комментарий от r

> Например в тот же нагрев сковороды:

> heat Pan Cold = Pan Hot

> Как у тебя возникнет две сковороды без введения понятия ссылок?

Я в сковордках нишарю, в хаскеле - тоже :) Поэтому и сказал про "ту запись".

> но возвращаясь к теме дискуссии - мышлении человека

"Сам топи урановые ломы в ртути" (с) Ну его нафиг, это мышление.

tailgunner ★★★★★
()
Ответ на: комментарий от ugoday

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

Еще разок - инкапсуляция, полиморфизм, декомпозиция программы на части - это все свойственно _только_ функциональщине, неужели?

anonymous
()
Ответ на: комментарий от ugoday

> Тебе бы не помешало чётко отделить в сознании _реальные_ вещи и их _представления_ в программе. Бо гвоздь в равной степени [не] является функцией, изменяемой структурой данных или имплементацией класса Гвозди, отнаследованного от класса ВсякиеМелкиеСтальныеШтуки.

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

> А в твоей программе реальная яишница? о.О Тоесть можно вытащить дебаггером и сожрать?

Нет, но в моей программе можно одно "яйцо" (переменную, объект) от другого отличить благодаря identity, т.е. ведут они себя более естественно для человека, чем функциональные.

anonymous
()
Ответ на: комментарий от ugoday

> Поясни.

Prelude> putStr "hello\n" hello

Вывод на экран - это побочный эффект?

Вообще говоря, в хаскелле - нет побочных эффектов, но они описываются (реализуются, заворачиваются) в монады.

anonymous
()
Ответ на: комментарий от ugoday

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

Это был один из примеров, где фп помогает. Вы кстати, определитесь там есть побочные эффекты или нет :)

> Веришь-нет, но это тривиальным образом описывается в рамках ФП.

Веришь-нет, но это тривиальным образом описывается не только в рамках ФП.

> Снова-здорова. :-( Для человека естественна декомпозиция задачи на подзадачи и синтез сложных алгоритмов из простых моделей поведения.

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

> В рамках того-же примера с яишницей, повар, разбивая яйца, понимает зачем он это делает, как задача "разбить яйца" соотносится с обещей целью "сделать яишницу". Тогда как императивный повар должен тупо выполнять инструкции из рецепта в надежде, что в конце получится нечто съедобное. Грубо говоря, он не знает какое блюдо готовит до тех пор, пока не приготовит его окончательно и не попробует. Это фундаментально противоестественно для человека.

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

anonymous
()
Ответ на: комментарий от tailgunner

>Я в сковордках нишарю, в хаскеле - тоже :) Поэтому и сказал про "ту запись"

Ну это простой паттерн матчинг,

Вот к стати тоже интересный пример:

z = sqrt(sqr(x) + sqr(y))

Что это такое императивно "по программистски"?

Императивно это надо шаги:
x2 = sqr(x)
y2 = sqr(y)
s = x2 + y2
res = sqrt(s)


А еще можно вспомнить что это теорема пифагора. А потом вспомнить алгебру и обнаружить интересные свойства вроде преобразования в

z^2 = x^2 + y^2

В чем мой поинт - что даже рассматривать как _последовательность_ эту нотацию мы начали только когда нам мозг превратили в програмистский - детям в школе в голову не придет это так делать - зато они в курсе про то что если возвести в квадрат обе части урванения - его истинность не изменится. То есть они рассматривают данную запись как уравнение, то есть _декларативно_.

Потому например вот такая бодяга с производной в функциональном языке в качестве примера просится легко: http://ocaml.spb.ru/chapter01.html#id2251705

Потому в FP _естественно_ есть разная фигня типа map, fold и прочие штуки. И они были у нас начиная со школы.

А в императивном в голову не придет. Потому разные лямбды и функции как first class object вон в 21 веке только рождаются в "распротстраненных" языках.

То есть в школе у нас это еще было, а на первом курсе паскаль у нас это все отобрал, подсунув нам вместо этого сомнительную шнягу x := x + 1 с которым ничего сделать нельзя.

ААААА. Нам промыли мозги!!!

r ★★★★★
()
Ответ на: комментарий от anonymous

>декомпозиция программы на части - это все свойственно _только_ функциональщине, неужели?

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

r ★★★★★
()
Ответ на: комментарий от anonymous

> Что значит знает? Как яичница может что-то знать?

У объекта-яичницы есть ссылка на вора?

Я просил привести код, потому что не понял, где ты тут увидел необходимость в мутабельных объектах:

> Для меня - это просто "объект", предмет, называйте как хотите, который у меня могут, к примеру украсть, и тогда я останусь без еды, в отличие от функционального подхода, где украсть нельзя, потому что ничего нельзя изменить - все же иммутабельно, - вор должен был получить чуть-чуть измененную копию моей яичницы, ее - так сказать значение, а не саму ее.

> Как раз в функциональных программах стараются от понятия времени уйти.

Можно поподробнее? Никогда о таком не слышал. Кстати, ты слышал о functional reactive programming?

> У реальных предметов есть история, у функциональных - нет.

А у объектно-ориентированных есть? И вообще, ты это к чему сказал?

Йопт, я сейчас моск сломаю, пытаясь отследить полёт твоей мысли.

pitekantrop ★★★
()
Ответ на: комментарий от tailgunner

>> А насчёт отсутствия мутабельности - дык если мы пишем омлет = приготовить(яйца), то это означает, что у нас были яйца в прошлом, а сейчас стал омлет. Дык конечно состояние мира в прошлом - иммутабельно

> Доо. В той записи, которую ты привел, в настоящем будут существовать и омлет, и _неповрежденные_ (иммутабельные, да) яйца, из которых он приготовлен.

Ты хочешь, чтобы яйца исчезали из области видимости? Есть в каком-то функциональном языке и такая хрень. Там на этом принципе I/O работает: типа использовал внешний мир - вот тебе новый, а старый уже исчез.

> Более того, из одних и тех же яиц ты сможешь приготовить сколько угодно омлетов %)

Смысл ещё раз готовить? Это будет тот же самый омлет. :)

pitekantrop ★★★
()
Ответ на: комментарий от anonymous

> Я могу перекрасить кровать - и для меня это будет все та же кровать, просто изменившая свое состояние.

Я тоже могу - точно так же, как нагрел сковородку с помощью монады State.

> в моей программе можно одно "яйцо" (переменную, объект) от другого отличить благодаря identity, т.е. ведут они себя более естественно для человека, чем функциональные

ФП запрещает ввести id?

pitekantrop ★★★
()
Ответ на: комментарий от pitekantrop

> Ты хочешь, чтобы яйца исчезали из области видимости?

Я хочу, чтобы они перешли в состояние "разбиты" :)

>> Более того, из одних и тех же яиц ты сможешь приготовить сколько угодно омлетов %)

> Смысл ещё раз готовить? Это будет тот же самый омлет. :)

Неизвестно, что менее логично - приготовить несколько раз один омлет, или раз за разом готовить омлеты из одних и тех же яиц %)

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Я хочу, чтобы они перешли в состояние "разбиты" :)

А зачем ты при этом хочешь чтобы это был один объект с двумя состояниями? Ты можешь это откатить? Ты представь какой ужас с точки зрения валижной инвариантности - уже три приведенных состояния (целые, разбиты, пожарены) - это просто немеряно надо контрактов энкапсулировать чтобы проконтролировать валидность транзишена этих объектов. Что жаренные не могут быть неразбитыми, или стать обратно целыми. Это ж целый жизненный цикл - немеряно кода.

А теперь представь что объект не меняет мутабельый стейт - а переходит в новый объект. То есть то что ты называешь сменой стейта - на самом деле транзишен данных. В том примере на хаскеле к стати это и описано - причем очень коротко и 100% инвариантов. Функция broke абсолютно однозначно разбивает яйца если они уже не были разбитыми. И с помощью того набора функций абсолютно невозможно зажарить неразбитые яйца или сделать это на холодной сковороде или собрать яйца обратно из яишницы.

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



r ★★★★★
()
Ответ на: комментарий от r

>>Я хочу, чтобы они перешли в состояние "разбиты" :)

>А зачем ты при этом хочешь чтобы это был один объект с двумя состояниями?

Потому что Real World (tm) так работает.

> три приведенных состояния (целые, разбиты, пожарены) - это просто немеряно надо контрактов энкапсулировать чтобы проконтролировать валидность транзишена этих объектов.

> А теперь представь что объект не меняет мутабельый стейт - а переходит в новый объект. То есть то что ты называешь сменой стейта - на самом деле транзишен данных.

Да никакой разницы. Переходы между состояниями отражают реальность. Никакие ФП-трюки не могут ее кардинально упростить. Можно замести мусор по диван, а можно - под ковер. Но мусор всё равно останется.

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

Статическая типизация и выразительные системы типов рулят, кто же спорит.

> Ты только представь какие километры кода нужны будут в императивном объекте с состояниями

Способов программирования конечных автоматов за 50 лет придумано немало :)

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

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

>Потому что Real World (tm) так работает.

Где?

Берем классический объект на императивном языке с состоянием

class Egg {
state: {raw | broken | fryed} = raw
}

Чем он характеризуется? Тем что этот можно присваивать как попало и когда попало.

Раскажи мне как ты в real world (tm) переведешь яйцо из сосяния разбитое в состояние целое? Или разжаришь обратно?

RW(tm) работает не так.

>Переходы между состояниями отражают реальность.


Правильно отражают реальность именно _переходы_. А с состояниями непонятно даже откуда собственно начать. В общем случае состояние объекта _невозвращаемо_ (благодаря такой направленной составляющей RW(tm) aka континуум как _время_) У меня в руках скорлупа. С этим уже ничего не сделаешь. Всякие измышления про "состояние яйца" - это именно _модель_ базирующаяся на _теоретической_ истории. Мир обратно не откатывается. Объекты которые можно переводить в одни и теже состояния сколько угодно - подмножество aka частный случай всего множества объектов реального мира (tm). Тому кто осилит сделать его общим дадут нобеля за путешествия во времени, но ему уже будет плевать потому что он станет бессмертным:)

>Статическая типизация и выразительные системы типов рулят, кто же спорит.


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

>20 лет назад примерно такой хайп стоял вокруг ООП.


"И теперь они везде" (C)....:)

r ★★★★★
()
Ответ на: комментарий от r

> Чем он характеризуется? Тем что этот можно присваивать как попало и когда попало.

> Раскажи мне как ты в real world (tm) переведешь яйцо из сосяния разбитое в состояние целое? Или разжаришь обратно?

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

unfry e@(Eggs Fryed x) = Eggs Raw x

и потом ее впихнуть куда-нибудь, и заработает все не так, как в real world - просто потому что смоделировали ситуацию неправильно.

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

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

anonymous
()
Ответ на: комментарий от r

> Ты только представь какие километры кода нужны будут в императивном объекте с состояниями которые будут запрещать яйцам опять собираться из яичницы и т.д. и какие километры условий надо будет чтобы остальные функции не принимали яиц не в том состоянии.

Да блин, может яйцо оказаться не в том состоянии, совершенно спокойно (см предыдущий ответ),- и проверки все-равно нужны.

anonymous
()
Ответ на: комментарий от pitekantrop

> ФП запрещает ввести id?

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

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.