Чем более функциональное программирование я выполняю, тем больше я чувствую, что оно добавляет дополнительный уровень абстракции, который похож на то, как слой лука - все охватывает предыдущие уровни.
Я не знаю, так ли это, поэтому, исходя из принципов ООП, с которыми я работал годами, кто-нибудь может объяснить, как функционал отображает или не точно отображает любой из них: инкапсуляция, абстракция, наследование, полиморфизм
Я думаю, что все мы можем сказать: да, это инкапсуляция с помощью кортежей, или кортежи технически считаются фактом «функционального программирования», или это всего лишь утилита языка?
Я знаю, что Haskell может удовлетворить требование «интерфейсов», но опять же не уверен, является ли его метод функциональным? Я предполагаю, что тот факт, что у функторов есть математическая основа, можно сказать, что это определенное встроенное ожидание функционала, возможно?
Пожалуйста, опишите, как вы считаете, функционал выполняет или не выполняет 4 принципа ООП.
Редактировать: Я прекрасно понимаю разницу между функциональной парадигмой и объектно-ориентированной парадигмой и понимаю, что в наши дни существует множество языков с множественной парадигмой, которые могут выполнять обе задачи. Я на самом деле просто ищу определения того, как прямой fp (думаю, пурист, как haskell) может выполнить любую из 4 перечисленных вещей, или почему он не может сделать ни одну из них. то есть «Инкапсуляция может быть сделана с помощью замыканий» (или, если я ошибаюсь в этом убеждении, пожалуйста, укажите причину).
источник
Ответы:
Функциональное программирование не на уровень выше ООП; это совершенно другая парадигма. Можно сделать ООП в функциональном стиле (F # был написан именно для этой цели), а на другом конце спектра у вас есть такие вещи, как Haskell, который явно отвергает принципы ориентации объекта.
Вы можете выполнять инкапсуляцию и абстракцию на любом языке, достаточно продвинутом для поддержки модулей и функций. ОО предоставляет специальные механизмы для инкапсуляции, но это не то, что присуще ОО. Смысл ОО - вторая пара, которую вы упомянули: наследование и полиморфизм. Эта концепция формально известна как подстановка Лискова, и ее невозможно получить без поддержки на уровне языка объектно-ориентированного программирования. (Да, в некоторых случаях возможно подделать его, но вы потеряете много преимуществ, которые ОО приносит на стол.)
Функциональное программирование не ориентировано на подстановку Лискова. Он фокусируется на повышении уровня абстракции и на минимизации использования изменяемого состояния и подпрограмм с «побочными эффектами», которые функциональные программисты любят использовать, чтобы заставить подпрограммы, которые действительно что-то делают (в отличие от простого вычисления чего-либо), звучат страшно. Но опять же, это совершенно разные парадигмы, которые можно использовать вместе или нет, в зависимости от языка и навыков программиста.
источник
Я считаю следующую интуицию полезной для сравнения ООП и ФП.
Вместо того, чтобы рассматривать FP как расширенный набор ООП, представьте, что ООП и FP - это два альтернативных способа взглянуть на похожую базовую модель вычислений, в которой вы имеете:
В ООП это фиксируется
В FP это фиксируется
При такой интерпретации объект можно рассматривать как совокупность замыканий (его методов), все из которых захватывают одни и те же нелокальные переменные (переменные-члены объекта, общие для всех замыканий в коллекции). Это представление также подтверждается тем фактом, что в объектно-ориентированных языках замыкания часто моделируются как объекты с использованием только одного метода.
Я думаю, что разные точки зрения проистекают из того факта, что объектно-ориентированное представление сосредоточено на объектах (данных), а функциональное представление сосредоточено на функциях / замыканиях (операциях).
источник
Это зависит от того, кого вы просите дать определение ООП. Спросите пять человек, и вы, вероятно, получите шесть определений. Википедия говорит :
Поэтому, когда кто-то дает очень точный ответ, принимайте его с недоверием.
Тем не менее, есть хороший аргумент в пользу того, что да, FP - это расширенный набор ООП в качестве парадигмы. В частности , определение Алана Кея термина «объектно-ориентированное программирование» не противоречит этому понятию (но это делает Кристен Найгаард ). Все, что Кей действительно беспокоил, это то, что все является объектом, и эта логика реализуется путем передачи сообщений между объектами.
Возможно, что еще более интересно для вашего вопроса, классы и объекты можно рассматривать в терминах функций и замыканий, возвращаемых функциями (которые одновременно действуют как классы и конструкторы). Это очень близко к программированию на основе прототипов, и на самом деле JavaScript позволяет делать именно это.
(Конечно, JavaScript допускает изменение значений, что недопустимо в чисто функциональном программировании, но при этом не требуется в строгом определении ООП.)
Тем не менее, более важный вопрос: является ли это значимой классификацией ООП? Полезно ли думать об этом как о подмножестве функционального программирования? Я думаю, что в большинстве случаев это не так.
источник
FP как OO не является четко определенным термином. Есть школы с разными, порой противоречивыми определениями. Если вы берете то, что у них общего, вы переходите к:
функциональное программирование - это программирование с функциями первого класса
ОО-программирование - это программирование с полиморфизмом включения в сочетании по крайней мере с ограниченной формой динамически разрешаемой перегрузки. (Примечание стороны: в ОО - кругах полиморфизм обычно берется среднее включение полиморфизма, в то время как FP школы это обычно означает , что параметрический полиморфизм.)
Все остальное либо присутствует в другом месте, либо отсутствует в некоторых случаях.
FP и OO - два инструмента построения абстракций. У каждого из них есть свои сильные и слабые стороны (например, у них разные предпочтительные направления расширения в задаче выражения), но ни один из них не является более мощным, чем другой. Вы можете построить OO-систему на ядре FP (CLOS - одна из таких систем). Вы можете использовать OO-фреймворк для получения функций первого класса (например, смотрите, как лямбда-функции определены в C ++ 11).
источник
std::function
, к которому могут быть назначены как указатели функций, так и лямбда-выражения, является явно общим, а не объектно-ориентированным. Это неудивительно, потому что ограниченная марка полиморфизма объектной ориентации (полиморфизм подтипа) строго менее мощна, чем параметрический полиморфизм (даже Хиндли-Милнер, не говоря уже о полной Системе F-омега).Нет; ООП может рассматриваться как расширенный набор процедурного программирования и принципиально отличается от функциональной парадигмы, поскольку его состояние представлено в полях экземпляра. В функциональной парадигме переменные - это функции, которые применяются к постоянным данным для получения желаемого результата.
На самом деле вы можете считать функциональное программирование подмножеством ООП; если вы сделаете все свои классы неизменяемыми, вы можете подумать, что у вас есть какое-то функциональное программирование.
источник
Ответ:
В Википедии есть отличная статья о функциональном программировании с некоторыми примерами, которые вы просите. @ Конрад Рудольф уже предоставил ссылку на статью ООП .
Я не думаю, что одна парадигма является супер-набором другой. Это разные точки зрения на программирование, и некоторые проблемы лучше решать с одной точки зрения, а некоторые - с другой.
Ваш вопрос усложняется всеми реализациями FP и ООП. У каждого языка есть свои особенности, которые имеют отношение к любому хорошему ответу на ваш вопрос.
Все более Тангенциальный Рамблинг:
Мне нравится идея, что такой язык, как Scala, пытается дать вам лучшее из обоих миров. Я волнуюсь, что это дает вам осложнения обоих миров.
Java является ОО-языком, но в версии 7 добавлена функция «попробуй с ресурсами», которая может использоваться для имитации своего рода замыкания. Здесь он имитирует обновление локальной переменной «а» в середине другой функции, не делая ее видимой для этой функции. В этом случае первая половина другой функции - это конструктор ClosureTry (), а вторая половина - метод close ().
Выход:
Это может быть полезно по назначению: открыть поток, записать в него и надежно закрыть его, или просто соединить две функции так, чтобы вы не забыли вызвать вторую после выполнения некоторой работы между ними. , Конечно, это настолько ново и необычно, что другой программист может удалить блок try, не осознавая, что он что-то ломает, поэтому в данный момент это своего рода анти-паттерн, но интересно, что это можно сделать.
Вы можете выразить любой цикл в большинстве императивных языков как рекурсию. Объекты и переменные можно сделать неизменными. Процедуры могут быть написаны так, чтобы минимизировать побочные эффекты (хотя я бы сказал, что настоящая функция на компьютере невозможна - время, которое требуется для выполнения, и ресурсы процессора / диска / системы, которые она потребляет, являются неизбежными побочными эффектами). Некоторые функциональные языки могут выполнять многие, если не все объектно-ориентированные операции. Они не должны быть взаимоисключающими, хотя некоторые языки имеют ограничения (например, запрещение какого-либо обновления переменных), которые предотвращают определенные шаблоны (например, изменяемые поля).
Для меня наиболее полезными частями объектно-ориентированного программирования являются сокрытие данных (инкапсуляция), обработка достаточно похожих объектов как одинаковых (полиморфизм) и сбор ваших данных и методов, которые работают с этими данными вместе (объекты / классы). Наследование может быть флагманом ООП, но для меня это наименее важная и наименее используемая часть.
Наиболее полезными частями функционального программирования являются неизменяемость (токены / значения вместо переменных), функции (без побочных эффектов) и замыкания.
Я не думаю, что это объектно-ориентированный, но я должен сказать, что одна из самых полезных вещей в информатике - это способность объявлять интерфейс, а затем реализовывать различные части функциональности и данные для реализации этого интерфейса. Мне также нравится иметь несколько изменяемых фрагментов данных для работы, поэтому я думаю, что мне не совсем удобно работать исключительно на функциональных языках, хотя я стараюсь ограничивать изменчивость и побочные эффекты во всех моих проектах программ.
источник