Jako programista Java / C # / C ++ dużo słyszę o językach funkcjonalnych, ale nigdy nie musiałem się ich uczyć. Słyszałem również, że wyższy poziom myślenia wprowadzony w językach funkcjonalnych sprawia, że jesteś lepszym programistą języka OOP / języka proceduralnego.
Czy ktoś może to potwierdzić? W jaki sposób poprawia twoje umiejętności programowania?
Jaki jest dobry wybór języka do nauki w celu poprawy umiejętności w mniej zaawansowanym języku?
Odpowiedzi:
I w zasadzie zgadzają się z odpowiedzią FrustratedWithFormsDesign za , ale poprosił także, jak uczenie się nowego paradygmatu pomaga rozwijać swoich umiejętności. Mogę podać kilka przykładów z własnego doświadczenia.
Od czasu nauki programowania funkcjonalnego jestem znacznie bardziej świadomy, z którymi pojęciami pracuję bardziej naturalnie uważanymi za „obiekty” (ogólnie tam, gdzie mutacja ma sens), a które z natury są uważane za niezmienne „wartości” (myślę, że istnieje ważne rozróżnienie , dotykając, gdzie OO ma sens, a kiedy FP ma sens, ale to tylko moja opinia).
Zauważyłem, gdzie mój kod zawiera efekty uboczne, i staram się izolować te miejsca, czyniąc więcej moich funkcji „czystymi” funkcjami. To znacznie poprawia testowalność mojego kodu OO.
Jestem bardziej świadomy cykli w mojej reprezentacji danych. (Na przykład nie sądzę, że można napisać funkcję konwersji listy połączonej na listę podwójnie połączoną w Haskell, więc zauważasz cykle znacznie więcej w tym języku). Unikanie cykli zmniejsza ilość synchronizacji musisz wykonać, aby struktury danych były wewnętrznie spójne, zmniejszając obciążenie związane z udostępnianiem tych struktur między wątkami.
Bardziej prawdopodobne jest, że będę polegać na rekurencji (rekurencyjne konstrukcje zapętlające schematu to rzeczy piękne). Dijkstra poruszył tę kwestię w uwagach na temat programowania strukturalnego - algorytmy rekurencyjne odwzorowują bardzo bezpośrednio indukcję matematyczną, co, jak sugeruje, jest jedynym sposobem intelektualnego udowodnienia poprawności naszych pętli. (Nie sugeruję, że musimy udowodnić, że nasz kod jest poprawny, ale że im łatwiej nam to zrobić, tym bardziej prawdopodobne jest, że nasz kod jest poprawny.)
Bardziej prawdopodobne jest, że użyję funkcji wyższego rzędu. Artykuł Johna Hughesa, Dlaczego programowanie funkcjonalne ma znaczenie . Podkreśla kompozycyjność uzyskaną dzięki zastosowaniu funkcjonalnych technik programowania, przy czym funkcje wyższego rzędu odgrywają ważną rolę.
Ponadto, jak poruszono w odpowiedzi Jettiego , przekonasz się, że wiele pomysłów na FP jest włączanych do nowszych języków OO. Zarówno Ruby, jak i Python zapewniają wiele funkcji wyższego rzędu, słyszałem LINQ opisany jako próba wprowadzenia obsługi rozumień monadycznych do C #, nawet C ++ ma teraz wyrażenia lambda.
źródło
1 + 2
jest matematycznie równoważny2 + 1
, ale1.+(2)
jest implementowany inaczej niż2.+(1)
. Istnieje wiele problemów z oprogramowaniem SW, które można zrozumieć bardziej naturalnie przy użyciu operacji niż przy użyciu interfejsów obiektowych.Nie powiedziałbym, że z pewnością sprawi, że staniesz się lepszym programistą OOP, ale wprowadzi cię w nowy sposób myślenia, a to może sprawić, że będziesz lepiej w rozwiązywaniu problemów w ogóle, nie tylko w zakresie OOP.
źródło
Nauka języka funkcjonalnego - dla mnie Lisp - naprawdę pomaga w budowaniu aplikacji równoległych. Metody funkcjonalne (oparte na stanie, bez skutków ubocznych) są znacznie łatwiejsze do synchronizacji i łatwiej jest zabezpieczyć wątek, ponieważ zależą tylko od ich wkładu. Oznacza to, że jedynymi danymi, które należy obserwować dla danego obszaru kodu, są przekazywane parametry. Ułatwia to także debugowanie.
źródło
Thread
przedmioty są ... niezdarne.Nauka jakiegokolwiek innego paradygmatu programowania poprawi Twoje umiejętności programistyczne w ogóle. Programowanie, gdy nie jest to materiał naukowy (a nawet często), jest w zasadzie rozwiązywaniem problemów. Jednym słowem myślenie. Różne paradygmaty to różne sposoby myślenia o problemach i ich rozwiązaniach. Nie myśl więc o tym jako o „nauce języka funkcjonalnego”. Pomyśl o tym jako o „uczeniu się innego sposobu myślenia o problemach i ich rozwiązaniach”. Wtedy zobaczysz zalety nauki języka, nawet jeśli nigdy go nie używasz.
Aby odpowiedzieć na twoje konkretne pytanie, byłem programistą C ++ w dawnych czasach (wcześniej był standard dla C ++). Śledziłem wszystkie zwykłe rzeczy z obiektami utrzymującymi stan zmanipulowanymi metodami itp. Itd. Potem natknąłem się na Haskella i nauczyłem się (wiele) tego. (Nie sądzę, żeby ktokolwiek naprawdę się uczył Haskella.) Ćwiczenie wydawało się wtedy trochę zmarnowane, dopóki jeden z moich kolegów, tester przydzielony do mojej grupy, nie skomentował, że mój kod staje się łatwiejszy do przetestowania.
Stało się tak, że zacząłem sprawiać, by moje przedmioty stawały się coraz bardziej niezmienne. Klasy ze złożonym stanem zmiennym zaczęły być zastępowane klasami, które klonowały się ze zmianami, zwracając nowe obiekty. Obiekty współdzielone zaczęły być zastępowane obiektami, które miały semantykę kopiowania przy zapisie (dając iluzję wielu klonów obiektów bez narzutu pamięci). Funkcje nie wywoływały żadnych skutków ubocznych, chyba że absolutnie konieczne; czysta, matematyczna definicja „funkcji” była coraz bardziej normą. Wszystko to zaczęło się dziać naturalnie w moim kodzie - bez udziału świadomej myśli - gdy badałem coraz więcej funkcjonalnej przestrzeni programistycznej.
Teraz moim celem jest nauczenie się co najmniej jednego nowego paradygmatu programistycznego co dwa lata (nawet jeśli jest to tylko niewielki paradygmat rozszerzenia, taki jak AOP) i co najmniej dwóch nowych języków w ramach każdego paradygmatu (jeden tak czysty, jak to możliwe, jeszcze jeden hybrydowy / praktyczny ). Każdy z nich dał mi nowe narzędzia intelektualne do zastosowania w całym moim programowaniu w dowolnym języku, więc moim zdaniem czas poświęcony na ich naukę nie został nawet trochę zmarnowany.
źródło
Powiedziałem to wcześniej i powiem to jeszcze raz, nauka języków funkcjonalnych zdecydowanie poprawiła mój C #. Pomogło mi zrozumieć lambdas (i pomogło mi je pokochać). Uświadomiłem sobie również, jak bardzo wolę programowanie funkcjonalne (F #) podczas pracy z operacjami asynchronicznymi!
źródło
Kod maszynowy to nic innego jak lista efektów ubocznych - poleceń wykonywanych bezpośrednio przez procesor. Efekty uboczne w C są różne, zamiast obsługi rejestrów i fizycznego sprzętu, zajmujesz się zestawem abstrakcji i pozwalasz kompilatorowi wykonać całą brudną robotę. C pozwala również uporządkować efekty uboczne w pętlach, a jeśli tak, to w instrukcjach. C ++ poprawia C, dodając OOP i niektóre bardzo potrzebne funkcje do języka. Java i C # dodają odśmiecanie, a Python dodaje dynamiczne pisanie.
Nawet z tymi wszystkimi funkcjami - dynamiczne pisanie, wyrzucanie elementów bezużytecznych itp. Programy w tych językach są nadal całkowicie oparte na efektach ubocznych. Funkcjonalne języki programowania, takie jak Scheme, Clojure, Haskell i ML, są czymś zupełnie innym, języki te są bliżej matematyki niż kodu maszynowego. Zamiast efektów ubocznych przekazujesz wartości wokół funkcji.
Polecam Schemat , jest minimalny i był używany w starych klasach wprowadzających MIT. Inne funkcjonalne języki programowania są znacznie trudniejsze do nauczenia. Clojure przynosi ze sobą wszystkie zawiłości Javy, ML ma skomplikowany system statyczny, Haskell jest czasem określany jako język akademicki - nie jest idealny dla początkujących i tak dalej. Z drugiej strony schemat jest łatwy do nauczenia się i zrozumienia.
Prawie wszystkie języki programowania wysokiego poziomu mają funkcje i rekurencję - pojęcia, na których opiera się programowanie funkcjonalne. Jako taka, twoja wiedza na temat FP powinna być pomocna prawie wszędzie, jednak jeśli naprawdę chcesz programować funkcjonalnie, powinieneś używać języka, w którym jest on naturalny i skuteczny, a nie próbować dopasować projekt innej osoby do twoich upodobań, to znaczy powinieneś używać funkcjonalnego języka programowania do programowania funkcjonalnego.
źródło