Чи є вивчення функціональної мови кращим програмістом OOP? [зачинено]


28

Як програміст Java / C # / C ++ я чую багато розмов про функціональні мови, але ніколи не знаходжу необхідності вивчати цю мову. Я також чув, що вищий рівень мислення, запроваджений у функціональних мовах, робить вас кращим програмістом OOP / процедурних мов.

Хтось може це підтвердити? Якими способами це покращує ваші навички програмування?

Який хороший вибір мови для вивчення з метою вдосконалення навичок менш складної мови?


3
Якщо ви кодуєте в C #, ви його вже знаєте. LINQ - цілком функціональна річ.
SK-логіка

Я думаю, що OOP краще для моделювання об'єктів реального життя.
Тулен Кордова

1
@ user61852 Більшість моделей дизайну OO не моделюють нічого про об'єкти "реального життя", а насправді дуже абстрактні поняття.
Андрес Ф.

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

Відповіді:


32

Я в основному погоджуюся з відповіддю FrustratedWithFormsDesign , але ви також запитували, як вивчення нової парадигми допомагає розвивати навички. Я можу навести пару прикладів із власного досвіду.

Оскільки я вивчаю функціональне програмування, я набагато усвідомлюю, з якими поняттями, з якими я працюю, більш природно розглядаються як "об'єкти" (як правило, де мутація має сенс), а які більш природно розглядаються як незмінні "цінності" (я думаю, є важлива відмінність , торкаючись того, де OO має сенс порівняно, коли FP має сенс, але це лише моя думка).

Я помічаю, де мій код включає побічні ефекти, і я обережніше виділяти ці місця, роблячи більшість своїх функцій "чистими" функціями. Це значно покращує перевірку мого OO-коду.

Я більше усвідомлюю цикли у своєму представленні даних. (Наприклад, я не думаю, що ви можете написати функцію для перетворення зв'язаного списку в подвійно пов'язаний список в Haskell, тому ви помічаєте цикли трохи більше на цій мові.) Уникнення циклів зменшує кількість синхронізації вам потрібно виконати, щоб ваші структури даних були внутрішньо послідовними, полегшуючи навантаження на обмін цими структурами між потоками.

Я швидше покладаюся на рекурсію (рекурсивні циклічні конструкції схеми - речі краси). Дійкстра торкнувся важливості цього в Примітках про структуроване програмування - рекурсивні алгоритми дуже безпосередньо вказують на математичну індукцію, що, на його думку, є єдиним засобом інтелектуально довести наші петлі правильними. (Я не припускаю, що ми повинні доводити свій код правильним, але що чим простіше нам це зробити, тим більше шансів на те, що наш код правильний.)

Я швидше використовую функції вищого порядку. Доповідь Джона Х'юза, чому питання функціонального програмування має значення . Це підкреслює композиційність, яку ви отримуєте від використання функціональних методів програмування, функцій вищого порядку, що відіграють головну роль.

Крім того, що стосується відповіді Jetti , ви дізнаєтесь, що багато нових ідей ПП включено в новіші мови OO. І Ruby, і Python забезпечують багато функцій вищого порядку, я чув, як LINQ описується як спроба ввести підтримку монадних розумінь у C #, навіть у C ++ зараз є лямбда-вирази.


@Aidan: wrt лямбда в C ++ 0x, у будь-якому випадку нові компілятори C ++ вже включили їх.
Матьє М.

1
"Об'єкт" як "річ, яка зберігає стан змін", є дуже поширеним явищем, але модель "Ціннісного об'єкта" існує вже багато років.
Френк Ширар

@Matthieu, дякую, я оновив текст, щоб це відобразити.
Айдан Каллі

@Frank: дякую за вказівник. Я не включив це у відповідь, але головне заперечення, яке я маю вводити Значення в Об'єкти, пов'язане з розрізненням інтерфейсів між об'єктами (якими належать об'єкти) та операцій (у яких відносини між об'єктами більше первинні, ніж самі об’єкти). 1 + 2математично еквівалентний 2 + 1, але 1.+(2)реалізується інакше, ніж 2.+(1). Існує ряд проблем ПЗ, ніж їх можна зрозуміти природніше за допомогою операцій, ніж використання об'єктних інтерфейсів.
Айдан Каллі

1
@Aidan Чи читали ви "Урозуміння абстракції даних, переглянуте" Вільяма Кука? Він заглиблюється у відмінності між об'єктами та ADT, на що ви натякаєте.
Френк Шірар

32

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


3
Враховуючи, що об'єкти - це фактично функції вищого порядку, я виявив, що вивчення FP-матеріалів допомогло безпосередньо з моїм OOP. Це, як ви кажете, більш загальноприйнятне / корисне, хоча.
Френк Ширар

12

Вивчення функціональної мови - для мене Lisp - дуже допомагає при побудові паралельних додатків. Функціональні методи (на основі стану, відсутність побічних ефектів) набагато простіше синхронізувати, і їх легше зробити безпечними для потоків, оскільки вони залежать лише від їх введення. Це означає, що єдині дані, які вам потрібно спостерігати для даної області коду, - це параметри, які ви передаєте. Це також полегшує налагодження.


Ви побачите, що це також допомагає в роботі бібліотек, що сподіваються на чисті функції як на їх завдання. Це також може допомогти опосередковано, є місця, де я напишу код OO у якомусь "функціональному стилі", де є "параметр володіння", який має неявний замок на купі об'єктів, на які він посилається, і використовується функцією . Поки ви документуєте свої очікування (і випробовуєте їх), це може дати вам кращий багатопотоковий код з кількома проблемами блокування. І кілька явних замків.

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

1
Пролог не є функціональною мовою. Це логічна мова. Якщо ви хочете Prolog- як логічна мова, Інтегровані функціонального програмування , а також, розум, ви можете захопити одружений на Меркурії . Попередження: Це трохи зашкодить вашому мозку, навіть якщо ви вже знаєте Пролог.
ПРОСТО МОЕ правильне ДУМКА

@ Справедливий мій правильний висновок: Так, я думаю, ти маєш рацію. Напевно, мені потрібно дізнатися більше про функціональні мови!
Майкл К

1
@moz: Так, я хотів би, щоб у Java були лямбда. Анонімні Threadоб’єкти ... незграбні.
Майкл К

9

Вивчення будь-якої іншої парадигми програмування в цілому покращить ваші навички програмування. Програмування, коли це не наукові дослідження (і навіть тоді, часто), в основному вирішує проблеми. Думаючи, одним словом. Різні парадигми - це різні способи мислення про проблеми та їх вирішення. Тому не думайте про це як про "вивчення функціональної мови". Подумайте про це як про "інший спосіб думати про проблеми та їх рішення". Тоді ви побачите переваги вивчення мови, навіть якщо ви ніколи її фактично не використовуєте.

Щоб вирішити ваше конкретне питання, я був програмістом на C ++ ще в часи (до того, як був стандарт для C ++). Я стежив за всіма звичними речами з об'єктами, що тримають стан, маніпулюючи методами, тощо. І т. Д. І т.д. (Я не думаю, що ніхто ніколи по-справжньому не вивчає Haskell.) Вправа здавалося трохи витраченою в той час, поки один з моїх колег, тестер, призначений для моєї групи, не зробив зауваження, що мій код стає простіше перевірити.

Сталося те, що я почав робити свої предмети все більш непорушними. Класи зі складним змінним станом почали замінюватися класами, які клонували себе змінами, повертаючи нові об’єкти. Спільні об'єкти почали замінюватись об'єктами, які мали семантику копіювання під час запису (таким чином, створюючи ілюзію безлічі клонів об’єктів без накладних витрат на пам'ять). Функції не мали побічних ефектів, якщо це абсолютно не потрібно; чисте, математичне визначення поняття "функція" все більше і більше було нормою. Все це почало відбуватися в моєму коді природним шляхом - жодна свідома думка не заплутувалася - коли я досліджував все більше функціонального простору програмування.

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


3

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


3

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

Навіть з усіма цими можливостями - динамічне набір тексту, збирання сміття тощо на цих мовах все ще повністю базуються на побічних ефектах. Мови функціонального програмування, такі як Scheme, Clojure, Haskell і ML - це зовсім інше, ці мови ближче до математики, ніж до машинного коду. Замість того, щоб використовувати побічні ефекти, ви передаєте значення навколо функцій.

Який хороший вибір мови для вивчення з метою вдосконалення навичок менш складної мови?

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

Якими способами це покращує ваші навички програмування?

Практично всі мови програмування високого рівня мають функції та рекурсію - поняття, на яких ґрунтується функціональне програмування. Таким чином, ваше знання FP повинно бути корисним майже скрізь, однак, якщо ви дійсно хочете програмувати функціонально, ви повинні використовувати мову там, де це природно і ефективно, а не намагатися зв'язати чужий дизайн мови на свій смак, тобто для функціонального програмування слід використовувати функціональну мову програмування.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.