Чи збільшує функціональне програмування «представницький розрив» між проблемами та рішеннями? [зачинено]


18

Оскільки машинна мова (наприклад, 0110101000110101) комп'ютерні мови, як правило, переросла у вищі форми абстрагування, загалом полегшуючи розуміння коду при застосуванні до проблеми. Assembler - це абстракція над машинним кодом, C - абстракція над асемблером тощо.

Об'єктно-орієнтований дизайн здається дуже хорошим, що дозволяє нам моделювати проблему з точки зору об'єктів, наприклад, проблема системи реєстрації університетських курсів може моделюватися з Courseкласом, Studentкласом тощо. Потім, коли ми пишемо рішення мовою ОО, ми маємо подібні класи, які несуть відповідальність, і це, як правило, корисно для проектування, особливо для модуляції коду. Якщо я даю цю проблему 10 незалежним командам, які вирішують її методом ОО, загалом 10 рішень матимуть спільні класи, що стосуються проблеми. Коли ви починаєте зв'язуватися та взаємодіяти між цими класами, може виникнути велика різниця, тому немає такого поняття, як "нульовий розрив у репрезентації".

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

Я розумію переваги FP щодо одночасного програмування. Але я щось пропускаю, чи FP не про зменшення представницького розриву (полегшення розуміння рішень)?

Ще один спосіб запитати це: чи має FP-код 10 різних команд, що вирішують ту саму проблему в реальному світі, багато спільного?


З Вікіпедії з абстракції (інформатика) (моє наголос):

Мови функціонального програмування зазвичай демонструють абстракції, пов'язані з функціями , такими як лямбда-абстракції (перетворення терміна у функцію якоїсь змінної), функції вищого порядку (параметри - функції), дужки абстракції (перетворення терміна у функцію змінної).

Представницький розрив може бути потенційно збільшений, оскільки [деякі] проблеми в реальному світі не моделюються легко за допомогою таких абстракцій.


Інший спосіб, який я бачу, зменшується представницький розрив, - це відшукати елементи рішення до проблеми. У машинному коді 01s ' дуже важко відстежити, тоді як Studentклас легко простежити назад. Не всі класи OO легко простежують проблемний простір, але багато хто робить.

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


Прийнята відповідь на пов’язане питання Чи можна використовувати UML для моделювання функціональної програми? - говорить: "Функціональні програмісти не мають великої користі для діаграм". Мені справді все одно, чи це UML, але це змушує мене замислитись про те, як абстракції FP легко зрозуміти / спілкуватися, якщо немає діаграм, які широко використовуються (якщо вважати, що ця відповідь є правильною). Знову ж таки, мій рівень використання / розуміння ПС є тривіальним, тому я не розумію потреби в діаграмах для простих програм FP.

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


Багато відповідей говорять про те, як аналіз і проектування робляться в ПП аналогічно OO, але поки що ніхто не цитує нічого високого рівня (Паул цитував якісь цікаві речі, але це низький рівень). Я вчора багато зробив Google, і знайшов цікаву дискусію. Далі - з функціональних програм Refactoring від Simon Thompson (2004 )

При проектуванні об'єктно-орієнтованої системи, це само собою зрозуміло, що дизайн буде передувати програмуванню. Дизайн буде написано за допомогою системи типу UML, яка підтримується в таких інструментах, як Eclipse. Починаючі програмісти цілком можуть вивчити підхід до візуального дизайну за допомогою таких систем, як BlueJ. Про роботу над аналогічною методологією функціонального програмування повідомляється у FAD: Функціональний аналіз та проектування , але мало інших робіт існує. Для цього може бути ряд причин.

  • Існуючі функціональні програми мають масштаб, який не потребує розробки. Багато функціональних програм є невеликими, але інші, наприклад, Glasgow Haskell Compiler, є суттєвими.

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

  • Функціональні програми будуються як розвивається серія прототипів.

У цитованій кандидатській дисертації переваги використання методів аналізу та проектування (ADM) окреслені незалежно від парадигм. Але зроблено аргумент, що ADM повинні узгоджуватися з парадигмою реалізації. Тобто OOADM найкраще працює для програмування OO і недостатньо застосовується до іншої парадигми, такої як FP. Ось чудова цитата, на яку я думаю, перефразовуючи те, що я називаю представницьким розривом:

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

Ось набір діаграм, запропонованих FAD:

  • діаграми залежності функцій, які представляють функцію з тими, які вона використовує для своєї реалізації;
  • діаграма залежності типу, яка забезпечує однакову послугу для типів; і,
  • діаграми залежності модулів, які представляють представлення архітектури модуля системи.

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

На жаль, окрім FAD, я не бачу жодних сучасних посилань на мови моделювання (візуальні), які пропонуються для FP. UML - це ще одна парадигма, тому ми повинні забути про це.


1
Коментарі не для розширеного обговорення; ця розмова переміщена до чату .
maple_shaft

Відповіді:


20

Основні дані структуровані однаково у майже будь-якій парадигмі. Ви будете мати a Student, a Courseтощо, будь то об'єкт, структура, запис чи інше. Різниця з OOP полягає не в тому, як структуруються дані, а в тому, як структуруються функції.

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

Раптом не так зрозуміло, який клас повинен створити і зберігати всі ці списки. Навіть менше, коли у вас складні комбінації цих списків. Однак ви повинні вибрати один клас.

На FP ви пишете функції, які приймають студента та список курсів та повертають відфільтрований список курсів. Ви можете згрупувати всі такі функції разом у модулі. Вам не доведеться поєднувати його з тим чи іншим класом.

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


5
@BenAaronson проблема мого досвіду полягає в тому, що потім будь-яка функція, пов’язана зі студентом, додається до класу Студент, і його обов'язки ростуть і зростають, поки вам не потрібно ввести, StudentCourseFiltererщоб все було керованим
AlexFoxGill

3
@Den Hybrid підходи мають свої переваги. Однак неправда, що відмінність є штучною. Існує безліч компромісів, які Скала мусила зробити, щоб підходити до OOP і FP (менш потужний висновок типу один. Складність - інше: так, мова, що змішує OOP і FP, як правило, є більш складною - як у "важкому у використанні і зрозумій "- ніж один із його чистіших братів на двох крайнощах).
Андрес Ф.

3
@Den Дивіться також "Програмування" здебільшого функціонального " Еріка Мейєра не працює" , що суперечить гібридному підходу та за те, що він буде повноцінним "фундаменталістським" ПП.
Андрес Ф.

4
@Den Популярність, яку ви описуєте, - це, боюся, випадковість історії. Я використовую Scala на роботі, і це складний звір через те, як він намагається змішати FP і OOP. Перехід на справжню мову FP, як Haskell, відчуває подих свіжого повітря - і я не говорю з академічної точки зору!
Андрес Ф.

3
@День я не можу сказати, що робить будь-яка з цих функцій. Однак я можу вам сказати, якби перша функція на FP була сортуванням чи фільтром, вона буде називатися фільтром чи сортуванням , а не func(точно так, як ви її назвали IFilterтощо). Загалом, у програмі FP ви її називатимете, funcабо fколи sortабо filterє правильним вибором! Наприклад, при написанні функції вищого порядку, яка приймається funcза параметр.
Андрес Ф.

10

Коли я брав свій клас Java років тому, від нас очікували показати свої рішення всьому класі, тому я мусив побачити, як думають люди; як вони логічно вирішують проблеми. Я повністю очікував, що рішення складатимуться навколо трьох-чотирьох загальних рішень. Натомість я спостерігав, як 30 студентів вирішували проблему 30 абсолютно різними способами.

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

Технічною мовою, яка лежить в основі функціонального програмування, є математика . Відповідно, проблеми, які найбільш підходять для вирішення за допомогою функціонального програмування, по суті є математичними проблемами. Під математикою я не маю на увазі таку математику, яку ви б бачили у бізнес-рішеннях, як додавання та віднімання. Я, скоріше, кажу про математику, яку ви можете бачити в Math Overflow, або про математику, яку ви бачили в пошуковій системі Orbitz (це написано в Lisp).

Ця орієнтація має деякі важливі наслідки для функціональних програмістів, які намагаються вирішити проблеми програмування в реальному світі:

  1. Функціональне програмування є більш декларативним, ніж імперативним; це стосується насамперед того, щоб сказати комп'ютеру, що робити, а не як це зробити.

  2. Об'єктно-орієнтовані програми часто будуються зверху вниз. Створюється дизайн класу, і деталі заповнюються. Функціональні програми часто будуються знизу вгору, починаючи з невеликих детальних функцій, об'єднаних у функції вищого рівня.

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

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

  5. Оскільки все практичне програмне забезпечення виробляє побічні ефекти (I / O), чисто функціональні мови програмування потребують механізму для створення цих побічних ефектів, залишаючись математично чистими (монадами).

  6. Функціональні програми можна легше перевірити, зважаючи на їх математичну природу. Система типу Haskell під час компіляції може знаходити речі, які більшість мов OO не може.

І так далі. Як і в багатьох випадках в обчислювальній техніці, об'єктно-орієнтовані мови та функціональні мови мають різні переваги.

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


6
@thepacker: у вас є стан функціонального програмування. Тільки представлення відрізняється: в OOP ви використовуєте змінні змінні, тоді як у функціональному програмуванні ви можете використовувати нескінченні потоки станів, які створюються на ходу, коли програмі потрібно їх перевірити. На жаль, стан часто ототожнюють із змінними змінними, як ніби змінні змінні є єдиним способом представлення стану. Як наслідок, багато хто вважає, що мова програмування без змінних змінних не може моделювати стан.
Джорджо

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

5
+1, але в пунктах 2 і 4. я не продаюсь. Я бачив багато навчальних посібників Haskell і публікацій в блогах, які починаються з вирішення проблеми зверху вниз, визначаючи всі типи та операції, щоб побачити, як це все підходить разом, залишаючи не визначеним значення кожного значення та функції (добре, визначене для викидання виключення). Мені здається, що програмісти Haskell схильні моделювати цю проблему більш ретельно, оскільки вони більш схильні додавати тривіальні типи заради семантики - наприклад, додавати SafeStringтип для представлення рядків, у яких відмовився від HTML - і, як правило, відслідковуючи більше ефекти.
Довал

4
"проблеми, які найбільш підходять для вирішення за допомогою функціонального програмування, по суті є математичними проблемами". Це просто неправда. Той факт, що поняття Монади походить від теорії категорій, також не означає, що математичні завдання є найбільш природним / придатним для функціональних мов доменом. Це означає, що код, написаний на сильно набраних функціональних мовах, може бути описаний, проаналізований та аргументований щодо використання математики. Це потужна додаткова функція, а не те, що перешкоджає вам писати "Пригоди Барбі Кінь" в Haskell.
йогобрюшина

6
@itsbruce Barbie Horse Adventures - це серйозне математичне моделювання вищого калібру, це підждон холінг FP в надмірно складні числові проекції, як матриці, що описують фізичне мерехтіння волосся Барбі протягом дискретного періоду в різних можливих умовах реального світу, які переконують людей повністю відхилити це як не має значення для кодування їх щоденних бізнес-проблем.
Джиммі Хоффа

7

Я хотів би наголосити на аспекті, який я вважаю важливим і який не висвітлювався в інших відповідях.

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

OOP і FP розглядають дані та операції з двох різних точок зору і забезпечують різні компроміси, як уже вказував Роберт Харві.

Одним з важливих аспектів, якими вони відрізняються, є спосіб, яким вони дозволяють розширити ваше програмне забезпечення.

Розглянемо ситуацію, в якій ти маєш колекцію типів даних і набір операцій, наприклад, ти маєш різні формати зображень і ти підтримуєш бібліотеку алгоритмів для обробки зображень.

Функціональне програмування полегшує додавання нових операцій у ваше програмне забезпечення: вам потрібна лише локальна зміна коду, а саме ви додаєте нову функцію, яка обробляє різні формати вхідних даних. З іншого боку, більше додає нові формати: вам потрібно змінити всі функції, які ви вже реалізували (не локальні зміни).

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

Цей різний підхід до розширення є однією з причин, чому OOP є більш підходящим для певних проблем, коли набір операцій змінюється рідше, ніж набір типів даних, над якими ці операції працюють. Типовим прикладом є ДПІ: у вас є фіксований набір операцій , які все віджети повинні реалізувати ( paint, resize, move, і т.д.) , і набір віджетів , які ви хочете розширити.

Отже, відповідно до цього виміру, OOP та FP - це лише два виразні способи організації вашого коду. Див. SICP , зокрема Розділ 2.4.3, Таблицю 2.22 та пункт Повідомлення, що передаються .

Підсумовуючи: в OOP ви використовуєте дані для організації операцій, у FP ви використовуєте операції для організації даних. Кожен підхід сильніший чи слабший відповідно до контексту. Загалом, жоден з двох не має вищого представницького розриву між проблемою та рішенням.


1
Насправді, шаблон відвідувачів (в OOP) дає вам таку ж силу, як ви сказали для FP. Це дозволяє додавати нові операції, роблячи додавання нових класів важче. Цікаво, чи можна це зробити на FP (наприклад, додавання нових форматів замість операцій).
Ейфорія

1
Сценарій обробки зображень не здається найкращим прикладом. Ви, звичайно, перетворили зображення в якийсь внутрішній формат і обробляєте, щоб замість того, щоб писати окремі реалізації всіх ваших матеріалів обробки зображень для кожного типу зображень?
Гей,

1
@Giorgio, можливо, я не отримую від цієї частини наміченого значення: "додавання нових форматів більше задіяне: вам потрібно змінити всі функції, які ви вже реалізували."
Ей,

2
@Hey Giorgio, ймовірно, посилається на так звану проблему вираження . "Додавання нових форматів" означає "додавання нових конструкторів (також" випадків ") до типу даних".
Андрес Ф.

1
@Euphoric: Я не розглядав деталі, але аналог FP для шаблону відвідувачів повинен містити Otherваріант / конструктор у вашому типі даних, а додатковий параметр функції, який слід передавати всім функціям для обробки іншого випадку. Звичайно, це незручно / менш природно щодо рішення OOP (динамічне відправлення). Таким же чином, шаблон відвідувачів незручний / менш природний, ніж рішення FP (функція вищого порядку).
Джорджіо

5

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

Спосіб роботи з цими типами в Haskell часто майже не відрізняється від способу OO. У Haskell кажу

  null xs
  length xs

а на Яві ви кажете

  xs.isEmpty
  xs.length

Помідор, помідор. Функції Haskell не прив’язані до об'єкта, але вони тісно пов'язані з його типом. "Ах, але , - ви кажете," в Java він називає, який метод будь-якої довжини є відповідним фактичному класу цього об'єкта ". Несподіванка - Хаскелл теж робить поліморфізм із класами типів (та іншими речами).

У Haskell, якщо у мене є - це сукупність цілих чисел - не має значення, чи є колекцією список чи набір чи масив, цей код

  fmap (* 2) is

поверне колекцію з усіма подвійними елементами. Поліморфізм означає, що відповідна карта буде викликана функція для конкретного типу.

Насправді ці приклади насправді не є складними типами, але те саме стосується і більш складних проблем. Думка про те, що функціональні мови не дозволяють моделювати складні об'єкти та пов'язувати з ними конкретну функціональність, просто неправильна.

Там є важливими і суттєвими відмінностями між функціональним і ГО стилі , але я не думаю , що ця відповідь має мати справу з ними. Ви запитали, чи функціональні мови перешкоджають (або перешкоджають) інтуїтивному моделюванню проблем та завдань. Відповідь - Ні.


По суті, ви можете використовувати класи типів у Java / C #; ви просто явно передаєте словник функцій, а не компілятор виводить правильний на основі типу.
Довал

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

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

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

4
@Fuhrmanator "Я не бачу, як це робиться на FP", тож ти скаржишся на те, що ти не розумієш, не має сенсу; перейдіть, вивчіть це, зрозумійте це ретельно, і тоді це матиме сенс. Можливо, після того, як це має сенс, ви вирішите, що це лайно, і вам не потрібні інші, щоб довести це вам, хоча інші люди, такі як вище, це розуміють і не прийшли до цього висновку. Ви, здається, принесли ніж до бою з гармати, і тепер ви всі говорите, що гармати марні, бо вони не гострі.
Джиммі Хоффа

4

ПП дійсно прагне скорочення представницького розриву:

Те, що ви бачите багато у функціональних мовах, - це практика побудови мови (за допомогою дизайну знизу вгору) у мову вбудованого домену (EDSL) . Це дає змогу розробити засоби висловлення проблем вашого бізнесу таким чином, що є природним для вашого домену в межах мови програмування. Хаскелл і Лісп пишаються цим.

Частина (якщо не все) того, що дозволяє цю здатність, - це більш гнучкість та виразність у межах самої основної мови; з функціями першого класу, функціями вищого порядку, складом функцій, а в деяких мовах - алгебраїчними типами даних (дискримінаційними союзами AKA) та можливістю визначати оператори *, є більше гнучкості для того, як виражати речі, ніж у OOP, який є означає, що ви, мабуть, знайдете більш природні способи висловити речі зі своєї проблемної області. (Слід сказати, що багато мов OOP останнім часом переймають багато цих функцій, якщо не починати з них.)

* Так, у багатьох мовах OOP ви можете перекрити стандартні оператори, але в Haskell ви можете визначити нові!

З мого досвіду роботи з функціональними мовами (переважно F # і Haskell, деякі Clojure, а також трохи Lisp та Erlang), я маю простіший час відображення проблемного простору вниз мовою, ніж у OOP - особливо з алгебраїчними типами даних, що я вважаю більш гнучким, ніж заняття. Щось, що підштовхувало мене до циклу, коли починався з FP, особливо з Haskell, - це те, що мені довелося думати / працювати на трохи вищому рівні, ніж я звик в імперативних мовах або мовах OOP; Ви, можливо, також в цьому зіткнетеся.


Занепокоєння бізнесу (від замовника) виражаються не дуже часто у функціях вищого порядку. Але клієнт може написати однолінійну історію користувача та надати вам ділові правила (або ви можете їх вийти з клієнта). Мене цікавить моделювання домену (зверху вниз?) (З тих артефактів), яке дозволяє нам дійти до абстракцій проблеми, яка відображає першокласні функції тощо. Чи можете ви навести деякі посилання? Чи можете ви використовувати конкретний приклад домену, абстракцій тощо?
Фурманатор

3
@Fuhrmanator Клієнт все ще може писати однорядкові історії користувачів та правила бізнесу незалежно від того, використовуєте ви OOP та FP . Я не сподіваюся, що клієнти зрозуміють функції вищого порядку більше, ніж я очікую, що вони зрозуміють спадкування, склад чи інтерфейси.
Андрес Ф.

1
@Fuhrmanator Як часто ви змушували клієнта висловлювати свої занепокоєння щодо дженерики або абстрактних базових класів та інтерфейсів? Боже милий. Пол дав вам дуже хорошу відповідь, пояснивши практичний та надійний метод моделювання за допомогою методик, які, безумовно, не надто складно уявити. І все ж ви наполягаєте на тому, щоб вона була описана в рамках однієї конкретної методики моделювання однієї конкретної парадигми, як ніби це якось найприродніший спосіб представити дизайн, і все інше можна переробити в його термінах.
йогобрюшина

@Fuhrmanator Це може бути не настільки високим рівнем, як ви шукаєте, але має дати деяке розуміння процесу проектування за допомогою функціональних методів: Проектування з типами . Я б рекомендував переглядати цей сайт взагалі, оскільки він має чудові статті.
Павло

@Fuhrmanator Там же це мислення Функціонально серія
Пол

3

Як заявив Ніклаус Вірт, "Алгоритми + структури даних = програми". Функціональне програмування - це спосіб організації алгоритмів, і воно не дуже багато розповідає про способи впорядкування структур даних. Дійсно, існують мови FP як із змінними (Lisp), так і з незмінними (Haskell, Erlang) змінними. Якщо ви хочете порівняти та порівняти FP з чимось, вам слід вибрати імперативне (C, Java) та декларативне (Prolog) програмування.

З іншого боку, OOP - це спосіб побудови структур даних та приєднання до них алгоритмів. FP не заважає будувати структури даних, подібні до OOP. Якщо ви мені не вірите, перегляньте декларації типу Haskell. Однак більшість мов FP погоджуються, що функції не належать до структур даних і повинні скоріше знаходитися в одному просторі імен. Це робиться для спрощення побудови нових алгоритмів за допомогою функції функції. Дійсно, якщо ви знаєте, який вхід приймає функція і який результат вона виробляє, чому це має мати значення, до якої структури даних вона теж належить? Наприклад, чому addфункція повинна викликатися в екземплярі типу Integer і передавати аргумент, а не просто передавати два аргументи Integer?

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


Через інкапсуляцію та приховування даних, які самі по собі не є принципами ОО, я не повністю згоден з тим, що ОО є структурами даних + алгоритмами (це лише внутрішній вигляд). Краса будь-якої хорошої абстракції полягає в тому, що є якась послуга, яку вона надає, щоб вирішити частину проблеми, не потрібно розуміти занадто багато деталей. Я думаю, ви говорите про капсуляцію, коли ви розділяєте функції та дані в FP, але я занадто зелений, щоб точно знати. Також я відредагував своє запитання, щоб віднести пошук від рішення назад до проблеми (щоб уточнити значення представницького розриву).
Фурманатор

if you know what input a function takes and what output it produces, why should it matter which data structure it belongs too?Це дуже схоже на згуртованість, що важливо для будь-якої модульної системи. Я б заперечував, що невідомо де знайти функцію, це ускладнить розуміння рішення, що пояснюється більшим представницьким розривом. Багато систем OO мають цю проблему, але це через поганий дизайн (низька згуртованість). Знову ж таки, питання простору імен не вдається мені в галузі FP, тому, можливо, це не так погано, як це звучить.
Фурманатор

1
@Fuhrmanator Але ви ж знаєте , де знайти таку функцію. І є лише одна функція, а не кілька функцій з тим самим іменем, визначена для кожного типу даних (ще раз див. "Проблема з виразами"). Наприклад, для функцій бібліотеки Haskell (які вам рекомендується використовувати, замість того, щоб знову відкрити колесо або зробити трохи менш корисні версії зазначених функцій), у вас є чудові інструменти відкриття, такі як Hoogle , який настільки потужний, що дозволяє вам шукати за підписом (спробуйте! :))
Андрес Ф.

1
@Fuhrmanator, після "Це дуже схоже на згуртованість", я б очікував, що ти логічно зробиш висновок, що мови FP дозволяють писати програми з більшою згуртованістю, але ти мене пережив. :-) Я думаю, ви повинні вибрати мову FP, вивчити її та вирішити для себе. Якби я був ти, я б запропонував почати з Haskell, оскільки він досить чистий і тому не дозволить писати код в імперативному стилі. Ерланг і деякі Лісп - також хороший вибір, але вони змішуються в інших стилях програмування. Scala і Clojure, IMO, починаються досить складно.
mkalkov
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.