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


17

Протягом усього минулого року мені писали код Scala (походить з фону Java). Мені дуже сподобалось, як можна створити простіший і чистіший код, використовуючи вали, класи регістрів, функції карти / фільтра / лямбда, імпліцити та умови виводу. Я використовував його здебільшого для програми на базі Akka .

Цього року я працюю над проектом Scala з новою командою, яка дуже любить функціональне програмування. Вони активно використовують Scalaz , і код скрізь заповнений додатками, контекстними межами, читачем / автором / монадою держави, навіть основний метод "загорнутий" у монаду вводу / виводу. Їх міркування полягають у тому, що це змушує компілятор "працювати на нас", стверджуючи, що код правильний, і кожна функція не має побічних ефектів.

Незважаючи на це, з моєї точки зору, весь цей синтаксис дійсно перешкоджає діловій логіці. Наприклад, тип "MyBusinessObject" є прекрасним, а також такі типи, як "Список [MyBusinessObject]", "Option [MyBusinessObject]" або навіть "Future [MyBusinessObject]". Всі вони мають чітке значення та призначення. З іншого боку, код:

def method[M[_]: Applicative] = {
  case (a, b) => (ca[M](a) |@| cb[M](b)) {
    case t @ (ra, rb) =>
      if (ra.result && rb.result) t.right
      else t.left
  }
}

чи додає це складності програмі, чи просто я не звик до такого способу програмування?


6
Яке ваше об'єктивно відповідне запитання?
Мисливець на оленів

1
Схоже, це призводить до тонни коду з однією або двома літерами імен змінних. Виглядає трохи як APL. Це не є доповненням.
user949300

3
Я почав грати з Haskell минулого року. Це виглядало неймовірно складно в той час, коли я не розумів таких понять, як каррінг, функтори, монади тощо. Haskell схожий на Scalaz тим, що він має безліч коротких, символічних функцій, як >>=і <$>, що нічого не означають, поки ви знати, що вони роблять. Дізнавшись, що вони означають, вони читають мені дуже природно і швидко. Насправді не відповідь, просто мій об’єктивний досвід з подібними речами. Я також користуюся Scala, але не маю досвіду роботи з бібліотекою Scalaz.
KChaloux

3
Вам просто незнайомі ідіоми. @ user949300 короткі змінні насправді не є проблемою для багатьох функціональних кодів (подумайте про конвенції стилю Math!). Також прочитайте блог Тоні Морріса для більш глибокого обговорення того, що краще передає значення, типи чи багатослівні назви змінних.
Андрес Ф.

3
@ user949300: короткі імена змінних віддають перевагу локально, це те саме у функціональному та імперативному світі (ви б не писали for(i=0; i<7; ++i) { trivialOperation(i); }з якоюсь незграбною trivialOperationCountзмінною, чи не так?) Тепер функціональні мови програмування із узгодженням шаблону іноді вводять ще кілька змінних, де ви просто виписати дзвінки методу аксесуара в ОО. Результат, як правило, більш стислий; можливо трохи менше пояснення, але пошук декларації даних зазвичай дає зрозуміти це швидко. Статичний набір тексту дуже допомагає, це не так, як в APL.
близько

Відповіді:


37

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

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


7
Це також має багато спільного з громадою. Для розробника з фоном Java або C # код ледь зрозумілий (і його / її спільнота теж не зрозуміє цього). Але якщо ви пишете Haskell, наприклад, і не використовуєте монади, додатки, функтори тощо, ви збиваєте з цієї мови спільноту. "Природність" коду не притаманна, а відносно її спільності та усталеної практики.
Андрес Ф.

1
Це важко помітити, тому що більшість із нас походить із загальнообов’язкового походження, що іноді змушує нас робити неправильні припущення щодо природного.
Андрес Ф.

просто подивіться на бібліотеку SLT C ++, яка могла б бути настільки читаючою для аматора
щурячий вирод

@ratchetfreak: Я думаю, ти маєш на увазі STL. Я думаю, що це дуже хороший приклад (і справді я це мав на увазі у своїй відповіді). Використання мета-програмування шаблонів має багато сенсу, коли ви програміст STL, оскільки це робить STL більш багаторазовим. І люди, які мають підтримувати цей код, зазвичай також використовуються для метапрограмування шаблонів. Використання метапрограмування шаблонів таким чином, як STL, у вашому стандартному бізнес-додатку може легко призвести до надскладного, важкого для підтримки коду. Напевно, можна зустріти (рідкісні) випадки, коли TMP чудово працює навіть у діловому застосуванні.
Док Браун

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

7

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

Щодо того, чи додає цей конкретний код складність програмі - я не знаю. Домовились, що загальний фрагмент коду може бути складним сам по собі. Але це утиліта, а не частина логіки бізнесу. Якщо ви хочете знати, чи робить це базу коду більш складною чи простою, вам доведеться уявити, як вона повинна виглядати без цього фрагмента коду. Часто буває з такими загальними конструкціями, що вони самі складні, але це складність, яку можна помістити на одному екрані. У той же час вони роблять всю кодову базу трохи простішою. Особливо це стосується монад.

Знову ж таки, це також може бути випадком "мистецтва заради мистецтва", як пропонує @Doc Brown. Не можу це виключити.


5

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

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

Також Скалаз був написаний людьми, які довго їли та дихали FP; вони хотіли донести до Scala функціонал, доступний в Haskell. Роблячи це, вони не намагалися бути педагогічними. Скалаз використовує лексику та стиль, які видаються авторам чіткими та відвертими, але чужі для непосвячених. Методи, які викликають спантеличення для решти нас, авторам здавались настільки очевидними, враховуючи їхній досвід Haskell, що вони навіть не вимагали коментарів.

Крім того, Scala, як функціональна мова програмування, має деякі недоліки (частково через те, що у JVM є недоліки), що змусило авторів Scalaz писати гірші коди в деяких випадках. Наприклад, відсутність загального усунення хвостових викликів змушує використовувати батути в деякому коді, а відсутність "доброї системи" може ускладнити підписи типів.

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

Тримайся там. І це може допомогти.


-4

Чи додає це складності програмі, чи просто ви не звикли до такого способу програмування?

Чому, на вашу думку, ці можливості не одне й те саме?

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

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


11
Це просто не вірно:"Well written code can be read by people who aren't familiar with the specific programming language."
Андрес Ф.

@Andres: Це правда ... до точки. Добре написаний код відокремлює бізнес-логіку від деталей впровадження, а бізнес-логіка повинна бути читабельною, тому що більшість того, що вона робить, - це прямі виклики добре названих помічницьких функцій. Ці помічники, звичайно, можуть використовувати всі види мовних функцій, і для розуміння потрібен великий досвід роботи з мовою та бібліотеками.
Ben Voigt

4
Я вважаю , що наступний ідіоматічен APL: x[⍋x←6?40]. Як ви думаєте, що це робить? Я точно не знав би…
bdesham

3
@Brendan Тільки в межах тієї ж парадигми (і навіть тоді, іноді ні). Наприклад, Prolog, Java та APL настільки різні, що я можу стверджувати, що якщо ви знаєте лише одну з цих (і жодної іншої мови), ви не можете прочитати інші дві, незалежно від того, наскільки добре ви знаєте першу. (Серйозно, на прикладі бдешама, як дияволу ви повинні інтерпретувати "ялинку", якщо ви не знаєте жодної APL?)
Ізката

1
Брендане, ваше визначення добре написаного - це нестандартне. Добре написане завжди відносно мови та її спільноти. Програма мовою X добре написана, якщо вона не баггі, вона ефективна і зрозуміла ... для даної аудиторії! Це стосується писемності загалом, до речі: завжди знайте свою аудиторію. Те, що підходить для (скажімо) наукової роботи, ймовірно, не підходить для електронного листа вашій мамі.
Андрес Ф.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.