Являются ФП и ОО ортогональной?


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

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

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

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

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

10 70

10 ответов:

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

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

объектно-ориентированное программирование охватывает такие темы, как:
  • инкапсуляция
  • полиморфизм
  • абстрагирование

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

давайте, выражение (1 + 2) * 3. Тогда АСТ будет:
       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, С другой стороны, мы будем реализовывать эту таблицу по столбцам - мы напишем функцию для каждого глагола, и эта функция будет по-разному реагировать на аргументы различных типов (возможно, с использованием сопоставления шаблонов).

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

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

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

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

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