Schemat vs Haskell dla wprowadzenia do programowania funkcjonalnego?

36

Czuję się swobodnie w programowaniu w C i C # i będę badał C ++ w przyszłości. Mogę być zainteresowany badaniem programowania funkcjonalnego jako innego paradygmatu programowania. Robię to dla zabawy, moja praca nie polega na programowaniu komputerowym i jestem nieco zainspirowana wykorzystaniem programowania funkcjonalnego, nauczanego dość wcześnie, na kursach informatyki na studiach. Rachunek lambda z pewnością przekracza moje zdolności matematyczne, ale myślę, że poradzę sobie z programowaniem funkcjonalnym.

Który z Haskell lub Scheme służyłby jako dobre wprowadzenie do programowania funkcjonalnego? Używam emacsa jako edytora tekstu i chciałbym móc go łatwiej skonfigurować w przyszłości, co wiązałoby się z nauką Emacsa Lispa. Rozumiem jednak, że Emacs Lisp dość różni się od schematu i jest bardziej proceduralny niż funkcjonalny.

Prawdopodobnie użyłbym książki „Mały Schemer”, którą już kupiłem, gdybym realizował Schemat (wydaje mi się to trochę dziwne z powodu mojego ograniczonego przeglądania). Lub skorzystałbym z „Learn You a Haskell for Great Good”, jeśli ścigam Haskella. Oglądałbym również filmy wprowadzające do dr. Erika Meijera na kanale 9.

Doceniamy wszelkie sugestie, opinie lub uwagi.

Dzięki.

PS BTW Mam również dostęp do F #, ponieważ mam Visual Studio 2010, którego używam do programowania w C #, ale nie sądzę, że powinny to być moje główne kryteria wyboru języka.

haziz
źródło
3
Nie zapomnijReal World Haskell
alternatywny
15
Drobny komentarz boczny: rachunek lambda jest niezwykle prostym systemem; fajne jest to, że nie jest skomplikowane, ale wręcz przeciwnie; że możesz wyrazić wszystko, co chcesz w tak prostym systemie. Zacznij od języka programowania; teraz wyrzucaj WSZYSTKO oprócz odniesień zmiennych, definicji funkcji i wywołań funkcji. Voila! Rachunek Lambda.
9
Mogę nauczyć cię rachunku lambda w pięć minut. Teraz zrozumienie konsekwencji tego, czego się właśnie nauczyłeś, trwa całe życie. :)
5
Wybrałem Haskell zamiast Scheme głównie dlatego, że nie ma on tak wielu natynkowych nawiasów!
Joey Adams,

Odpowiedzi:

27

Polecam OCaml.

Z mojego osobistego punktu widzenia, główną podstawą współczesnych programów funkcjonalnych są funkcje wyższego rzędu, system typów statycznych oraz algebraiczne typy danych i dopasowanie wzorców.

Pomiędzy schematem, ML i Haskell wybrałbym ML, ponieważ uważam, że jest najbardziej odpowiedni dla tej definicji. Schemat nie ma pisania statycznego (istnieje Typed Racket, ale nie jest przeznaczony dla początkujących w schemacie), a Haskell ma zbyt wiele innych rzeczy (monady, leniwa ocena ...), które, chociaż interesujące, mogą odwrócić uwagę od ważnej podstawy .

SML i OCaml są równie interesujące; Jestem bardziej przyzwyczajony do OCaml i ma to bardziej „praktyczne” uczucie, które jest miłe (ale jeśli naprawdę chcesz „praktyczny” na ryzyko utraty duszy, równie dobrze możesz wybrać F #).

Schemat i Haskell są również bardzo interesującymi językami. Nacisk na makra na schemat jest interesujący, ale nie jest bezpośrednio związany z programowaniem funkcjonalnym (jest to kolejna rzecz na świecie, którą zdecydowanie powinieneś spróbować, a także programowanie logiczne, języki oparte na stosie i E zorientowane na możliwości).

Haskell to zdecydowanie świetny język i, jak sądzę, obowiązkowy punkt dla aspirujących guru programowania funkcjonalnego. Ale ponieważ podstawowe języki OCaml i Haskell są bardzo podobne (z wyjątkiem leniwej oceny, która rozprasza początkującego), łatwo jest nauczyć się Haskell, gdy poznasz podstawy OCaml. A raczej możesz skoncentrować się na dziwnych rzeczach i nie musisz jednocześnie przyswajać podstaw.

Podobnie, gdy zobaczysz OCaml, a być może także Haskell i nadal chcesz dowiedzieć się więcej, powinieneś spojrzeć na Coq lub Agdę. Jednak niewielu poleciłoby Coq lub Agdę na pierwsze wprowadzenie do programowania funkcjonalnego ...

Mówiąc jasno: myślę, że nauka OCaml (lub SML), a następnie Haskell sprawi, że będziesz tak dobrym programistą, jak uczenie się Haskell bezpośrednio, ale łatwiej (lub mniej boleśnie).
Poza tym OCaml i Haskell mają dobre cechy, które je odróżniają, i warto wiedzieć o zaawansowanych funkcjach obu . Samo uczenie się Haskella jest pod tym względem gorsze (choć oczywiście możesz uczyć się OCamla po Haskellu; myślę, że jest to mniej logiczne i sprawi, że będziesz bardziej sfrustrowany).

Do nauki OCaml poleciłbym szkic książki Jasona Hickeya (PDF) .

¹ ta definicja jest kontrowersyjna. Niektórzy ludzie ze schematu twierdzą, że pisanie statyczne nie ma nic wspólnego z programowaniem funkcjonalnym. Niektórzy ludzie Haskell twierdzą, że ich definicja czystości („to, co robi Haskell, ale nie więcej”) jest warunkiem koniecznym bycia językiem funkcjonalnym. Zgadzam się nie zgadzać.

Robert Harvey
źródło
3
Dzięki za popchnięcie mnie w kierunku OCaml, i tak, zaryzykuję moją duszę i zbadam F #. Pracuję nad systemami Linux, Mac OS X i Windows (głównie te pierwsze), ale wydaje się, że FSI jest dostępny na wszystkich trzech platformach (z systemem mono na Linux i Mac OS X), co już robię. Fakt, że cała waga Microsoftu stoi za funkcjonalnym językiem programowania (choć „nieczystym”), powinien być mile widziany, a nie odrzucany przez fanów programowania funkcjonalnego.
haziz
SML nie żyje, ocaml istnieje, aby pisać coq
permeakra
1
+1 dla ML; jest bardziej przejrzysty niż Haskell.
m3th0dman
Uważam też, że dobrym pomysłem jest uczenie się SML lub OCaml, a następnie Haskell (+1). Po znajomości tych języków wybranie innego (np. Scali) jest bardzo łatwe. Dodatkowo można spojrzeć na Scheme, Common Lisp i Clojure (w tej kolejności), aby poczuć dynamiczne języki.
Giorgio
@haziz: Nawet jeśli tworzą dobre oprogramowanie, Microsoft (lub, w tym przypadku, Oracle itp.) pozostaje monopolistą, ze wszystkimi zaangażowanymi złymi praktykami, takimi jak blokowanie klientów, niezgodne formaty, niezgodne implementacje itp.
Giorgio
26

Jeśli interesują Cię bardziej zaawansowane koncepcje programowania funkcjonalnego, skorzystaj z Haskell. Istnieje odpowiedni system typów i ścisły zakaz mutacji. Mimo to Haskell nie jest dla osób o słabych nerwach.

Jeśli chcesz tylko zapoznać się z funkcjonalnym designem, skorzystaj ze Scheme. Składnia jest znacznie łatwiejsza do nauczenia się i czytania. Pozwala to na programowanie proceduralne, ale po prostu zdyscyplinuj się, aby nie używać żadnej procedury z !na końcu nazwy.

W Schemacie możesz także przeczytać Strukturę i interpretację programów komputerowych , która jest najlepszym wprowadzeniem do paradygmatów programowania, bez żadnych ograniczeń. W książce znajdują się wykłady zarówno MIT, jak i Berkeley .

Hoa Long Tam
źródło
4
„Składnia jest znacznie łatwiejsza do nauczenia się i czytania” jest bardzo subiektywna.
6
@luqui: True. Być może „zwykłe” to lepsze słowo. Żadnych wstecznych, infiksów, pierwszeństwa ani problemów z łączeniem - po prostu nawiasy, mnóstwo piekielnych, głupich nawiasów.
Hoa Long Tam,
17

Prawidłowa odpowiedź to oczywiście oba! Więc to tylko kwestia, którym językiem się zająć w pierwszej kolejności. Moja sytuacja jest identyczna z twoją. Naprawdę bardzo podobał mi się The Little Schemer. Z pewnością zrozumiesz podstawowe konstrukcje programowania funkcjonalnego po przejściu przez to (i będziesz mieć miejsce na umieszczenie plam z galaretki!)

Jestem za około ćwierć czasu na nauczenie się Haskell dla wielkiego dobra. Trochę mi się to podoba, ale te dwie książki nie mogą się bardziej różnić. Learn You a Haskell ma bardzo tradycyjne podejście do nauczania określonego języka. Mały Schemer jest oczywiście specyficzny dla Schematu, ale jest bardziej zainteresowany nauczaniem podstaw programowania funkcjonalnego, a nie języka Schematu.

Zdecydowanie polecam zacząć od The Little Schemer. Jest mniej praktyczny, ale bardziej podstawowy.

DaveGauer
źródło
17

Moje dwa centy w odniesieniu do programowania funkcjonalnego nie polegają na konkretnym języku, ale uczą się kluczowych pojęć programowania funkcjonalnego. Nauczyłem się programowania funkcjonalnego, rzucając się przede wszystkim w projekt, w którym mój szef nalegał, aby cały rozwój był przeprowadzany w APL. APL jest funkcjonalnym językiem przetwarzającym tablice i jest tak daleko od LISP, Haskell lub jakiegokolwiek innego głównego języka programowania, jaki można uzyskać. Prawdziwą korzyścią było, gdy odkryłem, że kiedy „zdławiłem” paradygmat programowania funkcjonalnego i mentalnie nauczyłem się, jak automatycznie rozkładać problem na program funkcjonalny, tak naprawdę nie byłem już dłużej zastraszany idiomatycznymi aspektami innych języków funkcjonalnych, takich jak Haskell, OCaml, Scheme, Scala i Clojure. JA'

Gdybym miał wybrać pierwszy język funkcjonalny, prawdopodobnie wybrałbym Haskell lub Steel Bank Common Lisp (SBCL). Dla Haskella przeczytałbym Naucz się Haskella ... , Real World Haskell , Droga Haskell do logiki, Matematyka i programowanie oraz Perły projektowania algorytmów funkcjonalnych . Dla CL przeczytałem Land of Lisp , Paradigms of Artificial Intelligence Programming i (jeśli jesteś naprawdę hardcorowy) Let over Lambda . Możesz mieszać i łączyć wszystkie te książki, aby uzyskać szeroki przegląd praktycznych podejść i koncepcji programowania funkcjonalnego.

Zastanowiłbym się również nad nauką Clojure i Scali, ponieważ są to zarówno bardzo dobre, jak i bardzo ekspresyjne języki funkcjonalne same w sobie (pomimo tego, co powiedziałby purysta FP).

Marc
źródło
6

Zgadzam się z punktem „naucz się obu”, ale jest jeszcze kilka punktów, o których dotychczas nie wspomniano. Przede wszystkim, jeśli jesteś początkujący w programowaniu funkcjonalnym i korzystasz z Haskell, musisz zmierzyć się z kilkoma nowymi rzeczami oprócz FP: musisz nauczyć się żyć w leniwym środowisku, które może wymagać znacznego wysiłku i potrzebujesz radzić sobie z „prawdziwym” systemem typu, który może być bardzo daleki od tego, którego używasz w C lub C #.

Schemat, OTOH, ma obco wyglądającą składnię, ale nie ma żadnego statycznego systemu typów do nauki i jest to ścisły język, więc rzeczy są bardziej znane. Ponadto implementacje schematu są zazwyczaj bardzo plastyczne - na przykład Racket prowadzi je do skrajności i zapewnia wariant leniwy i statycznie typowany. Oznacza to, że możesz zacząć od „łatwych” rzeczy i poćwiczyć posługiwanie się funkcjonalnym językiem, a później możesz się rozwijać i korzystać z wariantu maszynowego i leniwego. Powinny być teraz łatwiejsze, ponieważ możesz poradzić sobie z jedną funkcją naraz. Aby być jasnym, pojęciabędą na tyle nowe, że kwestia składniowa będzie niewielka i w większości nieistotna. Innymi słowy, kiedy zaczniesz wchodzić w nowe koncepcje, będziesz na tyle zajęty, że składnia po prostu zniknie. (A jeśli naprawdę zależy ci na składni, to składnia Haskella jest czymś, co osobiście uważam za bardzo elegancką - ale to dlatego, że jest również bardzo daleka od twojej średniej składni C / C # / C ++.)

Ale powiedziawszy to wszystko, myślę, że F # ma również sens - mówisz, że robisz to na marginesie, ale kiedy nauczysz się FP, wkrótce będziesz chciał użyć wszystkich tych dobrych rzeczy. Używanie F # oznacza, że ​​możesz robić więcej „prawdziwych” rzeczy, ponieważ prawdopodobnie łatwo jest rozwiązać te same problemy, z którymi masz do czynienia w codziennej pracy. Idealnie dojdziesz do punktu, w którym zobaczysz przewagę używania tego nad, powiedzmy, C # - i użyjesz go w jakimś projekcie. Więc chociaż masz rację, nie wybierając F # tylko dlatego, że łatwiej jest ci uzyskać dostęp, powinieneś to rozważyć, ponieważ nie ma nic lepszego niż w rzeczywistości używaniete nowe koncepcje. W przeciwieństwie do tego, jeśli używasz Scheme lub Haskell i uważasz, że jest to język zabawkowy do swoich celów (nawet jeśli wiesz, że niektórzy ludzie używają go do prawdziwych aplikacji), nigdy nie potraktujesz całej FP zbyt poważnie. [Ale YMMV opiera się głównie na subiektywnych obserwacjach i może się znacznie różnić w zależności od osoby.]

Eli Barzilay
źródło
6

Czy jest jakiś powód, dla którego ML nie jest jedną z twoich opcji? Dostępna jest spora ilość materiałów wprowadzających, w tym książek i materiałów szkoleniowych. Jeśli lubisz The Little Schemer, możesz także polubić The Little MLer. Wreszcie możesz łatwo przejść do F # później. (Nie to, że pukam Haskella lub Scheme - najlepiej naucz się wszystkich trzech).

Również ostrzeżenie o Emacsie Lispie. Nie sądzę, że ani Haskell, ani ML przygotują cię na to. Pomocny będzie język Lispy, taki jak Scheme, ale nadal istnieją duże różnice, np. zmienne o dynamicznym zasięgu. Rozszerzenia Emacsa, z samej swojej natury, wydają się być bardziej konieczne niż funkcjonalne - dotyczą zmiany stanu edytora.


źródło
Dzięki za popchnięcie mnie w kierunku ML / OCaml, i tak, „zaryzykuję moją duszę” i zbadam F #. Pracuję nad systemami Linux, Mac OS X i Windows (głównie te pierwsze), ale wydaje się, że FSI jest dostępny na wszystkich trzech platformach (z systemem mono na Linux i Mac OS X), co już robię. Fakt, że cała waga Microsoftu stoi za funkcjonalnym językiem programowania (choć „nieczystym”), powinien być mile widziany, a nie odrzucany przez fanów programowania funkcjonalnego.
haziz
BTW zamówiłem The Little MLer od Amazon i już go otrzymałem i rozpocząłem swoją Podróż. Właśnie dodałem Learning F # do mojej biblioteki. Wydaje się, że jest to bardziej ogólny przewodnik dydaktyczny, którego będę używać w celu uzupełnienia The Little MLer.
haziz
6

Napisz sobie program w ciągu 48 godzin (w haskell)

Naprawdę polecam to. Nauczysz się Haskell przy użyciu prawdziwego i interesującego problemu, a nauczysz się najlepszej lekcji schematu z gry z zbudowanym przez ciebie tłumaczem. Jeśli wybierzesz się na tę trasę, przygotuj kilka dobrych prezentacji w Haskell. Zrozumiesz je lepiej, jeśli masz problem do rozwiązania.

John F. Miller
źródło
Użyłem tej wiki / pdf, aby nauczyć się Haskell i odświeżyć moje umiejętności OCaml (tłumacząc idiomatic Haskell na OCaml). Byłoby całkiem fajnie, gdyby ktoś mógł wziąć ten materiał i „rozwidlić” go na kilka funkcjonalnych języków. Może to być podstawa całkiem fajnej funkcjonalnej strzelanki językowej!
Marc
1
Główny problem polega na tym, że wprowadza parsec bez wprowadzania monad.
alternatywny
@alternative parsec ma interfejs Monadic, ale ma także interfejs Applicative, nie wspominając już o wielu innych funkcjach. Przedstawienie Parsec przed monadycznym uogólnieniem nie jest zbyt nierozsądne
Philip JF
4

Poszedłbym z Haskellem. W schemacie możesz zostać popchnięty do robienia procedur, a jego system typów nie jest tak pomocny jak Haskella, co jest świetne dla początkujących, ponieważ sprawdza, czy Twój kod jest poprawny w czasie kompilacji.

alternatywny
źródło
3
„w zasadzie sprawdza, czy kod jest poprawny” jest bardzo błędne. Żaden system typów nie może tego zrobić. (Chyba że twój system typów jest prawdziwym dowodem twierdzeń.)
Eli Barzilay,
4
@Eli, użyłeś Haskell? Chociaż teoretycznie to stwierdzenie jest oczywiście fałszywe, w praktyce uważam, że jest dość dokładne, przynajmniej w porównaniu z każdym innym językiem, którego użyłem. To powiedziawszy, nie zgadzam się, że jest to dobra właściwość dla początkującego. Kiedy uczę się lin, wolę raczej zobaczyć, co mój kod źle zrobił, niż kompilować mnie, że to źle, i walczyć z nim, gdy nawet nie znam słownictwa używanego przez komunikaty o błędach.
1
@Eli „prawie” jest tutaj kluczowym terminem. W Haskell spędzasz więcej czasu zastanawiając się, jak go wdrożyć, a następnie wdrożenie przychodzi dość łatwo. Następnie sprawdź to, aby upewnić się, że twoje mapy, fałdy itp. Są zdrowe.
alternatywny
@Eli Barzilay: System typów Haskella wydaje się być bardzo bliski bycia twierdzącym twierdzeniem. Z pewnością stworzyło środowisko, w którym dowody twierdzeń wydają się prawie bardziej powszechne niż inne narzędzia. (Nie to, że
sugeruję
@luqui - Tak, użyłem go; nie, to wciąż fałszywe stwierdzenie, zarówno w praktyce, jak i teorii. Nie jest to jednak coś, co jest unikalne dla Haskell.
Eli Barzilay,
1

Myślę, że łatwo dać się wciągnąć w dyskusje na temat języków i nie rozumieć o co chodzi. Dla kogoś, kto chce się dowiedzieć, na czym polega FP, różnice między Ocaml / ML / Scheme / Haskell nie są w połowie tak ważne, jak komfort korzystania z materiałów (książek, filmów, narzędzi), których używasz do nauki. I czy masz przyjaciela, który pomoże ci nauczyć się określonego języka, przebija wszystko inne.

autodidakto
źródło
0

Jeśli nie jest czysty, równie dobrze możesz użyć języka rozkazującego, więc Haskell.

pyon
źródło
0

W jednej z odpowiedzi, które otrzymałeś na swoje pytanie, uznałem ten link za całkiem interesujący, ponieważ daje on przedsmak Haskell i Scheme.

Oprócz tego fajnego linku, oto moje zdanie na twoje pytanie.

Jeśli pochodzisz z konieczności programowania, możesz włożyć dużo wysiłku w naukę programowania funkcjonalnego. Upewniłbym się, że nauka nie jest pusta. Oznacza to, że możesz zastosować go do swojej obecnej lub następnej pracy lub że pomoże ci to w inny sposób.

Istnieje wiele dobrych języków. Ludzie Scali wychwalali ich język, podobnie jak ludzie Clojure i CL. Nawet Pythoniści twierdzą, że lenistwo. Inne osoby, które odpowiedziały, sugerowały ML. Amit Rathore, która napisała Clojure in Action, może nawet zasugerować, byś nauczył się Haskell.

Wspomniałeś o Windows i F #. Czy to pomoże ci na twojej obecnej pozycji? Nic nie wiem o F #. Czy to wystarczy? Pytam o to, ponieważ IMHO Python ma konstrukcje funkcjonalne, ale to nie jest jak programowanie w Clojure.

Podsumowując, naucz się funkcjonalnego języka, który jest „naprawdę” funkcjonalny i czyni to w najlepszym przypadku dla twojej sytuacji.

octopusgrabbus
źródło
-2

Z względnego punktu widzenia początkującego sugeruję, aby nie zaczynać od SICP, jeśli zdecydujesz się na Schemat, chyba że twoja matematyka jest dość dojrzała. Książka i filmy są pełne subtelności i wcale nie są intuicyjne dla kogoś, kto zaczyna.

varreli
źródło