Dlaczego obecny entuzjazm dla programowania funkcjonalnego? [Zamknięte]


50

Ostatnio słyszałem wiele entuzjazmu na temat funkcjonalnych języków programowania, w odniesieniu do Scali, Clojure i F #. Niedawno zacząłem studiować Haskell, aby nauczyć się paradygmatu FP.

Uwielbiam to, jest naprawdę fajne i pasuje do mojego tła matematycznego.

Ale czy to naprawdę będzie miało znaczenie? Oczywiście nie jest to nowy pomysł.

Oto moje pytania:

  1. Co przyczyniło się do ostatniego entuzjazmu FP? Czy jest to tylko nuda z OO, czy też coś się zmieniło, aby FP była bardziej potrzebna niż wcześniej?
  2. Czy to wskazuje na przyszłość PR? A może to moda, jak bazy danych zorientowane obiektowo?

Innymi słowy, czy ktoś może mi pomóc zrozumieć, skąd to się bierze i dokąd zmierza?



13
Nie duplikat - to pytanie, dlaczego ludzie nagle robią zamieszanie, ponieważ nie jest to nowy pomysł (podczas gdy to pytanie wymaga więcej obiektywnych różnic).
Peter Boughton,

2
Ludzie ostatnio robią zamieszanie z powodu FP? Wiadomość dla mnie, myślałem, że zawsze tak było, że jakaś grupa robiła zamieszanie o to, jak FP przejmie imperatywny świat programowania.
Chris,

1
Myślę, że wcześniej odpowiedziałem na to pytanie na StackOverflow.
Ken Bloom

1
Tak - FP był już stary Myślę, że kiedy używałem Scheme jako licencjata w Kolumbii w 1989 roku. To chyba lśniąca nowa rzecz.
Tim

Odpowiedzi:


33

Jedną z głównych innowacji w FP, która spowodowała „eksplozję” zainteresowania, są monady.

W styczniu 1992 roku Philip Wadler napisał artykuł zatytułowany The Essence of Functional Programming, który wprowadził monady do programowania funkcjonalnego jako sposób radzenia sobie z IO.

Głównym problemem w czystych, leniwych, funkcjonalnych językach programowania była użyteczność w radzeniu sobie z IO. Jest jednym z członków „Niezręcznej drużyny” w programowaniu, ponieważ „lenistwo i skutki uboczne są z praktycznego punktu widzenia niezgodne. Jeśli chcesz używać leniwego języka, musi to być język czysto funkcjonalny; jeśli chcesz użyć efektów ubocznych, lepiej użyj surowego języka. ” Odniesienie

Problem z IO przed monadami polegał na tym, że utrzymanie czystości nie było możliwe w przypadku programów, które faktycznie byłyby przydatne do czegokolwiek. Przez IO rozumiemy wszystko, co dotyczy zmiany stanu, w tym uzyskiwanie danych wejściowych i wyjściowych od użytkownika lub środowiska. W czystym programowaniu funkcjonalnym wszystko jest niezmienne, aby umożliwić lenistwo i czystość (wolne od skutków ubocznych).

Jak monady rozwiązują problem IO? Cóż, bez zbytniego dyskutowania o monadach, w zasadzie pobierają „Świat” (środowisko wykonawcze) jako dane wejściowe do monady i wytwarzają nowy „Świat” jako wynik, a wynik: wpisz IO a = Świat -> (a, Świat).

Dlatego też FP coraz częściej wchodzi do głównego nurtu, ponieważ największy problem, IO (i inne) został rozwiązany. Jak wiadomo, odbywa się również integracja z istniejącymi językami OO. LINQ to na przykład monady.

Aby uzyskać więcej informacji, polecam przeczytać o monadach i artykułach wymienionych w mojej odpowiedzi.


Niezwykle pouczające, dzięki. Akceptuję tę odpowiedź, nie dlatego, że jest słuszna, a inni się mylą (kilkakrotnie głosowałem), ale dlatego, że uważam, że zasługuje ona na widoczność.
Eric Wilson,

Bardziej trafnym przykładem byłaby jednak type IO a = UI -> (a, UI)fantastyczna odpowiedź.
ChaosPandion,

@Richard: „type IO a = World -> (a, World)” brzmi prawie zbyt dobrze, aby mogło być prawdziwe (myślałem, że nigdy nie dostanę monad). Myślę, że porównujesz LINQ do monad, ponieważ kiedy przekazujesz lambda do operatora LINQ, lambda „widzi” całe swoje otoczenie, czy to prawda?
Stefan Monov,

@Stefan: Brzmi dość trafnie, gdy mówi, że lambda widzi otoczenie, ale nie jestem w 100% jasny, więc waham się odpowiedzieć, dopóki sam się nie nauczę. Mogę jednak powiedzieć ze 100% pewnością, że LINQ to monady, ponieważ twórcy wielokrotnie to mówili. SelectMany jest dokładnie równoważne Bind w Haskell. Jeśli nie przeczytałeś „ Cudów Monad ” ( blogs.msdn.com/b/wesdyer/archive/2008/01/11/... ) Bardzo polecam ... pokaże , jak LINQ jest naprawdę monadami. Twoje zdrowie.
Richard Anthony Hein

1
@ Job, zobacz blogs.msdn.com/b/wesdyer/archive/2008/01/11/... zgodnie z powyższym komentarzem.
Richard Anthony Hein

30

Jednym z głównych problemów podczas programowania tradycyjnych języków, takich jak C, Java, C #, asembler itp., Jest trudna sekwencja kroków, które należy wykonać, aby wykonać dane zadanie, ponieważ najpierw trzeba przygotować wszystkie zależności i ICH zależności wcześniej

Przykład: aby wykonać A, musisz mieć obecne B i C, a B zależy od D i E, co daje coś w rodzaju

  • re
  • mi
  • do
  • b
  • ZA

ponieważ musisz mieć przygotowane składniki, zanim będziesz mógł ich użyć.

Języki funkcjonalne, zwłaszcza leniwe, przewracają ten język do góry nogami. Pozwalając A powiedzieć, że potrzebuje B i C, i pozwolić środowisku uruchomieniowemu języka dowiedzieć się, kiedy uzyskać B i C (co z kolei wymaga D i E), które wszystkie są oceniane, gdy są potrzebne do oceny A, możesz stworzyć bardzo małe i zwięzłe bloki konstrukcyjne, które dają małe i zwięzłe programy. Leniwe języki pozwalają również na korzystanie z nieskończonych list, ponieważ obliczane są tylko faktycznie używane elementy i bez konieczności przechowywania całej struktury danych w pamięci przed użyciem.

Naprawdę fajna sztuczka polega na tym, że ten automatyczny mechanizm „och, potrzebuję B i C” jest skalowalny, ponieważ nie ma ograniczeń - jak w programie sekwencyjnym - co do tego, gdzie i kiedy ta ocena może się zdarzyć, więc może się zdarzyć na w tym samym czasie, a nawet na różnych procesorach lub komputerach.

Że dlatego Języki funkcjonalne są interesujące - bo «co zrobić, gdy» mechanizm zostaje przejęty przez system wykonawczego w przeciwieństwie do programatora posiadającego to zrobić ręcznie. Jest to tak ważna różnica, jak automatyczne odśmiecanie pamięci dla Javy do C, i jeden z głównych powodów, dla których łatwiej jest pisać solidne, skalowalne, wielowątkowe oprogramowanie w Javie niż w C. Jeszcze łatwiej jest pisać solidne, skalowalne oprogramowanie wielowątkowe w językach funkcjonalnych ...


3
Tak było oczywiście w 1950 r.
Eric Wilson,

1
@FarmBoy, nie bardzo, ale jest dzisiaj.

5
Czym różni się to od wstrzykiwania zależności?
Bill K

2
@ Bill K, doskonała obserwacja - sam tego nie zrobiłem. Różnica polega na tym, że obiekty do wstrzyknięcia - przynajmniej w Javie - są chętnie oceniane, a nie leniwie oceniane. Nie możesz wstrzyknąć nieskończonej listy.

1
@ Thorbjørn Ravn Andersen Nie jestem pewien, czy rozumiem, dlaczego nieskończona lista byłaby przydatna, czy faktycznie możesz wykonać sumę operacji typu (lista nieskończona)? Wydaje się bardzo mało prawdopodobne. W przeciwnym razie brzmi to tak, jak sposób, w jaki Java używa iteratorów, po prostu kodujesz iterator w taki sposób, że tworzy on obiekty tylko wtedy, gdy o nie poprosisz - nie do końca, ale nigdy się nie kończy (istnieje DUŻA różnica, prawda? )
Bill K

21

Na przełomie lat 80. i 90. komputery stały się wystarczająco mocne, by obsługiwać OOP w stylu Smalltalk. W dzisiejszych czasach komputery mają wystarczającą moc do FP. FP programuje na wyższym poziomie i dlatego często - choć przyjemniej jest programować - nie jest to najbardziej efektywny sposób rozwiązania określonego problemu. Ale komputery są tak szybkie, że Cię to nie obchodzi.

Wielordzeniowe prorgamming może być łatwiejsze dzięki czysto funkcjonalnym językom programowania, ponieważ jesteś zmuszony izolować kod zmieniający stan.

Również granice języków programowania są dziś zatarte. Nie musisz rezygnować z jednego paradygmatu, jeśli chcesz użyć innego. Możesz robić FP w najpopularniejszych językach, więc bariera wejścia jest niska.


6
Chciałem dodać odpowiedź, ale trafiłeś w sedno mojego ostatniego zdania; Programowanie funkcjonalne będzie coraz bardziej rozpowszechnione, gdy liczba rdzeni w jednej maszynie wzrośnie. Nieodłączny brak stanu ułatwia mechaniczne dzielenie programów funkcjonalnych na procesory (co oznacza, że ​​jeśli masz program czysto funkcjonalny, kompilator może teoretycznie zająć się równoległością za Ciebie przy minimalnym wysiłku z Twojej strony, patrz youtube.com/watch? v = NWSZ4c9yqW8 do dyskusji na temat równoległości danych).
Inaimathi,

1
@Inaimathi Ditto. Programowanie funkcjonalne jest bardzo skalowalne, więc ma sens w architekturach wielordzeniowych.
EricBoersma,

Zauważ, że mój pierwszy komentarz został napisany przed zredagowaniem odpowiedzi i zawiera dodatkowe oświadczenie.
Inaimathi,

Przepraszam za to. Właśnie zapomniałem o tym punkcie.
LennyProgrammers,

Czy naprawdę ogólnie przyjmuje się, że kompilatory funkcjonalne nie mogą tworzyć kodu maszynowego tak zoptymalizowanego jak OOPS? Nie mogę wymyślić żadnego teoretycznego powodu, dla którego to musi być prawda; i mogę wymyślić sposoby, w których możliwe są bardziej zaawansowane optymalizacje niż w OOPS.
Jeremy,

7

Dzisiejsze zapotrzebowanie na przetwarzanie rozproszone.

FP wykorzystuje funkcje jako bloki konstrukcyjne, które nie mają stanu, więc wywoływanie ich n razy przy tych samych parametrach powinno zawsze zwracać tę samą wartość, nie mają skutków ubocznych.

W ten sposób możesz wysłać tę samą funkcję do wielu komputerów, aby wykonywać i wykonywać pracę równolegle.

W paradygmacie OO jest to nieco trudniejsze, ponieważ bloki konstrukcyjne są obiektami, które są prawie z definicji stanowe. W przypadku kilkukrotnego wywołania tej samej metody należy zachować ostrożność podczas synchronizacji danych wewnętrznych, aby uniknąć uszkodzenia danych. Chociaż nadal jest to możliwe, paradygmat FP działa lepiej niż OO w niektórych scenariuszach, w których obliczenia muszą być rozproszone.

Pojawienie się FP (i do pewnego stopnia NoSQL) następuje po opowieściach o niesamowitych wynikach obliczeniowych w setkach tysięcy komputerów pracujących równolegle i jak łatwo jest.

Ale prawdopodobnie jest to tylko niszowa aplikacja wymagająca takiej konfiguracji. Dla wielu, wielu innych aplikacji / systemów, procedury i OO działają dobrze.

Zaraz więc poszerzymy nasze horyzonty programistyczne i ponownie przyjrzymy się koncepcjom, które kiedyś uważaliśmy, że nie wykroczą poza środowisko akademickie.

Nauczyłem się programować w Lisp lata temu, a wtedy nie wiedziałem, że to nawet FP. Do tej pory prawie o tym zapomniałem, ale na pewno pomogę mi bardzo łatwo zrozumieć pojęcia takie jak rekurencja.


2
Pytanie dotyczy zalet języków podobnych do FP . To, co opisałeś, można zrobić również przy użyciu tradycyjnych języków.
Pacerier

6

Przechodzimy do epoki, w której przetwarzanie wielordzeniowe nie jest po prostu czymś wykonywanym w zapleczach laboratoriów naukowych lub na specjalistycznym sprzęcie. Odbywa się to teraz za pomocą procesorów towarowych. Programowanie funkcjonalne, przynajmniej większość wariantów, na które byłem narażony, ogólnie stara się narzucić pogląd na wolne od skutków ubocznych, bezpaństwowe jednostki obliczeniowe. Jest to kwintesencja paradygmatu pracy wielordzeniowej, ponieważ nie trzeba utrzymywać stanu między procesorami.

Jest to tylko jeden z powodów, ale cholernie dobry powód, aby zobaczyć funkcjonalne programowanie.


5

Myślę, że główną odpowiedzią na to pytanie jest „ujawnienie”.

Programowanie funkcjonalne nie jest niczym nowym, uczyłem się Haskell na uniwersytecie około 12 lat temu i bardzo mi się podobało. Ale rzadko używam tego języka w mojej pracy zawodowej.

Ostatnio w głównym strumieniu zyskuje na popularności kilka języków, które wykorzystują podejście oparte na wielu paradygmatach; F # , JavaScript jest najlepszym przykładem.

W szczególności JavaScript, szczególnie gdy jest używany z funkcjonalnym językiem frameworkowym, takim jak jQuery lub Prototype , staje się językiem codziennym dla wielu osób ze względu na całą pracę nad dynamicznymi nowoczesnymi stronami internetowymi. Ta ekspozycja na funkcjonalny styl sprawia, że ​​ludzie zdają sobie sprawę z mocy, jaką przyznaje, zwłaszcza gdy można wrócić do stylu imperatywnego.

Po ujawnieniu ludzie wypróbowują pełniejsze wersje funkcjonalnych języków i zaczynają wykorzystywać je do codziennych zadań.

Ponieważ F # staje się językiem pierwszej klasy w Visual Studio 2010 i jQuery (i in.) Stają się tak ważne, realistyczne staje się używanie tych języków, a nie tylko coś niejasnego do grania lub tworzenia izolowanych programów.

Pamiętaj, że kod musi być łatwy w utrzymaniu - krytyczna masa programistów musi używać języków i obsługiwać je, aby firmy mogły czuć się bezpiecznie podczas ich używania.


3

W tej rozmowie Anders Hejlsberg wyjaśnia swój pogląd na ten temat.

[EDYTOWAĆ]

Przepraszamy, link był nieprawidłowy. Teraz wskazuje właściwe miejsce.

Niezwykle krótkie podsumowanie niektórych punktów jednogodzinnej rozmowy:

Języki funkcjonalne pozwalają na bardziej deklaratywny styl programowania niż języki proceduralne, więc programy napisane w języku FL zwykle koncentrują się bardziej na tym, co zamiast na tym, jak . Ze względu na ich elegancką strukturę matematyczną FL są również łatwiejsze do optymalizacji i transformacji przez kompilatory, co umożliwia również łatwe metaprogramowanie i budowę wbudowanych DSL. Wszystko to razem sprawia, że ​​programy funkcyjne są bardziej zwięzłe i samodokumentujące niż programy proceduralne.

Ponadto, w obliczu ery manycore w najbliższej przyszłości, języki programowania muszą być w stanie wykorzystywać wielowątkowość / przetwarzanie na różne sposoby. Wielowątkowość na maszynach z jednym rdzeniem była w istocie mechanizmem dzielenia czasu, co odzwierciedlała architektura systemów. Wielowątkowość na maszynach Manycore będzie zupełnie inna. Języki funkcjonalne nadają się szczególnie do paralelizacji, ponieważ przeważnie unikają stanu, więc nie trzeba się martwić o integralność współdzielonych danych zmiennych (ponieważ zwykle nie ma współdzielonych danych zmiennych).


1
Czy mógłbyś podsumować?

1
@Thorbjorn To przypomina mi człowieka, który nie mógł podsumować . (Nie kieruj tego do siebie, odpowiedz autorowi.)
Mark C

1
Link nawet nie prowadzi do właściwego miejsca.
Ken Bloom

2

Myślę, że ma to związek z ścisłą korelacją między paradygmatem programowania funkcjonalnego a programowaniem w Internecie.

Ruby on Rails przyniósł ulgę całemu funkcjonalnemu programowaniu, ponieważ oferuje bardzo szybką ścieżkę do funkcjonalnej aplikacji internetowej (heh heh). Istnieje ciekawa dyskusja na temat SO , a jedna szczególna odpowiedź wyróżnia się:

Programowanie funkcjonalne bardzo dobrze pasuje do aplikacji internetowych. Aplikacja internetowa odbiera żądanie HTTP i generuje wynik HTML. Można to uznać za funkcję od żądań do stron.

Porównaj z aplikacjami komputerowymi, w których zwykle mamy długi proces, stanowy interfejs użytkownika i przepływ danych w kilku kierunkach. Jest to bardziej odpowiednie dla OO, który martwi się obiektami z przekazywaniem stanu i wiadomości.

Biorąc pod uwagę, że programowanie funkcjonalne istnieje od wieków, zastanawiam się, dlaczego nie widzę wielu ogłoszeń o pracy szukających programistów Lisp do projektów sieciowych typu greenfield.


Wydaje mi się, że analogia funkcjonalna dotyczy sieci tylko przypadkowo, ponieważ podstawowy protokół jest bezstanowy. Aplikacje internetowe nie są tak naprawdę bezstanowe, co w rzeczywistości jest powodem, dla którego zawsze musimy jakoś ominąć HTTP.
Mladen Jablanović

@Mladen Hmmm, czy możliwe jest połączenie stanu komunikacji klient-serwer (HTTP) ze stanem aplikacji (DAO itp.)? Cytując Stefana Tilkova stąd ( codemonkeyism.com/stateless-applications-illusion ) „W aplikacji internetowej każde indywidualne żądanie powinno zawierać wystarczającą ilość informacji, aby można je było przetworzyć niezależnie od tego, czy poprzednie żądanie miało miejsce, czy nie. Stałe zasoby po stronie serwera stan jest w porządku, stan po stronie klienta jest w porządku, stan przejściowej komunikacji (sesji) nie jest taki, ponieważ zrujnuje on skalowalność i możliwość zaksięgowania ”. To jest podstawa REST.
Gary Rowe,

1
możesz przeczytać paulgraham.com/avg.html, aby lepiej zrozumieć, dlaczego niewielu ogłoszeń o pracę szuka deweloperów Lisp.

@ Thorbjørn Ravn Andersen Dobry artykuł. Inspiruje mnie do przełamania edytora Lisp.
Gary Rowe,

1

Programowanie funkcjonalne daje mi takie samo mrowienie: „ wow, to jest nowe ”, jak wtedy, gdy wiele lat temu zacząłem bawić się przedmiotami.

Zdaję sobie sprawę z tego, że FP nie jest jak dotąd nową koncepcją, ale nie było też OO, kiedy nastąpił prawdziwy przełom w latach dziewięćdziesiątych, kiedy „wszyscy” nagle odeszli od programowania proceduralnego. Było to w dużej mierze spowodowane terminowym sukcesem Javy, a później C #.

Wyobrażam sobie, że to samo stanie się z FP, gdy kolejna partia języków zacznie się rozprzestrzeniać w ten sam sposób. Chociaż mają już, przynajmniej w niektórych kręgach, języki takie jak Scala i F #.


OO jest znacznie młodszy od FP, ale już wcześniej znalazł się w centrum uwagi. Myślę, że nawiasy wystraszyły zbyt wiele osób
Javier,

1

Oto moje pytania: 1. Co przyczyniło się do ostatniego entuzjazmu FP? Czy jest to tylko nuda z OO, czy też coś się zmieniło, aby FP była bardziej potrzebna niż wcześniej? 2. Czy świadczy to o przyszłości PR? A może to moda, jak bazy danych zorientowane obiektowo?

Inni podali dobry powód techniczny.

Myślę, że głównym powodem, dla którego FP zyskuje na popularności wśród przeciętnych deweloperów i menedżerów, jest obietnica umożliwienia lepszego wykorzystania wielordzeniowych procesorów. Ze wszystkiego, co przeczytałem, FP umożliwia łatwiejsze (niełatwe) programowanie równoległe.

Jego przyszłe powszechne zastosowanie będzie możliwe, jeśli obietnica będzie prawdziwa i zostanie spełniona.


To duże „jeśli”. COBOL, bycie „po angielsku” oznaczałoby, że każdy może programować. AI sprawi, że programowanie stanie się przestarzałe. OO zamierzał uczynić programowanie tak prostym, jak montaż tinkertoys. Kodery są jak rockowe bandy, zawsze szukające „następnej wielkiej rzeczy”, a potem następnej i tej…
Mike Dunlavey,

0

Myślę, że jest to połączenie dwóch trendów:

  1. Funkcje funkcjonalne dodawane do głównych języków (np. C #).
  2. Tworzone są nowe języki funkcjonalne.

Prawdopodobnie istnieje naturalny limit dla pierwszego trendu, ale domyślam się, że każdy nowy język będzie musiał obsługiwać programowanie funkcjonalne, przynajmniej jako opcja, aby być traktowanym poważnie.


0

Kiedyś ludzie pisali programy do uruchamiania na pulpicie przy użyciu rodzimych interfejsów API systemu operacyjnego, a te interfejsy API były (ogólnie) pisane w języku C, więc w większości przypadków, jeśli chcesz napisać program dla rodzimych interfejsów API, napisał ten program w C.

Myślę, że nową innowacją w ciągu ostatnich 10 lat jest różnorodność interfejsów API, na które warto zwrócić uwagę, szczególnie w takich sprawach, jak tworzenie stron internetowych, w których interfejsy API platformy są nieistotne (ponieważ tworzenie strony internetowej zasadniczo wymaga manipulacji ciągami). Ponieważ nie kodujesz bezpośrednio do Win32 API lub POSIX API, daje to ludziom swobodę wypróbowania funkcjonalnych języków.


0

Jest schludny, sprytny i łaskocze twój mózg. W porządku.

Jest to także IMHO, klasyczny modwagon. Rozwiązanie szukające problemu.

To tak, jak wszystkie te start-upowe firmy założone przez inżynierów oszołomionych ulubionym pomysłem, które płoną jasno przez chwilę, ale są cicho wyprzedzane przez firmy oparte na dostarczaniu tego, co jest potrzebne.

To nowy pomysł, który chciałbym zobaczyć, programowanie oparte na potrzebach, a nie programowanie oparte na pomysłowych pomysłach. Może to brzmi przyziemnie, ale myślę, że w rzeczywistości może być dość kreatywne i sprytne.


-1

Zdecydowanie z powodu F #, chociaż czasami trudno jest powiedzieć, która jest przyczyną, a która skutkiem.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.