Делает ли изучение функционального языка лучшим программистом ООП? [закрыто]


28

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

Кто-нибудь может это подтвердить? Каким образом это улучшает ваши навыки программирования?

Каков хороший выбор языка для изучения с целью улучшения навыков на менее сложном языке?


3
Если вы пишете код на C #, вы уже знаете его. LINQ довольно функциональная вещь.
SK-logic

Я думаю, что ООП лучше для моделирования реальных объектов.
Тулаинс Кордова

1
@ user61852 Большинство шаблонов проектирования ОО не моделируют ничего о «реальных» объектах, но на самом деле являются очень абстрактными понятиями.
Андрес Ф.

Будьте больше, чем программист на Java / C # (+ C ++). Есть разница между гигантским швейцарским армейским ножом с не такой маленькой брошюрой, в которой описывается, почему вы выбрали лезвие X из 40, и лезвием, которое вы можете вырезать из всего, что вам нравится, потому что оно чертовски острое и изгибается просто Право так, что вы можете применить его режущую способность в самых разных обстоятельствах, не задумываясь. (с открывашкой для бутылок в ручке, конечно)
Эрик Реппен

Ответы:


32

Я в основном согласен с ответом FrustratedWithFormsDesign , но вы также спросили, как изучение новой парадигмы помогает развивать свои навыки. Я могу привести пару примеров из собственного опыта.

Начиная с изучения функционального программирования, я намного больше осознаю, какие концепции, с которыми я работаю, более естественно рассматриваются как «объекты» (обычно там, где имеет место мутация), а какие более естественно рассматриваются как неизменные «ценности» (я думаю, что есть важное различие касаясь того, где ОО имеет смысл, по сравнению с тем, когда имеет смысл ФП, но это только мое мнение).

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

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

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

Я более склонен использовать функции более высокого порядка. Статья Джона Хьюза « Почему функциональное программирование имеет значение» . Это подчеркивает возможность компоновки, которую вы получаете, используя методы функционального программирования, причем функции высшего порядка играют главную роль.

Кроме того, как уже упоминалось в ответе Jetti , вы обнаружите, что многие идеи FP внедряются в новые ОО-языки. Ruby и Python предоставляют много функций более высокого порядка, я слышал, что LINQ описывается как попытка обеспечить поддержку монадического понимания в C #, даже в C ++ теперь есть лямбда-выражения.


@Aidan: по отношению к лямбдам в C ++ 0x, во всяком случае, новые компиляторы C ++ уже включили их.
Матье М.

1
«Объект» как «вещь, которая содержит изменяемое состояние» очень распространена, но паттерн «Объект стоимости» существует уже много лет.
Фрэнк Шиарар

@Matthieu, спасибо, я обновил текст, чтобы отразить это.
Эйдан Калли

@Frank: спасибо за указатель. Я не включил это в ответ, но основное возражение, которое я должен сделать, чтобы сделать значения объектами, связано с различием ч / б интерфейсов объектов (которые принадлежат объектам) и операциями (в которых отношения между объектами более первичнее самих объектов). 1 + 2математически эквивалентно 2 + 1, но 1.+(2)реализовано иначе, чем 2.+(1). Существует целый ряд проблем SW, которые можно понять более естественно при использовании операций, чем при использовании объектных интерфейсов.
Эйдан Калли

1
@Aidan Вы читали книгу Уильяма Кука "О понимании абстракции данных, снова в курсе"? Он углубляется в различия между объектами и ADT, на что вы намекаете.
Фрэнк Шиарар

32

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


3
Учитывая, что объекты на самом деле являются функциями более высокого порядка, я обнаружил, что изучение FP действительно помогло с моим ООП. Это, как вы говорите, более общеприменимо / полезно.
Фрэнк Шиарар

12

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


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

Я никогда не слышал, чтобы Пролог называли функциональным языком. Если я прищуриваюсь достаточно, я смутно вижу, как (части) Пролог мог помочь с ФП.
Фрэнк Шиарар

1
Пролог не является функциональным языком. Это логический язык. Если вам нужен логический язык, похожий на Prolog, который также интегрирован с функциональным программированием, учтите , вы можете получить представление о Mercury . Предупреждение: это немного повредит вашему мозгу, даже если вы уже знаете Пролог.
ТОЛЬКО МОЕ правильное мнение

@ Просто мое правильное мнение: Да, я думаю, что вы правы. Думаю, мне нужно больше узнать о функциональных языках!
Майкл К

1
@moz: Да, я бы хотел, чтобы на Java были лямбды. Анонимные Threadобъекты ... неуклюжи.
Майкл К

9

Изучение любой другой парадигмы программирования улучшит ваши навыки программирования в целом. Программирование, когда оно не является академическим научным материалом (и даже тогда, часто), в основном является решением проблем. Думая одним словом. Различные парадигмы - это разные способы мышления о проблемах и их решениях. Так что не думайте об этом как о «изучении функционального языка». Думайте об этом как о «изучении другого способа думать о проблемах и их решениях». Тогда вы увидите преимущества изучения языка, даже если вы никогда его не используете.

Чтобы ответить на ваш конкретный вопрос, я был программистом на C ++ еще в те времена (еще до того, как появился стандарт для C ++). Я следовал за всеми обычными вещами с объектами, содержащими состояние, управляемое методами и т. Д. И т. Д. И т. Д. Затем я наткнулся на Хаскелл и изучил (большую часть) это. (Я не думаю, что кто-то когда-нибудь по-настоящему изучает Haskell.) Это упражнение выглядело немного напрасным, пока один из моих коллег, тестировщик, назначенный в мою группу, не сделал ничего из комментариев, что мой код стало легче тестировать.

Случилось так, что я начал делать свои объекты все более и более неизменными. Классы со сложным изменяемым состоянием начали заменяться классами, которые клонировали себя с изменениями, возвращая новые объекты. Общие объекты начали заменяться объектами, которые имели семантику копирования при записи (таким образом, создавая иллюзию множества клонов объектов без использования памяти). Функции не имели побочных эффектов, за исключением случаев, когда это абсолютно необходимо; Чистое математическое определение «функции» становилось все более и более нормой. Все это начало происходить в моем коде естественным образом - без какой-либо сознательной мысли - когда я исследовал все больше и больше функционального пространства программирования.

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


3

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


3

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

Даже со всеми этими функциями - динамическая типизация, сборка мусора и т. Д. Программы на этих языках все еще полностью основаны на побочных эффектах. Функциональные языки программирования, такие как Scheme, Clojure, Haskell и ML - это нечто совершенно иное, эти языки ближе к математике, чем к машинному коду. Вместо того, чтобы использовать побочные эффекты, вы передаете значения вокруг функций.

Каков хороший выбор языка для изучения с целью улучшения навыков на менее сложном языке?

Я рекомендую Scheme , она минимальна и использовалась в старых вводных классах MIT. Другие функциональные языки программирования гораздо сложнее выучить. Clojure сочетает в себе все тонкости Java, ML - сложную систему статических типов, Haskell иногда называют академическим языком - он не идеален для начинающих и так далее. Схема с другой стороны проста в освоении и понимании.

Каким образом это улучшает ваши навыки программирования?

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.