Czy istnieje metodologia programowania funkcyjnego? [zamknięte]

Inżynieria oprogramowania, której się dzisiaj uczy, skupia się całkowicie na programowaniu obiektowym i "naturalnym" obiektowym spojrzeniu na świat. Istnieje szczegółowa metodologia, która opisuje, jak przekształcić model domeny w model klasy z kilkoma krokami i wieloma artefaktami (UML), takimi jak diagramy przypadków użycia lub diagramy klas. Wielu programistów zinternalizowało to podejście i ma dobry pomysł na to, jak zaprojektować aplikację obiektową od podstaw.

Nowy hype to programowanie funkcjonalne, którego uczy się w wielu książkach i samouczkach. Ale co z funkcjonalną inżynierią oprogramowania? Czytając o Lispie i Clojure, doszedłem do dwóch ciekawych stwierdzeń:

  1. Programy funkcjonalne są często rozwijane od dołu do góry zamiast od góry do dołu ('on Lisp', Paul Graham)

  2. Programiści funkcyjni używają map, gdzie oo-programiści używają obiektów/klas ("Clojure for Java Programmers", talk by Rich Hickley).

Więc jaka jest metodologia systematyczna (oparta na modelu ?) zaprojektowanie aplikacji funkcjonalnej, np. w Lispie czy Clojure? Jakie są wspólne kroki, jakich artefaktów używam, jak mapować je z przestrzeni problemu do przestrzeni rozwiązania?

Author: Thorsten, 2011-01-31

13 answers

Dzięki Bogu, że inżynierowie oprogramowania nie odkryli jeszcze programowania funkcyjnego. Oto kilka podobieństw:

  • Wiele oo "wzorców projektowych" jest przechwytywanych jako funkcje wyższego rzędu. Na przykład, wzór odwiedzającego jest znany w świecie funkcjonalnym jako "fałd" (lub jeśli jesteś spiczastym teoretykiem, "katamorfizm"). W językach funkcyjnych typy danych to głównie drzewa lub krotki, a każdy typ drzewa ma z tym związany naturalny katamorfizm.

    Te funkcje wyższego rzędu często posiadają pewne prawa programowania, zwane "wolnymi twierdzeniami".

  • Programiści funkcyjni używają diagramów znacznie mniej niż Programiści OO. Większość tego, co jest wyrażane na diagramach OO, jest zamiast tego wyrażana w typach , lub w "signatures", które należy traktować jako"typy modułów". Haskell ma również "klasy typu", które jest trochę jak typ interfejsu.

    Ci funkcjonalni programiści, którzy używają typów, generalnie myślą że " po poprawnym dobraniu typów, kod praktycznie sam się pisze."

    Nie wszystkie języki funkcjonalne używają jawnych typów, ale książka jak projektować programy, doskonała książka do nauki Scheme/Lisp/Clojure, opiera się w dużej mierze na" opisach danych", które są ściśle związane z typami.

Więc jaka jest metodologia systematyczna (oparta na modelu?) zaprojektowanie aplikacji funkcjonalnej, np. w Lispie czy Clojure?

Dowolna metoda projektowania na podstawie abstrakcji danych działa dobrze. Zdarza mi się myśleć, że jest to łatwiejsze, gdy język ma wyraźne typy, ale działa nawet bez. Dobrą książką o metodach projektowania abstrakcyjnych typów danych, która jest łatwo dostosowana do programowania funkcyjnego, jest Abstraction and Specification in Program Development autorstwa Barbary Liskow i Johna Guttaga, the first edition. Za tę pracę liskow otrzymał nagrodę Turinga.

Kolejna metodologia projektowania, która jest unikalna w Lispie jest zdecydować, jakie rozszerzenia językowe będą przydatne w problemowej domenie, w której pracujesz, a następnie użyć higienicznych makr, aby dodać te konstrukcje do języka. Dobrym miejscem do poczytania o tego typu projektach jest artykuł Matthew Flatta Tworzenie języków w Racket. Artykuł może być za paywall. Można również znaleźć bardziej ogólne materiały na temat tego rodzaju projektowania, szukając terminu "język wbudowany specyficzny dla domeny"; dla konkretnych porad i przykłady poza tym, co obejmuje Matthew Flatt, prawdopodobnie zacznę od Grahama na Lispie a może ANSI Common Lisp.

Jakie są wspólne kroki, jakich artefaktów używać?

Wspólne kroki:

  1. Zidentyfikuj dane w programie i operacje na nim oraz zdefiniuj abstrakcyjny typ danych reprezentujący te dane.

  2. Identyfikować wspólne działania lub wzorce obliczeń i wyrażać je jako funkcje wyższego rzędu lub makra. Spodziewaj się zrobić ten krok w ramach refaktoryzacji.

  3. Jeśli używasz wpisanego języka funkcyjnego, używaj go wcześnie i często. Jeśli używasz Lispu lub Clojure, najlepszą praktyką jest najpierw pisanie kontraktów funkcyjnych, w tym testów jednostkowych-jest to rozwój oparty na testach na maksa. I będziesz chciał użyć dowolnej wersji QuickCheck został przeniesiony na platformę, która w Twoim przypadku wygląda jak to się nazywa ClojureCheck . Jest to niezwykle potężna biblioteka do konstruowania losowych testów kodu wykorzystująca funkcje wyższego rzędu.

 158
Author: Norman Ramsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-16 06:04:37

Dla Clojure, polecam wrócić do starego dobrego modelowania relacyjnego. Out of the Tarpit to inspirująca lektura.

 43
Author: cgrand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-19 10:36:30

Osobiście uważam, że wszystkie zwykłe dobre praktyki z rozwoju OO mają zastosowanie również w programowaniu funkcyjnym - tylko z kilkoma drobnymi poprawkami, aby wziąć pod uwagę funkcjonalny światopogląd. Z punktu widzenia metodologii nie musisz robić niczego zasadniczo innego.

Moje doświadczenie wynika z przejścia z Javy do Clojure w ostatnich latach.

Niektóre przykłady:

  • Zrozumieć swoją domenę biznesową / model danych - równie ważne, czy projektujesz model obiektowy, czy tworzysz funkcjonalną strukturę danych z zagnieżdżonymi mapami. Pod pewnymi względami FP może być łatwiejsze, ponieważ zachęca do myślenia o modelu danych oddzielnie od funkcji / procesów, ale nadal musisz robić oba.

  • Orientacja usługi w projektowaniu - w rzeczywistości działa bardzo dobrze z perspektywy FP, ponieważ typowa usługa jest tak naprawdę tylko Funkcją z pewnymi efektami ubocznymi. Myślę, że "oddolny" widok oprogramowania rozwój czasami w świecie Lispu to w rzeczywistości tylko dobre zasady projektowania API zorientowanych na usługi w innym przebraniu.

  • Test Driven Development - działa dobrze w językach FP, w rzeczywistości czasami nawet lepiej, ponieważ czyste funkcje nadają się bardzo dobrze do pisania jasnych, powtarzalnych testów bez potrzeby konfigurowania stanowego środowiska. Możesz również zbudować oddzielne testy, aby sprawdzić integralność danych (np. czy ta mapa ma wszystkie klucze w spodziewam się, aby zrównoważyć fakt, że w języku OO definicja klasy wymusiłaby to dla Ciebie w czasie kompilacji).

  • Prototyng / iteracja - działa równie dobrze z FP. Możesz nawet być w stanie prototypować na żywo z użytkownikami, jeśli będziesz bardzo bardzo dobry w budowaniu narzędzi / DSL i używaniu ich w REPL.

 38
Author: mikera,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-31 15:27:02

Oo programowanie ściśle łączy dane z zachowaniem. Programowanie funkcyjne oddziela te dwa elementy. Więc nie masz diagramów klas, ale masz struktury danych, a szczególnie algebraiczne typy danych. Te typy mogą być pisane tak, aby bardzo ściśle pasowały do Twojej domeny, w tym eliminując niemożliwe wartości przez konstrukcję.

Więc nie ma książek i książek na ten temat, ale istnieje ugruntowane podejście do, jak to się mówi, niemożliwych wartości nie do reprezentowania.

W ten sposób można dokonać szeregu wyborów dotyczących reprezentowania pewnych typów danych jako funkcji zamiast, i odwrotnie, reprezentowania pewnych funkcji jako związku typów danych zamiast tak, że można uzyskać, na przykład, serializacji, ściślejszej specyfikacji, optymalizacji, itp.

Następnie, biorąc pod uwagę to, piszesz funkcje nad swoimi adts tak, że ustanawiasz jakiś rodzaj algebry - tzn. istnieją stałe prawa, które utrzymują te funkcje. Niektóre są może idempotent -- to samo po wielu aplikacjach. Niektóre są asocjacyjne. Niektóre są przechodnie itp.

Teraz masz domenę, na której masz funkcje, które komponują się zgodnie z dobrze zachowanymi prawami. Prosty wbudowany DSL!

Oh, a biorąc pod uwagę właściwości, można oczywiście napisać automatyczne testy randomizowane z nich (Ala QuickCheck).. a to dopiero początek.

 13
Author: sclv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 01:25:05

Projektowanie obiektowe to nie to samo co Inżynieria oprogramowania. Inżynieria oprogramowania ma związek z całym procesem przechodzenia od wymagań do działającego systemu, na czas i z niskim wskaźnikiem defektów. Programowanie funkcjonalne może różnić się od OO, ale nie pozbawia się wymagań, wysokiego poziomu i szczegółowych projektów, weryfikacji i testowania, wskaźników oprogramowania, estymacji i innych "rzeczy inżynierii oprogramowania".

Ponadto programy funkcjonalne do wykazują modułowość i inną strukturę. Twoje szczegółowe projekty muszą być wyrażone w kategoriach pojęć w tej strukturze.

 7
Author: Kaz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-02 21:22:03

Zobacz moją odpowiedź na inny post:

Jak Clojure radzi sobie z rozdzieleniem trosk?

Zgadzam się, że więcej trzeba napisać na ten temat, jak tworzyć struktury dużych aplikacji, które używają podejścia FP (Plus więcej trzeba zrobić, aby udokumentować interfejs użytkownika oparty na FP)

 5
Author: drcode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:55:04

Jednym z rozwiązań jest stworzenie wewnętrznego DSL w wybranym języku programowania funkcyjnego. "Model" jest więc zbiorem reguł biznesowych wyrażonych w DSL.

 4
Author: James Kingsbery,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-31 15:06:18

Chociaż można to uznać za naiwne i uproszczone, myślę ,że "przepisy projektowe" (systematyczne podejście do rozwiązywania problemów stosowane do programowania, jak zalecany przez Felleisen et al. w ich książce HtDP) byłoby blisko tego, czego wydaje się szukać.

Tutaj kilka linków:

Http://www.northeastern.edu/magazine/0301/programming.html

Http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.86.8371

 3
Author: Artyom Shalkhakov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-01 16:46:49

Szczerze mówiąc, jeśli chcesz projektować przepisy dla programów funkcjonalnych, spójrz na standardowe biblioteki funkcji, takie jak Haskell ' s Prelude. W FP wzorce są zwykle przechwytywane przez procedury wyższego rzędu (funkcje, które działają na funkcjach). Więc jeśli wzorzec jest widoczny, często funkcja wyższego rzędu jest po prostu utworzona, aby uchwycić ten wzorzec.

Dobrym przykładem jest fmap. Funkcja ta przyjmuje funkcję jako argument i stosuje ją do wszystkich "elementów" drugiego argumentu. Ponieważ jest częścią klasy typu Functor, każda instancja Functora (np. lista, Wykres, itd...) może być przekazany jako drugi argument do tej funkcji. Przechwytuje ogólne zachowanie stosowania funkcji do każdego elementu jego drugiego argumentu.

 1
Author: nightski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-06 17:09:19

Istnieje styl "program calculation" / "design by calculation" związany z prof. Richardem Birdem i grupą Algebra of Programming na Uniwersytecie w Oksfordzie( Wielka Brytania), nie sądzę, aby było to zbyt naciągane, aby uznać to za metodologię.

Osobiście choć lubię prace wykonane przez grupę AoP, nie mam dyscypliny, aby ćwiczyć w ten sposób projektowanie. To jednak moja wada, a nie kalkulacja programu.

 1
Author: stephen tetley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-06 17:50:15

Uważam, że Behavior Driven Development jest naturalnym odpowiednikiem szybko rozwijającego się kodu zarówno w Clojure, jak i SBCL. Prawdziwą zaletą wykorzystania BDD z językiem funkcjonalnym jest to, że mam tendencję do pisania znacznie drobniejszych testów jednostkowych ziarna niż zwykle, gdy używam języków proceduralnych, ponieważ wykonuję znacznie lepszą pracę rozkładu problemu na mniejsze kawałki funkcjonalności.

 1
Author: Marc,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-19 01:02:33

Niedawno znalazłem tę książkę: Modelowanie domen funkcjonalnych i reaktywnych

Myślę, że idealnie pasuje do twojego pytania.

Z opisu książki:

Funkcjonalne i reaktywne Modelowanie domeny uczy, jak myśleć o modelu domeny w kategoriach czystych funkcji i jak komponować je, aby budować większe abstrakcje. Zaczniesz od podstaw programowania funkcyjnego i stopniowo przejdziesz do zaawansowanych koncepcji i wzorców, które trzeba wiedzieć, aby wdrożyć złożone modele domen. Książka pokazuje, w jaki sposób zaawansowane wzorce FP, takie jak algebraiczne typy danych, projektowanie oparte na typeklasie i izolacja efektów ubocznych, mogą sprawić, że twój model skomponuje się pod kątem czytelności i weryfikowalności.

 1
Author: elviejo79,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-04 17:11:19

Cóż,

Ogólnie wiele funkcjonalnych języków programowania jest używanych na uniwersytetach przez długi czas do "małych problemów z zabawkami".

Stają się coraz bardziej popularne, ponieważ OOP ma trudności z " programowaniem równoległym "z powodu"stanu".A czasami funkcjonalny styl jest lepszy dla problemu pod ręką, takiego jak Google MapReduce.

Jestem pewien, że kiedy faceci functioanl uderzą w ścianę [spróbuj zaimplementować systemy większe niż 1.000.000 linii kodu], część z nich przyjdzie z nowymi metodologie inżynierii oprogramowania z buzz słowa :-). Powinny one odpowiedzieć na Stare pytanie: jak podzielić system na kawałki, tak, że możemy "gryźć" każdy kawałek po kolei? [praca iteracyjna, inceremental en ewolucyjny sposób] za pomocą stylu funkcjonalnego.

Jest pewne, że styl funkcjonalny wpłynie na nasze zorientowane obiektowo Styl.Mamy "jeszcze" wiele koncepcji z systemów funkcjonalnych i dostosowane do nasze języki OOP.

Ale czy funkcjonalne programy będą wykorzystywane do taki wielki system?Czy staną się głównym strumieniem? Oto jest pytanie .

I nikt nie może przyjść z realistyczną metodologią bez wdrożenia tak wielkiego systemu, brudząc sobie ręce. Najpierw powinieneś ubrudzić ręce, a następnie zasugerować rozwiązanie. Rozwiązania-sugestie bez "prawdziwych bólów i brudu "będą " fantazją".

 -6
Author: Hippias Minor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-03 06:23:43