LINUX.ORG.RU

Почему ООП стало более популярным и соответствующие языки и технологии программирования чем то же ФП?

 ,


2

4

Заранее прошу прощения за то, что не в Talks, а сюда. Так получается, что теперь в Talks просто так постить нельзя, нужна некая карма и я должен «страдать» (Почему я не могу писать в раздел Talks? (комментарий)). Я в упор не помню данные своего старого аккаунта. Зарабатывать карму здесь и сейчас у меня нет ни времени, ни возможности, ни необходимости. Почему сюда, а не на другие форумы? Потому что считаю, что здесь обитают люди, которые смогут ответить на вопросы ниже и, возможно, даже, которые застали те самые времена (если конечно те самые люди ещё здесь).

Всем доброго времени суток! Не срача ради, а понимания для. Хочется понять историчность и почему так произошло. Понятно, что сейчас уже стали внедрять функциональные фичи много куда (в те же Java, C++, C# и т.д.). Стало появляться много функциональных языков (в том числе совсем новых). Но почему спустя столько времени? Почему спрашиваю:
- Functional programming has its origins in lambda calculus, a formal system developed in the 1930s (!!!) to investigate computability, the Entscheidungsproblem, function definition, function application, and recursion. Many functional programming languages can be viewed as elaborations on the lambda calculus (отсюда: https://en.m.wikipedia.org/wiki/Functional_programming);
- Lisp появился ажно в 1958 году;
- после лиспа ещё была целая куча функциональных языков (APL, IPL, ML, Miranda, Erlang, etc.);
- C++ в 1985;
- Haskell в 1990;
- Java в 1995;

Сама идея ООП (и то я так понял весьма размытая, каждый понимал (и, кстати, по-моему до сих пор понимает) по-своему) вроде как витала со времени создания самого лиспа, но до конкретных реализаций она добралась ближе к концу 80-х - начала 90-х годов.
(поправьте меня, если не прав)
И это ещё при всём при том, что ФП имеет под собой весьма конкретный математический базис (чего я, пожалуй, не могу сказать про ООП).
Я так понял, что благодаря таким крупным компаниям как Microsoft, Oracle...
Но почему они так сильно повлияли на развитие этих технологий и как именно они это сделали я, честно говоря, не совсем понимаю.
Ок, ладно, тогда железо было не такое как сейчас, памяти было маловато для нормального существования функциональных языков на x86 платформе.
Но ведь была же та же, например, Symbolics, которая вроде бы весьма активно продавала лисп-машины?
Ок, Symbolics развалилась благодаря неблагоприятному стечению обстоятельств и «эффективным» манагерам, но их наработки оказались никому не нужны что ли?
И опять-таки, когда нужное железо появилось почему выбор этих и других крупных компаний пал именно на эти языки?
Почему не на функциональные языки?
Потому что в то время функциональные языки в основном использовались сугубо в академической среде или как?
Или если перефразировать всё вышесказанное словами моего коллеги: «если всё так круто (про ФП), то почему оно ещё не захватило рынок?»

ФП имеет под собой весьма конкретный математический базис

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

buddhist ★★★★★
()

Столько бла-бла в ОП не по делу, а вот возьми и представь что-то типа Qt с его сотнями классов и тысячами свойств и методов в функциональном стиле

goingUp ★★★★★
()

И это ещё при всём при том, что ФП имеет под собой весьма конкретный математический базис (чего я, пожалуй, не могу сказать про ООП).

Если ты не можешь сказать, это абсолютно не значит, что под ООП нет математического базиса.

В самом заголовке содержится противопоставление ООП и ФП, что является глупостью. ООФП — вполне нормальное и закономерное явление.

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

самые практичные ништяки из ФП уже повытягивали

это те что

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

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

В интерфейсах с оопщиной проще всякие штучки-дрючки рисовать, наследуя их свойства от подобных.

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

byko3y ★★★★
()
Ответ на: комментарий от quantum-troll

вменяемый полиморфизм (с классами типов) появился в ФП довольно поздно

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

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

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

Никто не обязывает в ООП стиле писать с кучей внутренних переменных и изменчивых зависимостей. Как правильно заметил Вирт, основное достижение ФП - это вложенные структуры и функции без побочных эффектов (строго локальные данные). Но как бы при чем тут функции вообще? Этими инструментами можно пользоваться и в C.

byko3y ★★★★
()

если всё так круто (про ФП), то почему оно ещё не захватило рынок?

Это всё религиозное. Рынок тут не при чём.

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

редко встречаются задачи, где действительно есть смысл использовать ООП

как способ организации кода вполне. И на Си невозможно написать что-либо больше 5000 строк не прибегая к уподабливанию ООП. По крайней мере мне так видится

pihter ★★★★★
()
Ответ на: комментарий от quantum-troll

Чем объекты без наследования принципиально отличаются от структуры и функций в модуле? Кроме синтаксиса.

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

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

Этими инструментами можно пользоваться и в C.

Так зачем считать его критерием ФП?

Вообще, есть вещи которые определяют стиль программирования.

ООП: наследование, можно сделать класс, который «как Х» (все методы совпадают и везде можно использовать вместо X), но метод Y делает совсем другое. В классическом ООП ещё можно указать обработчик несуществующего метода.

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

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

но программируя модули с сокрытыми статиками, публичными структурами и функциями для работы с этими структурами

Суть ООП в статиках? Ведь структуры данных и функции для работы с ними — необходимое условие для любой информационной системы.

А (defun incrementor (n) (lambda () (setf n (+ n 1)) n)) — это тоже ООП? Ведь n для возвращаемой функции играет роль сокрытого статика.

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

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

А в чём проблема? Haskell hackage не подойдёт? Включая http://hackage.haskell.org/package/qtah-qt5

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

но программируя модули с сокрытыми статиками, публичными структурами и функциями для работы с этими структурами

Суть ООП в статиках? Ведь структуры данных и функции для работы с ними — необходимое условие для любой информационной системы.

В статиках (которые в отдельных модулях) — сокрытие, одна из черт ООП, да

Ведь структуры данных и функции для работы с ними — необходимое условие для любой информационной системы.

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

Я к тому что выступать против ООП со стороны сишников, которые сами же и пишут опираясь на принципы ООП (может и невольно) — как минимум — непоследовательно.

// весь этот бред не я придумал, это тов. Страуструп написал в своей нетленке

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

А (defun incrementor (n) (lambda () (setf n (+ n 1)) n)) — это тоже ООП? Ведь n для возвращаемой функции играет роль сокрытого статика.

а вот тут ЯННП, молод еще, исправлюсь )

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

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

А здесь написано, что ФП:

Как правильно заметил Вирт, основное достижение ФП - это вложенные структуры и ... строго локальные данные.

Вложенные структуры и локальные данные — это твои статики и есть.

а вот тут ЯННП

https://ru.wikipedia.org/wiki/Замыкание_(программирование)

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

И на Си невозможно написать что-либо больше 5000 строк не прибегая к уподабливанию ООП. По крайней мере мне так видится

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

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

Как правильно заметил Вирт, основное достижение ФП - это вложенные структуры и ... строго локальные данные.

Вложенные структуры и локальные данные — это твои статики и есть.

и какое же это достижение ФП — если это статики и есть? Оно ж было во времена динозавров (хотя может оно и из ФП пришло, но, чисто логически, жизни до Си не было)

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

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

Да, он реализует то самое первоистоковое ООП, о котором говорил Алан Кей, и которого нет в C++.

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

А (defun incrementor (n) (lambda () (setf n (+ n 1)) n)) — это тоже ООП? Ведь n для возвращаемой функции играет роль сокрытого статика.

а вот тут ЯННП, молод еще, исправлюсь )

Это функция incrementator, которая возвращает замыкание по локальной переменной n. Замыкание при вызове увеличивает значение n на единицу и возвращает значение n. Детали реализации скрыты, пользователь функции incrementor и ее результата-замыкания не обязан знать устройство этих функций.

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

А здесь написано, что ФП:

Как правильно заметил Вирт, основное достижение ФП - это вложенные структуры и ... строго локальные данные.

Вложенные структуры и локальные данные — это твои статики и есть.

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

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

И на Си невозможно написать что-либо больше 5000 строк не прибегая к уподабливанию ООП. По крайней мере мне так видится

Пардон, по-твоему структура данных с указателями на функции - это прям-таки «уподабливание ООП»?

не-не, не так. Есть хидер в котором структура данных, например чертика в игре. К нему есть сишный файл с набором прикладных функций — повернуть чертика, переместить чертика, отрисовать чертика. Каждая функция явно принимает указатель на структуру данных про конкретного чертика. Внутри исходника оно реализованно черноящиково(через статики) и наружу мы видим только описание структуры данных и набор функций для работы с ней. Наследование и полиморфизм тут на уровне исходных файлов кода: скопировал чертик.h и четрик.c в красный_чертик.h и красный_чертик.c после чего что нужно добавил, что нужно изменил, остальное оставил.

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

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

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

Да, он реализует то самое первоистоковое ООП, о котором говорил Алан Кей, и которого нет в C++.

я обо том же, именно первоистоковое, но-таки ООП

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

и какое же это достижение ФП — если это статики и есть? Оно ж было во времена динозавров (хотя может оно и из ФП пришло, но, чисто логически, жизни до Си не было)

Вот поэтому я и говорю, что считать статики и даже указатели на функции признаком ООП или ФП, слишком притянуто.

Действительный признак ООП: «тип А можно использовать везде вместо типа Б», Действительный признак ФП: возможность написать функцию comose(f,h) такую, что compose(f,h)(x) == f(h(x)).

К слову, во времена Си и ООП и ФП уже давно было и даже в Си/Юникс оба подхода использовались. «Всё есть файл» — ООП. cat | grep | sort | uniq — ФП.

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

хотя может оно и из ФП пришло, но, чисто логически, жизни до Си не было

https://en.wikipedia.org/wiki/History_of_programming_languages#First_programm...
Ты же понимаешь, что как минимум 8 ныне используемых высокоуровневых языков было создано до начала жизни? Это фортран, лисп, кобол, RPG, бейсик, PL/I, мампс, и паскаль - в порядке их появления.

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

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

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

Наследование и полиморфизм тут на уровне исходных файлов кода: скопировал чертик.h и четрик.c в красный_чертик.h и красный_чертик.c после чего что нужно добавил, что нужно изменил, остальное оставил.

Это уже «наследование на уровне фантазий». Можно это скатить до «наследование - это когда просишь коллегу написать вспомогательную функцию».

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

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

Да, он реализует то самое первоистоковое ООП, о котором говорил Алан Кей, и которого нет в C++.

я обо том же, именно первоистоковое, но-таки ООП

В первоистоковом ООП нет инкапсуляции, наследования, и полиморфизма.

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

Действительный признак ООП: «тип А можно использовать везде вместо типа Б», Действительный признак ФП: возможность написать функцию comose(f,h) такую, что compose(f,h)(x) == f(h(x)).

Нечего тут выдумывать:
https://ru.wikipedia.org/wiki/Функциональное_программирование
«Функциона́льное программи́рование — раздел дискретной математики и парадигма программирования, в которой процесс вычисления трактуется как вычисление значений функций в математическом понимании последних (в отличие от функций как подпрограмм в процедурном программировании).»

cat | grep | sort | uniq — ФП.

Да, это ФП, кстати, если не считать cat с побочками.

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

В первоистоковом ООП нет инкапсуляции, наследования, и полиморфизма.

вои ИМЕННО об этом я и надрываюсь всю дорогу. Это тоже ООП. Но, как и в 80% остальных споров, все скатилось к различному пониманию термина.

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

Это уже «наследование на уровне фантазий».

к Страуструпу с этими претензиями, это он мне в ухи налил )

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

Это уже «наследование на уровне фантазий».

к Страуструпу с этими претензиями, это он мне в ухи налил

Я тебе скажу, что в процедурных языках вместо наследований применяют такой прием, как сверхструктура - структура, содержащая избыточные данные, которые никогда не будут использоваться все одновременно. В зависимости от вызываемых функций поля будут иметь разные значения и в итоге выдавать разные результаты. Оно же в ООП известно как https://ru.wikipedia.org/wiki/Божественный_объект
Здесь нет модульности и связи через сообщения, здесь нет инкапсуляции, нет наследования, нет полиморфизма. Я сам периодически так пишу - это замечательный паттерн при разумном использовании, он дает потрясающе читаемый код, если вовремя остановиться, весь связанный код находится в одном месте, все возможные состояние просматриваются в простом текстовом редакторе. И при этом некоторые недалекие люди однозначно клеймят это антипаттерном.

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

byko3y ★★★★
()

ООП это крутейшая вещь, ФП тоже совсем не плох

anonymous
()

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

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

интересное замечание, но непонятное

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

процесс вычисления трактуется как вычисление значений функций в математическом понимании последних

В этом смысле функциональный любой язык программирования, где есть функции, а не подпрограммы. И неясно, чем Лисп более функциональный чем Си.

monk ★★★★★
()

Потому, что понятие слишком общее и его каждый трактует на свой лад.
К несчастью образцом для ООП являются классы C++.

anonymous
()

Сама идея ООП (и то я так понял весьма размытая, каждый понимал (и, кстати, по-моему до сих пор понимает) по-своему) вроде как витала со времени создания самого лиспа, но до конкретных реализаций она добралась ближе к концу 80-х - начала 90-х годов. (поправьте меня, если не прав)

Вы не правы. Simula 67 со всеми необходимыми атрибутами статически-типизированного ОО-языка появилась в 1967-ом году.

Динамически-типизированный Smalltalk – это середина-конец 1970-х (смотря какой диалект Smalltalk-а брать за точку отсчета).

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

лямбды (не тот смех, что в C++)

Что именно плохо в реализации С++-лямбд? В каком языке можно посмотреть на правильную реализацию?

Маленькие вложенные функции - это всегда удобно, многие популярные языки переняли эту фичу. Это давно было в паскале, пусть и функции приходится давать название, что соответствует духу языка. Нет никакой причины не делать это в том же Си, хоть в нем до сих пор этой фичи нет. В C++ лямбды-вложенные функции сделаны через создание объекта, что, хоть и уродливо, но вполне прокатывает.

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

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

Есть нотация функции с неявным получением доступа ко внешнему контексту (многие ФП и раст), есть нотация функции с явным получением доступа ко внешнему контексту (вариант с local/nonlocal в питоне), и есть нотация объекта-замыкания с явной передачей контекста параметром (php, C++).
Первый вариант, неявное указание, является самым удобным при условии, что запрещено наличие переменных с одинаковым именем в нескольких контекстах. Именно по этой причине в питоне сделали возможность использовать второй вариант, local/nonlocal, для исключения случайного пересечения имен.
Самый убогий - третий вариант, поскольку, по сути, является явной передачей параметра, а никак не использованием внешнего контекста. А поскольку есть явная передача значений внешней функцией в виде аргументов с тем же именем внутренней функции, то это уже и не замыкание вовсе.

Второй вопрос: можно ли вернуть замыкание из внешней функции? Я отвечаю однозначно: если замыкание не возвращаемо из внешней функции, то это не замыкание, а вложенная функция с тем же контекстом. То есть, это критерий определения, а не удоства пользования.

Третий вопрос: видит ли замыкание изменения внешнего контекста после создания замыкания? Я пытался как-то втирать о том, что замыкание должно, а что не должно делать в этом плане, но на самом деле важна лишь ожидаемость поведения. В чистом ФП, естественно, изменений не должно быть. В расте с передачей по ссылке измеения должны быть видны, правда, видны они будут уже не в замыкании, а во вложенной функции. Хуже всего - когда внешний контекст внезапно появляется после создания замыкания, или когда объект из внешнего контекста оказывается уничтоженным и дает неопределенное поведение, аки C++.

Четвертый вопрос: сохраняются ли изменения захваченной переменной с каждым последующим вызовом замыкания? Раст говорит «да», лисп позволяет оба варианта, чистые функциональные языки не допускают изменения значений. Я много уделял внимания этой особенности, но в конечном счете для кодера эта особенность малозначительна и обычно соответствует политике работы с локальными переменными языка, потому я признаю этот вопрос неважным.

Давайте же пропустим замыкания в языках через эти три критерия:

- Rust: 1. Неявный хорошо предсказуемый контекст; 2. Можно вернуть замыкание при копировании значений, что есть единственное настоящее замыкание; 3. Изменения после создания не видны (move), и это предсказуемо; Вывод: в расте хорошие замыкания.

- Python: 1. Неявный непредсказуемый контекст с возможностью явно задать видимость переменной; 2. Всегда можно вернуть замыкание; 3. Изменения после создания видны; Вывод: в питоне хорошая реализация замыканий, но даже черезчур свободная, хоть это и соответствует духу питона.

- C++: 1. Неявная передача констант и глобальных переменных, передача локальных переменных явным параметром; 2. Всегда можно вернуть замыкание; 3. В зависимости от кривизны рук, ты можешь увидеть что угодно после создания замыкания; Вывод: замыкания в C++ есть, но лучше бы их не было.

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

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

процесс вычисления трактуется как вычисление значений функций в математическом понимании последних

В этом смысле функциональный любой язык программирования, где есть функции, а не подпрограммы. И неясно, чем Лисп более функциональный чем Си.

Значения нельзя менять. В функциональных языках «a = 2» - это не присвоение, это объявление константы «a» равной двум. И вывода на экран, в общем-то, тоже нет в ФП, но это уже как бы некоторые внешние, нечистые функции.

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

Четвертый вопрос: сохраняются ли изменения захваченной переменной с каждым последующим вызовом замыкания? Раст говорит «да», лисп позволяет оба варианта

Но как? В лиспе всегда в замыкании ссылка на переменную. Если перед вторым вызовом замыкания переменная изменилась, то в замыкание попадёт новое значение.

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

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

Как же хорошо, что ваше мнение не учитывали при добавлении лямбд в C++.

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

В функциональных языках «a = 2» - это не присвоение, это объявление константы «a» равной двум.

Тогда лисп никак не может быть функциональным. В нём setf — присвоение.

И APL не функциональный:

N ← 4 5 6 7
N ← N+1
N+2
является корректной программой.

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

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

Четвертый вопрос: сохраняются ли изменения захваченной переменной с каждым последующим вызовом замыкания? Раст говорит «да», лисп позволяет оба варианта

Но как? В лиспе всегда в замыкании ссылка на переменную. Если перед вторым вызовом замыкания переменная изменилась, то в замыкание попадёт новое значение.

Переобъявить переменную, бг-г. В общем-то да, изменения скорее сохраняются, чем нет.

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

Как же хорошо, что ваше мнение не учитывали при добавлении лямбд в C++.

Ага, так сладко было писать на божественном C++, а теперь еще слаще стало.

Ты уже забыл, что в крестах на каждый чих с возможностью расширяемости нужно создавать новый класс, получая нечитаемый код. А ты не сможешь вписывать в лямбду, потому что ее возможности очень ограничены. В итоге выбор весьма веселый: написать простые циклы в 13 строчек аля Си, либо изголяться с расширяемыми и повторно используемыми итераторами, но уже на 50 строчек, а также более медленную компиляцию и выполнение с отключенной оптимизацией (отладка). Ссыль я уже давал:
http://aras-p.info/blog/2018/12/28/Modern-C-Lamentations/

Это при том, что в хороших высокоуровневых языках расширяемое решение будет в десять строчек.

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

процесс вычисления трактуется как вычисление значений функций в математическом понимании последних

В этом смысле функциональный любой язык программирования, где есть функции, а не подпрограммы. И неясно, чем Лисп более функциональный чем Си.

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

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

Ага, так сладко было писать на божественном C++, а теперь еще слаще стало.

Вообще-то слаще.

Но суть в другом: вы высказали свое мнение, вам в ответ высказали другое мнение. Вы удивлены, что ваше мнение кому-то не нравится? Тогда вы еще более альтернативно одарены, чем можно подумать, прочитав ваши простыни.

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

Пример в студию.

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

Во-первых, вписывать что?

Во-вторых, как это коррелирует с вашим мнением о том, что нужно было сделать в C++.

Ссыль я уже давал: http://aras-p.info/blog/2018/12/28/Modern-C-Lamentations/

Этот «плач Ярославны» уже обсосали и обосрали 100500 раз.

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

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

В программировании зависит от функции, например результат POSIX sin зависит только от аргумента.

И программировать на математических функциях невозможно. Так как ассемблерные конструкции «запись в порт», «чтение из порта» не реализуются математическими функциями.

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