Свою відповідь я пишу в основному, маючи на увазі Haskell, хоча багато понять однаково добре застосовуються до інших функціональних мов, таких як Erlang, Lisp (s) та ML. Деякі навіть застосовуються (певною мірою) до Ruby, Python, Perl та Javascript.
Як люди пишуть функціональні програми? Як вони починаються?
За допомогою написання функцій. Коли ви займаєтесь функціональним програмуванням, ви або пишете main
, або ви пишете функцію помічника. Іноді вашою основною метою може бути написання типу даних з різними відповідними функціями, які працюють на ньому.
Функціональне програмування дуже добре підходить як для підходів зверху вниз, так і знизу вгору. Haskell наполегливо рекомендує писати програми на мові високого рівня, а потім просто визначати деталі вашого дизайну високого рівня. Див. minimum
, Наприклад:
minimum :: (Ord a) => [a] -> a
minimum xs = foldl1 min xs
Функція пошуку найменшого елемента в списку записується просто як проходження списку, використовуючи функцію min для порівняння кожного елемента з "акумулятором" або поточним мінімальним значенням.
Чи існують шаблони дизайну функціональних мов?
Є дві речі, які можна прирівняти до "моделей дизайну", imho, функцій вищого порядку і монадам . Поговоримо про колишнє. Функції вищого порядку - це функції, які або приймають інші функції як вхідні, або виробляють функції як вихідні. Будь-функціональна мова зазвичай робить інтенсивне використання map
, filter
іfold
(складку часто також називають "зменшити"): три дуже основних функції вищого порядку, які застосовують функцію до списку різними способами. Вони красиво замінюють котельну плиту для петель. Передача функцій навколо як параметрів - надзвичайно потужна перевага програмуванню; безліч "моделей дизайну" можна зробити простішими, використовуючи функції вищого порядку, вміючи створювати свої власні та мати можливість використовувати потужну стандартну бібліотеку, яка сповнена корисних функцій.
Монади - це «страшніша» тема. Але вони насправді не такі страшні. Мій улюблений спосіб подумати над монадами - це думати про них як обволікання функції в міхурі та надання їй функції надсил (які працюють лише всередині міхура). Я міг би пояснити, але світ не потребує ще однієї аналогії монади. Тож перейду до швидких прикладів. Припустимо, я хочу використовувати недетерміновану "схему дизайну". Я хочу запустити однакові обчислення для різних вхідних даних одночасно. Я не хочу вибирати лише один вхід, я хочу вибрати їх усі. Це був би список монад:
allPlus2 :: [Int] -> [Int]
allPlus2 xs = do x <- xs
return (x + 2)
Тепер ідіоматичний спосіб зробити це насправді map
, але задля ілюстрації, чи бачите ви, як монада списку дозволила мені написати функцію, схожу на те, що вона працює на одне значення, але наділила її надсилою для роботи над кожним елементом у список? До інших наддержав належать відмова, стан, взаємодія із «зовнішнім світом» та паралельне виконання. Ці наддержави дуже потужні, і більшість мов програмування дозволяють функціям з надпотужними силами розгулювати все навколо. Більшість людей кажуть, що Haskell взагалі не дозволяє цим супердержавам, але насправді Haskell просто містить їх у монадах, щоб їх вплив можна було обмежити та спостерігати.
tl; dr Grokking функції вищого порядку і монади - це еквівалент Haskell, що відповідає моделям дизайну grokking. Після того, як ви засвоїте ці поняття Haskell, ви почнете думати, що «дизайнерські шаблони» - це здебільшого дешеві шляхи вирішення, що імітують силу Haskell.
Чи застосовуються методології, як екстремальне програмування, або гнучка розробка для функціональних мов?
Я не бачу нічого, що зв'язує ці стратегії управління з будь-якою парадигмою програмування. Як зазначає фінфо, функціональне програмування практично змушує вас робити функцію декомпозиції, розбиваючи велику проблему на підпроблеми, тому міні-віхи повинні бути шматочком пирога. Є такі інструменти, як QuickCheck і Zeno, щоб перевірити або навіть довести властивості щодо функцій, які ви пишете.