Функциональное программирование против объектно-ориентированного программирования

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

  • Когда вы выбираете функциональное программирование над объектно-ориентированным?
  • Каковы типичные определения проблем, когда функциональное программирование является лучшим выбором?

Ответ 1

Когда вы выбираете функциональное программирование над объектно-ориентированным?

Когда вы ожидаете разного рода эволюцию программного обеспечения:

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

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

Когда эволюция идет не так, у вас есть проблемы:

  • Добавление новой операции в объектно-ориентированную программу может потребовать редактирования многих определений классов для добавления нового метода.

  • Добавление нового типа вещи в функциональную программу может потребовать редактирования многих определений функций для добавления нового случая.

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

Каковы типичные определения проблем, когда функциональное программирование является лучшим выбором?

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

Ответ 2

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

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

Другой пример: F #. Вы можете сказать, что это в основном FP, но существует много концепций и конструкций ООП. Вы можете определять классы, абстрактные классы, интерфейсы, иметь дело с наследованием. Вы даже можете использовать изменчивость, когда он делает ваш код более четким или когда он резко увеличивает производительность.

Многие современные языки являются мультипарадигмой.

Рекомендуемые показания

Поскольку я нахожусь в одной лодке (фон ООП, изучая FP), я бы предложил вам некоторые чтения, которые я действительно оценил:

Ответ 3

Объектно-ориентированное программирование предлагает:

  • Инкапсуляция, чтобы
    • управляющая мутация внутреннего состояния
    • ограничение связи с внутренним представлением
  • Подтипирование, позволяющее:
    • замена совместимых типов (полиморфизм)
    • грубое средство совместного использования между классами (наследование реализации)

Функциональное программирование в Haskell или даже в Scala может позволить замену через более общий механизм классов типов. Могучее внутреннее состояние либо не рекомендуется, либо запрещено. Инкапсуляция внутреннего представления также может быть достигнута. См. Haskell против OOP для хорошего сравнения.

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

EDITED Удалена ссылка на неявные преобразования при обсуждении классов классов. В Scala типы классов кодируются с неявными параметрами, а не с конверсиями, хотя неявные преобразования - это еще одно средство для подмены совместимых типов.

Ответ 4

  • Если вы находитесь в сильно параллельной среде, полезно использовать чисто функциональное программирование. Отсутствие изменчивого состояния делает concurrency почти тривиальным. См. Erlang.

  • В многостраничном языке вы можете моделировать некоторые функции функционально, если существование изменяемого состояния должно быть детализированным, и, таким образом, FP является хорошей моделью для проблемной области. Например, см. Список в Python или std.range на языке программирования D. Они вдохновлены функциональным программированием.

Ответ 5

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

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

OOP говорит, что объединение данных и их поведение в одном месте облегчает понимание того, как работает программа. FP говорит, что данные и поведение являются совершенно разными и должны быть раздельными для ясности.

Даже объединение как Javascript, так и объектно-ориентированного программирования позволяет разработчикам писать коды, которые являются чистыми, краткими и повторяемыми. Разработчики могут создавать небольшие блоки кодов, которые затем могут быть вызваны снова, без необходимости переписывать код или копировать код снова и снова. OOP JavaScript также предлагает основанное на прототипе наследование, основанное на классе, которое позволяет объектам напрямую наследовать от других объектов.