Rośnie funkcjonalne programowanie?

42

Zauważyłem ostatnio, że funkcjonalne języki programowania zyskują popularność . Niedawno zobaczyłem, jak Indeks Tiobe pokazuje wzrost popularności w porównaniu do ubiegłego roku, chociaż większość z nich nawet nie osiąga 50 najpopularniejszych języków według tego indeksu.

Tak było od dłuższego czasu. Programowanie funkcjonalne po prostu nie stało się tak popularne jak inne modele (tj. Programowanie obiektowe).

Widziałem jednak odrodzenie zainteresowania siłą programowania funkcjonalnego, a teraz, gdy multikresy są coraz bardziej popularne, programiści zaczęli wykazywać zainteresowanie innymi modelami współbieżności, które już były badane w przeszłości przez języki takie jak Haskell i Erlang.

Z wielkim zainteresowaniem widzę, że pomimo braku znaczącej akceptacji społeczności, pojawia się coraz więcej takich języków. Clojure (2007), Scala (2003), F # (2002) to tylko trzy przykłady ostatniej dekady.

Sam poświęciłem trochę czasu na naukę Haskell i Scali. I znajduję wielki potencjał w paradygmacie, który dla mnie był nowy, mimo że byłam tam tak długo.

I oczywiście, moim największym pytaniem jest, czy któreś z nich stanie się na tyle popularne, aby rozważyć podjęcie jakiegokolwiek wysiłku, ale to pytanie, na które nawet Mandrake nie byłby w stanie odpowiedzieć, pomimo całego zamieszania, jakie ludzie o nim robią.

Chcę zapytać:

  • W jakich scenariuszach powinienem rozważyć funkcjonalny język programowania, który lepiej nadaje się do wykonania danego zadania? Oprócz tak ostatnio popularnego problemu wielordzeniowego programowania równoległego.
  • Gdybym zdecydował się na funkcjonalny język programowania, który uznałbyś za największe pułapki, z którymi się borykam? (Oprócz zmiany paradygmatu i trudności w ocenie wydajności z powodu leniwej oceny).
  • Przy tak wielu funkcjonalnych językach programowania, jak wybrać ten, który najlepiej odpowiada Twoim potrzebom?

Wszelkie zalecenia dotyczące dalszych badań będą mile widziane.

Szukałem opinii w Internecie i wygląda na to, że cała ta odnowiona popularność wynika z pomysłu, że teraz uderzymy w ścianę Prawa Moore'a i nadejdą funkcjonalne języki programowania i bohatersko nas uratują. Ale jeśli tak jest, powiedziałbym, że istnieje większe prawdopodobieństwo, że istniejące popularne języki dostosują się do tego paradygmatu.

Być może niektórzy z was, z większym doświadczeniem w codziennej pracy z tymi językami, mogą uzyskać więcej informacji na ten temat. Wszystkie twoje opinie będą lepiej doceniane i uważnie przemyślane.

Z góry dziękuję!

edalorzo
źródło
4
To Erlang, a nie Earlang (edytowałbym twój post, ale System nie pozwala na edycję 1-literową).
quant_dev
6
Warto powiedzieć - nie ma twardej granicy między językami funkcjonalnymi a imperatywnymi. Języki rodziny ML nie są wolne od skutków ubocznych i obsługują bezwzględnie konieczne polecenia i struktury oraz zmienne zmienne. Niektóre języki imperatywne - poza moim językiem Python i JavaScript - mają znaczące cechy zaczerpnięte z programowania funkcjonalnego. Osobiście mam nadzieję, że w głównym nurcie zobaczę więcej funkcjonalnych pomysłów - zwłaszcza dopasowanie wzorców.
Steve314,
1
Posiadanie kilku cech wspólnych dla języków funkcjonalnych niekoniecznie czyni język „funkcjonalnym”. Programowanie funkcjonalne dotyczy zarówno sposobu myślenia i projektowania programów, jak i konkretnych funkcji językowych.
mipadi
2
@mipadi - i dlatego możesz zastosować filozofię funkcjonalną w dowolnym języku, do tego stopnia, na jaki pozwalają dostępne narzędzia. Możesz pisać kod w stylu funkcjonalnym w Pythonie (w ramach limitów), w tym zakresie Python jest językiem funkcjonalnym. W ML możesz pisać kod w stylu rozkazującym, a do tego stopnia ML jest językiem rozkazującym. Nie jest to dokładnie to samo, co „źli programiści potrafią pisać Fortran w dowolnym języku”, chociaż oczywiście jest to łatwa pułapka, jeśli wpadniecie w błąd.
Steve314,
1
@mipadi - ale jeśli imperatywny język ma wszystkie normalne konstrukcje funkcjonalne, możesz zrobić z nim wszystko, co możesz w funkcjonalnym języku - luka zostałaby zamknięta, a pytanie brzmiałoby „jaki jest najlepszy sposób, aby to zrobić”, a nie „jaki jest sposób funkcjonalny / imperatywny”. Rodzina ML już naprawdę zlikwidowała tę lukę, ale ponieważ nazywa się ją funkcjonalną, uważamy, że jest to styl funkcjonalny, a nie po prostu dobry.
Steve314,

Odpowiedzi:

24

W jakich scenariuszach powinienem rozważyć funkcjonalne języki programowania, które lepiej nadają się do wykonania danego zadania? Oprócz tak ostatnio popularnego problemu wielordzeniowego programowania równoległego.

Wszystko, co wymaga utworzenia sekwencji pochodnych elementów danych przy użyciu szeregu kroków transformacji.

Zasadniczo „problem z arkuszem kalkulacyjnym”. Masz pewne dane początkowe i zestaw obliczeń wiersz po rzędzie, które możesz zastosować do tych danych.

Nasze aplikacje produkcyjne wykonują szereg statystycznych podsumowań danych; do tego najlepiej podchodzić funkcjonalnie.

Jedną wspólną rzeczą jest łączenie trzech potwornych zestawów danych. Podobne do sprzężenia SQL, ale nie tak ogólne. Następnie następuje szereg obliczeń danych pochodnych. To wszystko tylko transformacje funkcjonalne.

Aplikacja została napisana w języku Python, ale została napisana w funkcjonalnym stylu, przy użyciu funkcji generatora i niezmiennych krotek nazwanych. To kompozycja funkcji niższego poziomu.

Oto konkretny przykład kompozycji funkcjonalnej.

for line in ( l.split(":") for l in ( l.strip() for l in someFile ) ):
    print line[0], line[3]

Jest to jeden ze sposobów, w jaki programowanie funkcjonalne wpływa na języki takie jak Python.

Czasami tego rodzaju rzeczy są zapisywane jako:

cleaned = ( l.strip() for l in someFile )
split = ( l.split(":") for l in cleaned )
for line in split:
     print line[0], line[3]

Jeśli zdecyduję się przejść na funkcjonalny język programowania, które Twoim zdaniem są największymi pułapkami, z którymi się spotkam? (Oprócz zmiany paradygmatu i trudności w ocenie wydajności z powodu leniwej oceny).

Niezmienne przedmioty to najtrudniejsza przeszkoda.

Często kończysz obliczanie wartości tworzących nowe obiekty zamiast aktualizowania istniejących obiektów. Pomysł, że jest to zmienny atrybut obiektu, jest trudny do złamania.

Pochodna właściwość lub funkcja metody jest lepszym podejściem. Przedmioty stanowe są trudne do złamania.

Przy tak wielu funkcjonalnych językach programowania, jak wybrać ten, który najlepiej odpowiada Twoim potrzebom?

Na początku to nie ma znaczenia. Wybierz dowolny język do nauki. Gdy już coś wiesz, możesz rozważyć wybranie innej, która będzie lepiej odpowiadać Twoim potrzebom.

Przeczytałem o Haskell, aby zrozumieć rzeczy, których brakuje w Pythonie.

S.Lott
źródło
5
@edalorzo: Python nie jest słabo napisany. Jest bardzo, bardzo mocno napisany. Nie ma operatora rzutowania, więc jest silniej napisany niż Java lub C ++.
S.Lott,
5
@ S.Lott - czy statyczne sprawdzanie typu nie pomaga w narzędziach refaktoryzacyjnych IDE i podobnych typach inteligencji? Jeśli masz uruchomioną kompilację w tle i statycznie sprawdzasz typy, czy to nie oznacza, że ​​możesz zautomatyzować więcej w swoich narzędziach? Zgadzam się, że jeśli masz 100% pokrycia kodu w swoich testach, to go złapie. Musisz zdać sobie sprawę z tego, że prawdopodobnie mniej niż 50% kodu produkcyjnego w przedsiębiorstwie faktycznie obejmuje test jednostkowy, prawda? :) Istnieje prawdziwy świat, w którym musimy żyć.
Scott Whitlock
8
@ S.Lott "Sprawdzanie typu statycznego nie jest aż tak pomocne. Nie ma znaczenia, czy jest sprawdzanie statyczne przez kompilator czy sprawdzanie w czasie wykonywania. Nadal piszesz tyle samo kodu i tyle samo testów jednostkowych. „ Err, nie. Istotą statycznego sprawdzania typu jest to, że wyłapuje błędy, w związku z czym znacznie zmniejsza liczbę wymaganych testów.
Jon Harrop
3
@ S.Lott „Python nie jest słabo napisany. Jest bardzo, bardzo mocno napisany”. Python pośrednio rzuca między typami liczbowymi, które są słabo wpisywane.
Jon Harrop
3
@ Steve314 „W końcu statyczne sprawdzanie typu wyłapuje niektóre błędy, które pasują do podstawowych zasad. Testy jednostkowe w zasadzie mogą wychwycić wszystkie te błędy i wiele innych.” Nie. Sprawdzanie statyczne potwierdza poprawność aspektu programu. Testy jednostkowe mają na celu obalenie poprawności, ale niczego nie dowodzą. Testowanie jednostkowe nie zastępuje statycznego sprawdzania typu ani żadnego innego rodzaju dowodu.
Jon Harrop
23

„Funkcjonalny” to kilka różnych funkcji, z których każda jest niezależnie przydatna, i uważam, że bardziej przydatne jest spojrzenie na każdą z nich osobno.

Niezmienność

Teraz, gdy go znam, za każdym razem, gdy mogę uciec od niezmiennego wyniku, zawsze staram się to robić, nawet w programie zorientowanym obiektowo. Łatwiej jest wnioskować o programie, jeśli masz dane typu wartości. Zwykle potrzebujesz zmienności dla takich rzeczy jak GUI i wąskie gardła wydajności. Moje byty (używające NHibernate) są również zmienne (co ma sens, ponieważ modelują dane przechowywane w bazie danych).

Funkcje jako typy pierwszej klasy

Cokolwiek chcesz to nazwać, przekazywanie delegatów, działań lub funkcji, to naprawdę przydatny sposób na rozwiązanie całej klasy problemów w świecie rzeczywistym, takich jak „dziura w środku”. Przekonałem się również, że przekazanie delegata, akcji lub funkcji do obiektu jest czystsze niż to, że ta klasa deklaruje zdarzenie i przechwytuje to zdarzenie (zakładając, że zwykle jest tylko jeden „detektor”). Jeśli wiesz, że istnieje jeden detektor, wówczas akcja zwrotna może zostać przekazana jako parametr konstruktora (i zapisana w niezmiennym elemencie!)

Umiejętność komponowania funkcji (na przykład przekształcanie się Action<T>w po prostu Actionjest również przydatne w niektórych scenariuszach).

Powinniśmy również zwrócić uwagę na składnię Lambda, ponieważ składnia Lambda jest dostępna tylko wtedy, gdy promujesz funkcje do typów pierwszej klasy. Składnia lambda może być bardzo ekspresyjna i zwięzła.

Monady

Wprawdzie jest to mój słaby punkt, ale rozumiem, że przepływy obliczeniowe w F #, takie jak asyncprzepływ pracy, to monada. To subtelna, ale bardzo mocna konstrukcja. Jest tak silny, jak yieldsłowo kluczowe używane do tworzenia IEnumerableklas w języku C #. Zasadniczo buduje on dla ciebie maszynę stanową, ale twoja logika wygląda liniowo.

Leniwa ocena i rekurencja

Złożyłem je razem, ponieważ chociaż zawsze są one skupione jako funkcje programowania funkcjonalnego, tak szybko weszły w języki, które są konieczne, że trudno je nazwać funkcjonalnymi.

Wyrażenia S.

Myślę, że nie jestem pewien, gdzie to umieścić, ale możliwość traktowania nieskompilowanego kodu jako obiektu (i sprawdzania / modyfikowania go), takiego jak S-Expressions Lisp lub wyrażenia LINQ, jest pod pewnymi względami najpotężniejsze narzędzie programowania funkcjonalnego. Większość nowych „płynnych” interfejsów .NET i DSL używa kombinacji składni lambda i wyrażeń LINQ do tworzenia bardzo zwięzłych interfejsów API. Nie wspominając już o Linq2Sql / Linq2Nhibernate, gdzie twój kod C # jest „magicznie” wykonywany jako SQL zamiast jako kod C #.

To była długa odpowiedź na pierwszą część twojego pytania ... teraz ...

Jeśli zdecyduję się przejść na funkcjonalny język programowania, które Twoim zdaniem są największymi pułapkami, z którymi się spotkam? (Oprócz zmiany paradygmatu i trudności w ocenie wydajności z powodu leniwej oceny).

Największym problemem, z jakim się spotkałem, było znalezienie granicy między stosowaniem rozwiązań funkcjonalnych a koniecznymi. Jednak po kilkakrotnym wypróbowaniu obu podejść zaczynasz odczuwać, że będzie działać lepiej.

Przy tak wielu funkcjonalnych językach programowania, jak wybrać ten, który najlepiej odpowiada Twoim potrzebom?

Jeśli znasz .NET, bardzo polecam F #. Z drugiej strony, jeśli jesteś bardziej zaznajomiony z JVM, zawsze jest Clojure . Jeśli jesteś bardziej akademicki niż praktyczny, wybrałbym Common Lisp lub Scheme. Jeśli znasz już Pythona, uważam, że dostępnych jest tam wiele funkcjonalnych konstrukcji.

Scott Whitlock
źródło
@Scott Dzięki za szczegółowe wyjaśnienie. Wydaje mi się, że to, co opisujesz jako największą pułapkę, zostałoby usunięte z równania za pomocą czysto funkcjonalnego języka programowania, takiego jak Haskell. Dlatego zacząłem od tego, ponieważ przez całe życie byłem programistą i nie chcę grać z nieczystym językiem programowania i ryzykuję, że nie nauczę się dobrze. Jeśli nie przeszkadza mi, że zadam inne pytanie: dwie rzeczy, które mnie martwią, to narzędzia i biblioteki. Jak dobra jest integracja F # z innymi narzędziami i bibliotekami .Net?
edalorzo
Nie rozumiem, dlaczego zbijasz kod w czasie wykonywania i generowania kodu kontroli i kontroli za pomocą programowania funkcjonalnego. Obaj nie mają ze sobą związku. Możliwości metaprogramowania, które opisujesz, można dodać do niemal dowolnego języka, funkcjonalnego lub nie. Myślę, że lisp zaczął kod jako trend danych, ale teraz jest dostępny w Ruby i innych niefunkcjonalnych językach.
davidk01
1
Integracja @edalorzo - F # z .NET jest bardzo dobra, z jednym drobnym wyjątkiem: brak projektanta GUI. Można obejść ten problem, projektując GUI w zestawie C # i odwołując się do niego z F # lub generując GUI wewnątrz F # tylko w kodzie (nie z projektantem).
Scott Whitlock,
@ davidk01 - dobre pytanie o metaprogramowaniu. Po prostu stwierdzam, że składnia lambda i metaprogramowanie wzajemnie się uzupełniają, ale masz rację, można je rozdzielić. Wygląda na to, że masz większe szanse na metaprogramowanie z funkcjonalnym językiem.
Scott Whitlock,
1
@ Scott: Myślę, że na wiele sposobów jest łatwiej - na przykład, gdy nie musisz martwić się o skutki uboczne, możesz modyfikować sekcję kodu w locie z większą pewnością - ogranicza to, co musisz zmienić.
Michael K
15

Tak było od dłuższego czasu. Programowanie funkcjonalne po prostu nie stało się tak popularne jak inne modele (tj. Programowanie obiektowe).

Dzieje się tak, jeśli liczyć programy opracowane przez profesjonalnych programistów (lub przynajmniej osoby postrzegające siebie jako takie). Jeśli rozszerzysz swoją sieć o programy opracowane przez osoby, które nie uważają się za takie, FP (lub przynajmniej programowanie w funkcjonalnym stylu) jest dość zbliżone do OO (Excel, Mathematica, Matlab, R ... nawet „nowoczesny” JavaScript ).

W jakich scenariuszach powinienem rozważyć funkcjonalne języki programowania, które lepiej nadają się do wykonania danego zadania? Oprócz tak ostatnio popularnego problemu wielordzeniowego programowania równoległego.

Moim osobistym zdaniem jest to, że wielordzeniowość nie jest zabójczą funkcją FP (przynajmniej dopóki kompilatory Haskell, Scala, Clojure, F # nie rozwiążą problemu z lokalizacją pamięci podręcznej). Funkcja zabójca map, filter, foldi przyjaciół, które umożliwiają bardziej zwięzły wyraz dużej grupy algorytmów. Sytuację pogarszają języki FP o bardziej zwięzłej składni niż większość popularnych odpowiedników OO.

Dodatkowo zbliżenie FP do modelu relacyjnego zmniejsza niedopasowanie impedancji z RDBMS ... co jest - co najmniej dla nie-programistów - bardzo miłe.

Również wtedy, gdy masz szczególnie trudne do spełnienia wymagania dotyczące „poprawności” - w formie, która jest trudna do przetestowania (powszechna w obliczeniach naukowych / analizie dużych danych, gdzie celem jest uzyskanie wcześniej nieznanych i jako takich nieokreślonych wyników) FP może zaoferować Zalety.

Jeśli zdecyduję się przejść na funkcjonalny język programowania, które Twoim zdaniem są największymi pułapkami, z którymi się spotkam?

  • brak obsługi narzędzi (F # i niektóre Lisps są wyjątkiem, Scala jest w drodze)
  • trudniej wycisnąć ostatni kawałek wydajności ze swojego sprzętu
  • społeczności często koncentrujące się na innych zagadnieniach niż te, z którymi boryka się duża grupa komercyjnych projektów rozwoju oprogramowania
  • bardzo niewielu programistów mających doświadczenie w stosowaniu FP w środowisku przemysłowym, a jeśli możesz je znaleźć, prawdopodobnie musisz konkurować z wynagrodzeniem i korzyściami, jakie może zaoferować przemysł finansowy
  • funkcjonalny styl programowania jest trudniejszy do debugowania; tzn. obserwowanie wyników w długim łańcuchu złożonych funkcji zwykle nie jest możliwe w większości (wszystkich?) debuggerów

Przy tak wielu funkcjonalnych językach programowania, jak wybrać ten, który najlepiej odpowiada Twoim potrzebom?

  • Ile problemów można rozwiązać, wychodząc już z bibliotek / frameworków na której platformie (np. JVM lub .Net), ile jest fabrycznie nowych? Czy istnieją konstrukcje językowe zdolne bezpośrednio wyrażać te problemy?

  • Ile kontroli niskiego poziomu potrzebujesz na przestrzeni i wydajności aplikacji?

  • Jak surowe są twoje wymagania dotyczące „poprawności”?

  • Czy stać Cię na przekwalifikowanie programistów i / lub konkurowanie z korzyściami oferowanymi przez niektóre wysoce dochodowe nisze w rozwoju SW?

Alexander Battisti
źródło
+1 @Alexander to z pewnością jedna z najlepszych odpowiedzi w tej dyskusji. Wprowadziłeś do dyskusji nowy wymiar argumentów, wprowadzając czynnik ludzki, trudność ze znalezieniem wykwalifikowanych programistów i utrzymywanie ich motywacji. Całkowicie zgadzam się z twoją wizją zabójczych cech języków FP, ponieważ każdego dnia widzę, jak coraz więcej imperatywnych języków je przyjmuje. Ale twój post otworzył mi oczy i uświadomiłam sobie, że wciąż wiele rzeczy nie wiem o FP. Wreszcie, twój punkt oparcia na istniejącej platformie, takiej jak .Net lub Java, jest z pewnością bardzo ważny i całkowicie sensowny.
edalorzo
9

Jeśli zdecyduję się przejść na funkcjonalny język programowania, które Twoim zdaniem są największymi pułapkami, z którymi się spotkam? (Oprócz zmiany paradygmatu i trudności w ocenie wydajności z powodu leniwej oceny).

Zakładając, że jesteś programistą C ++ / C # / Java w branży ...

Bądź przygotowany na zrzędliwych rówieśników, którzy nie chcą się niczego uczyć. Przygotuj się na spiczastych szefów narzucających złe wybory językowe „ponieważ kiedyś byli programistami”. Przygotuj się na żwawych naukowców na forach protekcjonujących cię w sprawie monoidów. Przygotuj się na niekończące się wojny językowe, ponieważ Scala nawet nie eliminuje ogonów, a Clojure naprawdę wymaga pedałów dla wszystkich nawiasów i nie zaczynaj od Erlanga.

Jeśli jesteś programistą internetowym, największą pułapką będą prawdopodobnie twoje włosy.

Przy tak wielu funkcjonalnych językach programowania, jak wybrać ten, który najlepiej odpowiada Twoim potrzebom?

Zacznę od platformy:

  • OCaml jest świetny w systemie Linux i okropny w systemie Windows.
  • F # jest świetny w systemie Windows i okropny w systemie Linux.
  • Scala i Clojure są świetne na JVM.
Jon Harrop
źródło
1
Kiedy czytam „Przygotuj się na zrzędliwych rówieśników, którzy nie chcą się niczego uczyć”. Chciałem krzyczeć: „Tak prawdziwe! Tak cholernie prawdziwe!” ale to naprawdę smutne.
Zelphir Kaltstahl
3

Dla jednej (co prawda stronniczej) perspektywy na to pytanie, możesz sprawdzić blog Boba Harpera, Existential Type . Carnegie Mellon niedawno przerobiła swój program CS, aby uczyć najpierw programowania funkcjonalnego, a inne paradygmaty są nauczane dopiero po ustaleniu solidnego podstaw programowania funkcjonalnego, a Harper daje cios, gdy nowy program nauczania jest wdrażany w praktyce .

Harper jest jednym z głównych twórców standardowego języka programowania ML, więc można śmiało powiedzieć, że jego własne zdanie na ten temat można z góry zgadnąć, a on z pewnością nie boi się kontrowersyjnych stwierdzeń argumentujących za tym stanowiskiem, ale czyni jego sprawa dobrze.

jimwise
źródło
1
+1 Ten artykuł jest z pewnością bardzo interesujący i od tej pory będę go przechowywać w moich ulubionych. Myślę, że nauczanie FP jako pierwszego jest z pewnością przyjemnym podejściem, ponieważ naprawdę trudno jest pozbyć się imperatywnego myślenia, jeśli zrobisz to inaczej, a przede wszystkim, jeśli nie używasz czysto funkcjonalnego języka programowania, trudno jest przełamać stare zwyczaje. Widzę również, że główne języki OOP zawierają funkcje funkcjonalne, dlatego nabycie umiejętności i stanu umysłu funkcjonalnego programisty musi być naprawdę przydatne w najbliższej przyszłości. Ciekawy wgląd, dzięki!
edalorzo
@jwise: +1 za artykuł Harpera. Uważam, że jego podejście jest bardzo odpowiednie. @edalorzo: Kiedy zaczniesz myśleć funkcjonalnie, zobaczysz imperatywny paradygmat jako ostateczność, którą musisz zastosować, aby zoptymalizować swój program, gdy nie jest on wystarczająco szybki. Niedawno piszę w Scali kilka małych narzędzi, niezbyt dużych, ale niebanalnych i posiadających prawdziwą funkcjonalność. Ku mojemu zdziwieniu varani razu nie użyłem ani żadnej kolekcji podlegającej modyfikacji. Tak więc imperatywne myślenie jest IMO pewnego rodzaju przedwczesną optymalizacją, która, jak wszyscy wiemy, jest źródłem wszelkiego zła.
Giorgio
2

W jakich scenariuszach powinienem rozważyć funkcjonalne języki programowania, które lepiej nadają się do wykonania danego zadania? Oprócz tak ostatnio popularnego problemu wielordzeniowego programowania równoległego.

Nie ma magicznej formuły, która podpowiada, kiedy używać programowania funkcjonalnego. To nie jest tak, że programowanie obiektowe lepiej pasuje do naszych obecnych sytuacji programistycznych. To po prostu inny sposób konstruowania programów pod względem innego zestawu abstrakcji.

Jeśli zdecyduję się przejść na funkcjonalny język programowania, które Twoim zdaniem są największymi pułapkami, z którymi się spotkam? (Oprócz zmiany paradygmatu i trudności w ocenie wydajności z powodu leniwej oceny).

Programowanie funkcjonalne nie ma nic wspólnego z lenistwem. ML i OCaml są funkcjonalnymi i ścisłymi językami. Największą przeszkodą, jaką napotkasz, jest konstruowanie rzeczy w kategoriach niezmiennych wartości i zawijanie głowy wokół jakiejkolwiek abstrakcji używanej w systemie typów do efektów ubocznych. Języki funkcjonalne lepiej nadają się do optymalizacji, ponieważ powodują, że skutki uboczne są bardzo wyraźne w systemie typów. Haskell używa monad, ale istnieją inne podejścia do używania efektów w czysto funkcjonalnych językach. Clean ma typy unikatowości, a niektóre inne języki w fazie rozwoju mają inne rzeczy.

Przy tak wielu funkcjonalnych językach programowania, jak wybrać ten, który najlepiej odpowiada Twoim potrzebom?

Wśród znanych mi języków programowania powiedziałbym, że tylko Haskell i Clean można nazwać językami funkcjonalnymi. Wszystkie pozostałe pozwalają na efekty uboczne bez wyraźnego zaznaczania tych efektów w systemie typów. Jeśli więc zamierzasz poświęcić czas na naukę programowania funkcjonalnego, to Haskell jest prawdopodobnie jedynym, który pasuje do tego rachunku. Wszystkie pozostałe, które znam, Erlang, Scala, Clojure, itp. Zapewniają funkcjonalne abstrakty na imperatywnym języku. Więc jeśli chcesz podejść do paradygmatu funkcjonalnego w bitach, poleciłbym Scalę lub Erlanga, a jeśli chcesz poradzić sobie ze wszystkim naraz i być może zrezygnować z frustracji, powinieneś iść z Haskellem.

davidk01
źródło
@ Dadivk01 +1 Podoba mi się rozumowanie, że langi FP są tak konkurencyjnym narzędziem jak każde inne i mogą być użyte do rozwiązania tych samych problemów, które rozwiązano przy pomocy innych modeli. Jak myślisz, dlaczego są mniej popularne? I czy nadal zgadzasz się, że lepiej nadają się one do rozwiązania problemu przetwarzania równoległego niż na przykład większość języków OOP? Czy powiedziałbyś, że niezmienny typ danych ma jakikolwiek wpływ na wielkość pamięci i wydajność w porównaniu z imperatywnymi językami? Dałem szansę Haskellowi, dlaczego powiedziałbyś „poddać się z frustracji”, przerażasz mnie, koleś :)
edalorzo
@edalorzo: Nie sądzę, aby programowanie funkcjonalne było lepsze dla algorytmów równoległych. Ludzie mylą programowanie deklaratywne z programowaniem funkcjonalnym. Program funkcjonalny ma na celu jego deklaratywny charakter i grupę naprawdę inteligentnych ludzi piszących doskonałe kompilatory do tłumaczenia deklaratywnego kodu na kod maszynowy. Każdy inny język, który skłania się bardziej do opisywania problemów zamiast jawnego wypowiadania drobnych szczegółów, będzie równie dobry do programowania równoległego.
davidk01
@edalorzo: Jeśli chodzi o „poddawanie się frustracji”, mówię to, ponieważ jeśli wszystko, co wiesz, to programowanie imperatywne, to system typów Haskell i jego monadyczne podejście do opisywania efektów może być trochę za dużo. Myślę, że lepiej zacząć od języka, który przyjmuje bardziej pragmatyczne podejście do skutków ubocznych, takich jak Erlang i Scala.
davidk01
0

Obecny wzrost zainteresowania językami funkcjonalnymi przypisałbym temu, że są one idealne do obliczeń równoległych. Na przykład cała idea zmniejszania mapy opiera się na paradygmacie funkcjonalnym. I nie ma wątpliwości, że równoległe obliczenia będą rosły, ponieważ jest oczywiste, że obecnie skalowanie jest o wiele łatwiejsze i tańsze niż skalowanie. Nawet na rynku konsumenckim procesory mają więcej rdzeni, a nie więcej GHz.

EDYCJA: ponieważ nie jest to oczywiste dla wszystkich.

W czystym programowaniu funkcjonalnym funkcja pobiera dane wejściowe, wytwarza dane wyjściowe i nie wywołuje żadnych skutków ubocznych. Brak efektu ubocznego oznacza, że ​​nie ma on wspólnego stanu, a zatem nie ma potrzeby mechanizmów synchronizacji, które w innym przypadku byłyby konieczne podczas jednoczesnego działania. Synchronizacja jest najtrudniejszą częścią każdego oprogramowania współbieżnego / równoległego, dzięki czemu jest czysto funkcjonalna, w zasadzie nie musisz zajmować się najtrudniejszą częścią.

Jeśli chodzi o redukcję map, nawet nazwa pochodzi od programowania funkcjonalnego (zarówno mapowanie, jak i redukcja to typowe operacje w paradygmacie funkcjonalnym). Oba etapy zmniejszania mapy są funkcjami, które działają równolegle, pobierają dane wejściowe, generują dane wyjściowe i nie mają skutków ubocznych. Jest to więc dokładnie pomysł programowania funkcjonalnego.

Kilka przykładów FP wykorzystanych do równoległości:

  • CouchDB - buduj na Erlangu
  • Czat na Facebooku - buduj na Erlangu
  • Twitter - duża część oparta na Scali
vartec
źródło
3
Wszyscy twierdzą, że programowanie równoległe jest uzasadnione, ale jest bardzo mało danych, aby je wykonać. Jeśli znasz takie źródła, powinieneś je zacytować. Złożone obliczenia często mają złożone zależności danych, a jeśli użyjesz funkcjonalnego paradygmatu programowania, nieodłączna zależność danych niektórych modeli w magiczny sposób nie zniknie. Programowanie za pomocą GPU jest tak równoległe, jak to tylko możliwe, ale można to zrobić za pomocą języków imperatywnych, ponieważ modele, z którymi pracują, mają wbudowaną równoległość.
davidk01
4
@vartec: W interesie obiektywności byłoby miło, gdybyś mógł podać referencje, które potwierdzą twoje roszczenia. Pomogłoby to nieświadomym czytelnikom o wiele więcej niż kontr-pytanie ...
blubb
1
@vartec: Właściwie nie, nigdy nie przyszło mi do głowy, że wiele osób, które twierdzą, twierdzą, że to prawda. Obwiniam moje szkolenie matematyczne, ale hej nie wszyscy wierzymy w takie rzeczy, jak twarde fakty i konkretne uzasadnienia naszych twierdzeń, a twoja edycja wciąż nie odnosi się do mojego komentarza.
davidk01
1
@vartec Możesz zamieścić odniesienie do wiarygodnego źródła popierającego twoje roszczenia.
quant_dev
1
+1 @ davidk01 „Wszyscy twierdzą, że programowanie równoległe jest twierdzeniem, ale jest bardzo mało danych, aby je poprzeć”. Jestem świadomy ogromnej ilości dowodów przeciwnych. Na przykład, artykuły Cilka opisują, jak mutacja na miejscu jest niezbędna, jeśli chcesz mieć dobrą złożoność pamięci podręcznej, która jest wymogiem skalowalnej równoległości na rdzeniu wielordzeniowym.
Jon Harrop