FP и OO ортогональны? - PullRequest
       73

FP и OO ортогональны?

72 голосов
/ 16 октября 2010

Я слышал это снова и снова, и я пытаюсь понять и подтвердить идею, что FP и OO ортогональны.

Прежде всего, что означает, что 2 понятия ортогональны?

FP поощряет неизменность и чистоту в максимально возможной степени, в то время как ОО кажется построенным для состояния и мутации - слегка организованная версия императивного программирования? Я понимаю, что объекты могут быть неизменными, но ОО, кажется, подразумевает состояние / изменение для меня.

Они кажутся противоположностями. Как это влияет на их ортогональность?

Такой язык, как Scala, позволяет легко использовать как OO, так и FP, влияет ли это на ортогональность двух методов?

Ответы [ 10 ]

68 голосов
/ 16 октября 2010

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

Два понятия объектно-ориентированное программирование и функциональное программирование не являются несовместимыми друг с другом. Объектная ориентация не подразумевает изменчивость. Многие люди, которые знакомятся с объектно-ориентированными программами традиционным способом, часто сначала используют C ++, Java, C # или подобные языки, где изменчивость распространена и даже поощряется (стандартные библиотеки предоставляют разнообразные изменяемые классы для использования людьми). Поэтому понятно, что многие люди связывают объектно-ориентированное программирование с императивным программированием и изменчивостью, как они это узнали.

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

  • Инкапсуляция
  • Полиморфизм
  • абстракция

Ничто из этого не подразумевает изменчивость и не исключает функциональное программирование. Так что да, они ортогональны в том смысле, что это разные понятия. Они не являются противоположностями - вы можете использовать один или другой, или оба (или даже ни один). Такие языки, как Scala и F #, пытаются объединить обе парадигмы в один язык:

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

Источник

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

Источник

15 голосов
/ 16 октября 2010

Прежде всего, что означает, что 2 понятия ортогональны?

Это означает, что эти два понятия не имеют противоположных идей или не несовместимы друг с другом.

FP поощряет неизменность и чистоту в максимально возможной степени. и ОО кажется чем-то, что построено для состояния и мутации (слегка организованная версия императивного программирования?). И я понимаю, что объекты могут быть неизменными. Но ОО, кажется, подразумевает состояние / изменение для меня.

Они кажутся противоположностями. Как это влияет на их ортогональность?

Такой язык, как Scala, позволяет легко использовать как OO, так и FP, влияет ли это на ортогональность двух методов?

OO - это инкапсуляция, состав объектов, абстракция данных, полиморфизм посредством подтипирования и контролируемая мутация при необходимости (неизменность также поддерживается в OO). FP - это композиция функций, управляющая абстракция и ограниченный полиморфизм (он же параметрический полиморфизм). Таким образом, две идеи не противоречат друг другу. Они оба предоставляют вам различные виды полномочий и механизмов абстракции, которые, безусловно, можно использовать на одном языке. Фактически, это тезис, на котором была построена Scala !

В своем выступлении Scala Experiment в Google Мартин Одерски очень хорошо объясняет, как он считает, что два понятия - OO и FP - ортогональны друг другу и как Scala элегантно и плавно объединяет две парадигмы новая парадигма, широко известная в сообществе Scala как объектно-функциональная парадигма. Должен смотреть разговор для вас. : -)


Другие примеры объектно-функциональных языков: OCaml , F # , Nemerle .

12 голосов
/ 16 октября 2010

Прежде всего, что означает, что 2 понятия ортогональны?

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

Они кажутся противоположностями.Как это влияет на их ортогональность?

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

, и ОО выглядит как нечто, созданное для состояния и мутации (слегка организованная версия императивного программирования?).И я понимаю, что объекты могут быть неизменными.Но OO, кажется, подразумевает состояние / изменение для меня.

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

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

7 голосов
/ 16 октября 2010

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

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

Например, такой функциональный язык, как OCaml, выполняет инкапсуляцию с помощью лексических областей видимости и замыканий, в то время как объектно-ориентированные языки используют модификаторы открытого / частного доступа. Эти механизмы сами по себе не являются несовместимыми, но они избыточны, и такой язык, как F # (в основном функциональный язык, который стремится жить в гармонии с явно объектно-ориентированной библиотекой .NET и языковым стеком), должен идти на попятную разрыв.

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

7 голосов
/ 16 октября 2010

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

Применяется кИсходный вопрос означает, что существуют чисто функциональные, не объектно-ориентированные языки программирования, такие как Haskell, чисто объектно-ориентированные, «нефункциональные» языки, такие как Eiffel, но также есть языки, которые не являются такими, как C, и языки, которые оба являются такимикак Scala.

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

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

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

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

6 голосов
/ 16 октября 2010

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

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

5 голосов
/ 17 октября 2010

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

FP поощряет неизменность и чистоту в максимально возможной степени

Вы говорите о чисто функциональном программировании.

в то время как ОО кажется построенным для состояния и мутации

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

Такой язык, как Scala, позволяет легко выполнять OO и FP одновременно

Не совсем. Отсутствие оптимизации хвостового вызова означает, что большая часть идиоматического, чисто функционального кода будет переполняться стеком в Scala, поскольку он пропускает кадры стека. Например, стиль прохождения продолжения (CPS) и все методы, описанные в статье Это завершает Брюса МакАдама. Нет простого способа исправить это, потому что сама JVM не способна к оптимизации хвостового вызова.

Что касается ортогональности чисто функционального программирования и объектно-ориентированного программирования, я бы сказал, что они, по крайней мере, близки к ортогональности просто потому, что чисто функциональное программирование имеет дело только с программами малого размера (например, функциями высшего порядка), тогда как объектно-ориентированное программирование имеет дело с масштабным структурированием программ. Вот почему функциональные языки программирования обычно предоставляют какой-то другой механизм для крупномасштабного структурирования, например, модульные системы высшего порядка Standard ML и OCaml или CLOS для Common Lisp или классы типов для Haskell.

2 голосов
/ 18 октября 2010

Одна вещь, которая помогла мне понять связь между FP и OO, была книга SICP, в частности, раздел «Модульность функциональных программ и модульность объектов» Если вы думаете об этих проблемах, и у вас естьв свободные выходные, возможно, стоит прочитать первые три главы, это довольно открытое зрелище.

1 голос
/ 20 августа 2017

Я только что нашел замечательное объяснение ортогональности ООП и ФП.

Основная идея заключается в следующем. Представьте, что мы работаем с математическими выражениями. Таким образом, у нас есть разные типы существительных (константа, сложение, умножение) и разные глаголы (eval, toString).

Допустим, выражение (1 + 2) * 3. Тогда AST будет:

       multiplication
         /        \
     addition      3
      /    \
     1      2

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

                +---------------------+-------------------------------------+
                | eval                | toString                            |
+---------------+---------------------+-------------------------------------+
| constant      | value               | value.toString                      |
+---------------+---------------------+-------------------------------------+
| addition      | lhs.eval + rhs.eval | lhs.toString + " + " + rhs.toString |
+---------------+---------------------+-------------------------------------+
| mutiplication | lhs.eval * rhs.eval | lhs.toString + " * " + rhs.toString |
+---------------+---------------------+-------------------------------------+

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

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

0 голосов
/ 19 октября 2010

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

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

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

Был большой интерес к методам функционального программирования, главным образом из-за требуемого управления состоянием при работе с многоядерными чипами и параллельным программированием.На данный момент кажется, что функциональное программирование имеет преимущество в этом, однако вы можете достичь того же эффекта, используя Objects.Вы просто думаете о проблеме по-другому.Вместо того, чтобы почесать голову, пытаясь как можно больше избавиться от состояния, вы смотрите на объекты в дизайне и видите, как вы можете связать их с тем, что лежит в основе того, что они должны делать, используя шаблоны проектирования, CRC иАнализ объекта.Там, где объекты сами по себе оказываются, и где функциональное программирование намного сложнее, это анализ реального мира и отображение его в понятную компьютеризированную систему.Например, в ОО объект person будет инкапсулировать состояние с помощью методов, которые воздействуют на состояние лица.В функциональном программировании человек был бы разбит на части данных и функции, которые воздействуют на данные о человеке, с дополнительным условием, что данные должны создаваться один раз и только один раз и быть неизменными.

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

...