Jako mój pierwszy język programowania zdecydowałem się nauczyć języka Haskell. Jestem magistrem filozofii analitycznej i Haskell pozwolił mi szybko i poprawnie tworzyć interesujące programy, na przykład przetworniki do analizowania języka naturalnego, weryfikatory twierdzeń i interpretatory. Chociaż programuję dopiero od dwóch i pół miesiąca, okazało się, że semantyka i składnia Haskella są znacznie łatwiejsze do nauczenia niż bardziej tradycyjne języki imperatywne i czuję się komfortowo (teraz) z większością jej konstrukcji.
Programowanie w Haskell jest jednak jak magia i chciałbym poszerzyć swoją wiedzę o programowaniu. Chciałbym wybrać nowy język programowania do nauki, ale nie mam wystarczająco dużo czasu, aby wybrać dowolny język, porzucić go i powtórzyć. Pomyślałem więc, że postawię tutaj pytanie, wraz z kilkoma zastrzeżeniami dotyczącymi rodzaju języka, którego szukam. Niektóre są subiektywne, inne mają na celu ułatwienie przejścia z Haskella.
- Mocny system typów. Jedną z moich ulubionych części programowania w Haskell jest pisanie deklaracji typu. Pomaga to uporządkować moje przemyślenia na temat poszczególnych funkcji i ich związku z programem jako całością. Ułatwia również nieformalne rozumowanie o poprawności mojego programu. Martwię się o poprawność, a nie efektywność.
- Nacisk na rekursję, a nie na iterację. Używam konstrukcji iteracyjnych w Haskell, ale implementuję je rekurencyjnie. Jednak znacznie łatwiej jest zrozumieć strukturę funkcji rekurencyjnej niż skomplikowaną procedurę iteracyjną, zwłaszcza gdy używa się kombinatorów i funkcji wyższego rzędu, takich jak mapy, fałdy i wiązania.
- Warto się uczyć. Haskell jest satysfakcjonujące język do pracy. To trochę jak czytanie Kanta. Moje doświadczenie z C kilka lat temu jednak nie było. Nie szukam C. Język powinien narzucać interesujący koncepcyjnie paradygmat, którego w moim całkowicie subiektywnym przekonaniu nie lubi C.
Ważenie odpowiedzi : to oczywiście tylko notatki. Chciałbym tylko odpowiedzieć każdemu, kto udzielił dobrze sformułowanych odpowiedzi. Byłeś bardzo pomocny.
1) Kilka odpowiedzi wskazywało, że silny, statycznie typowany język z naciskiem na rekurencję oznacza inny język funkcjonalny. Chociaż chcę nadal mocno współpracować z Haskellem, camccann i larsmans słusznie wskazali, że inny taki język „za bardzo ułatwiłby przejście”. Te komentarze były bardzo pomocne, ponieważ nie chcę pisać Haskell w Caml! Spośród asystentów dowodu, Coq i Agda wyglądają interesująco. W szczególności Coq stanowiłby solidne wprowadzenie do logiki konstruktywnej i teorii typów formalnych. Spędziłem trochę czasu z predykatem pierwszego rzędu i logiką modalną (Mendellsohn, Enderton, niektórzy Hinman), więc prawdopodobnie miałbym dużo zabawy z Coq.
2) Inni mocno preferowali Lisp (Common Lisp, Scheme and Clojure). Z tego, co wiem, zarówno Common Lisp, jak i Scheme mają doskonały materiał wprowadzający ( On Lisp and The Reasoned Schemer , SICP ). Materiał w SICP skłania mnie do Scheme. W szczególności Schemat poprzez SICP obejmowałby inną strategię oceny, wdrażanie lenistwa i możliwość skupienia się na tematach takich jak kontynuacja, tłumacze ustni, obliczenia symboliczne i tak dalej. Wreszcie, jak zauważyli inni, podejście Lispa do kodu / danych byłoby całkowicie nowe. Dlatego skłaniam się mocno w stronę opcji (2), Lispa.
3) Po trzecie, Prolog. Prolog ma bogactwo interesujących materiałów, a jego główna domena jest dokładnie tą, która mnie interesuje. Ma prostą składnię i jest łatwa do odczytania. W tej chwili nie mogę nic więcej komentować, ale po przeczytaniu przeglądu Prologu i przejrzeniu kilku materiałów wprowadzających, otrzymałem wynik (2). Wygląda na to, że Haskell zawsze hakuje cofanie się Prologa!
4) Spośród języków głównego nurtu Python wygląda najciekawiej. Tim Yates sprawia, że języki brzmią bardzo atrakcyjnie. Najwyraźniej Python jest często nauczany na pierwszym roku specjalizacji CS; więc jest albo bogata koncepcyjnie, albo łatwa do nauczenia. Musiałbym przeprowadzić więcej badań.
Dziękuję wszystkim za rekomendacje! Wygląda na to, że Lisp (Scheme, Clojure), Prolog lub asystent dowodu, taki jak Coq lub Agda, są głównymi zalecanymi językami.
źródło
Odpowiedzi:
Obawiam się, że możesz tutaj trochę za bardzo ułatwiać przejście. Bardzo ścisły system typów i czysto funkcjonalny styl są charakterystyczne dla Haskella i prawie wszystko, co przypomina główny język programowania, będzie wymagało przynajmniej pewnego kompromisu w jednym z nich. Mając to na uwadze, oto kilka ogólnych sugestii, których celem jest zachowanie większości tego, co lubisz w Haskellu, ale z pewnymi znaczącymi zmianami.
Zignoruj praktyczność i wybierz „więcej Haskella niż Haskella” : system typów Haskella jest pełen dziur z powodu nieterminacji i innych niechlujnych kompromisów. Posprzątaj bałagan i dodaj bardziej zaawansowane funkcje, a otrzymasz języki takie jak Coq i Agda , w których typ funkcji zawiera dowód jej poprawności (możesz nawet odczytać strzałkę funkcji
->
jako logiczną implikację!). Języki te były używane w dowodach matematycznych i w programach o wyjątkowo wysokich wymaganiach dotyczących poprawności. Coq jest prawdopodobnie najbardziej znanym językiem tego stylu, ale Agda ma bardziej haskellowy charakter (poza tym, że jest napisana w samym języku Haskell).Zignoruj typy, dodaj więcej magii : jeśli Haskell jest magią, Lisp jest surową, pierwotną magią tworzenia. Języki z rodziny Lisp (w tym również Scheme i Clojure ) mają prawie niezrównaną elastyczność w połączeniu z ekstremalnym minimalizmem. Języki zasadniczo nie mają składni i piszą kod bezpośrednio w postaci drzewiastej struktury danych; metaprogramowanie w Lispie jest łatwiejsze niż programowanie niemeta w niektórych językach.
Kompromisu trochę i zbliżyć się do głównego nurtu : Haskell wpada do szerokiej rodziny języków wpłynęły w dużym stopniu przez ML, z których każdy można prawdopodobnie przesuwają się bez zbyt wiele trudności. Haskell jest jednym z najsurowszych, jeśli chodzi o gwarancje poprawności wynikające z typów i stosowania stylu funkcjonalnego, gdzie inne często są stylami hybrydowymi i / lub z różnych powodów dokonują pragmatycznych kompromisów. Jeśli chcesz mieć ekspozycję na OOP i dostęp do wielu popularnych platform technologicznych, albo Scala na JVM, albo F #na .NET mają wiele wspólnego z Haskell, zapewniając jednocześnie łatwą współpracę z platformami Java i .NET. F # jest obsługiwany bezpośrednio przez firmę Microsoft, ale ma pewne irytujące ograniczenia w porównaniu z Haskell i problemy z przenośnością na platformach innych niż Windows. Scala ma bezpośrednie odpowiedniki w większym stopniu w systemie typów Haskella i wieloplatformowym potencjale Javy, ale ma bardziej ciężką składnię i brakuje jej potężnego wsparcia własnego, z którego korzysta F #.
Większość z tych zaleceń jest również wspomniana w innych odpowiedziach, ale mam nadzieję, że moje uzasadnienie dla nich dostarcza pewnego oświecenia.
źródło
Mam zamiar być tym facetem i zasugerować, że prosisz o niewłaściwą rzecz.
Najpierw mówisz, że chcesz poszerzyć swoje horyzonty. Następnie opisujesz rodzaj języka, który chcesz, a jego horyzonty brzmią niewiarygodnie jak te, które już masz. Nie wiele zyskasz, ucząc się w kółko tego samego.
Proponuję nauczyć się Lispa - tj. Common Lisp, Scheme / Racket lub Clojure. Wszystkie są domyślnie wpisywane dynamicznie, ale zawierają pewne wskazówki dotyczące typu lub opcjonalne wpisywanie statyczne. Racket i Clojure to prawdopodobnie najlepsze zakłady.
Clojure jest nowszy i ma więcej Haskellizmów, takich jak domyślnie niezmienność i dużo leniwej oceny, ale jest oparty na wirtualnej maszynie Java, co oznacza, że ma kilka dziwnych brodawek (np. JVM nie obsługuje eliminacji wywołań ogonowych, więc rekursja jest miła włamania).
Rakieta jest znacznie starsza, ale po drodze zyskała wiele mocy, takich jak obsługa typów statycznych i nacisk na programowanie funkcjonalne. Myślę, że prawdopodobnie wyciągniesz jak najwięcej z Racketa.
Systemy makr w Lisps są bardzo interesujące i znacznie potężniejsze niż cokolwiek, co zobaczysz gdziekolwiek indziej. Samo to jest warte przynajmniej uwagi.
źródło
Z punktu widzenia tego, co pasuje do twojego kierunku, oczywistym wyborem wydaje się język logiczny, taki jak Prolog lub jego pochodne. Programowanie logiczne można wykonać bardzo starannie w języku funkcjonalnym (patrz np. The Reasoned Schemer ), ale możesz czerpać przyjemność bezpośrednio z paradygmatu logiki.
Interaktywny system dowodzenia twierdzeń, taki jak twelf lub coq, również może Ci się spodobać.
źródło
Radziłbym ci nauczyć się Coq , który jest potężnym pomocnikiem dowodu ze składnią, która będzie wygodna dla programisty Haskell. Fajną rzeczą w Coq jest to, że można go wyodrębnić do innych języków funkcjonalnych, w tym Haskell. Jest nawet pakiet ( Meldable-Heap ) na Hackage, który został napisany w Coq, miał właściwości potwierdzone jego działanie, a następnie został wyodrębniony do Haskella.
Innym popularnym językiem, który oferuje więcej mocy niż Haskell, jest Agda - nie znam Agdy poza tym, że wiem, że jest pisana zależnie, na hackage i szanowana przez ludzi, których szanuję, ale to są dla mnie wystarczające powody.
Nie spodziewałbym się, że którekolwiek z nich będzie łatwe. Ale jeśli znasz Haskell i chcesz przejść do języka, który daje więcej mocy niż system typów Haskell, powinieneś to rozważyć.
źródło
Ponieważ nie wspomniałeś o żadnych ograniczeniach poza subiektywnymi zainteresowaniami i kładziesz nacisk na `` satysfakcjonujące uczenie się '' (no dobrze, zignoruję ograniczenie statycznego pisania), sugerowałbym naukę kilku języków o różnych paradygmatach, a najlepiej takich, które są „wzorowe” dla każdego z nich.
Zwłaszcza Lisps (CL nie tak bardzo jak Scheme) i Prolog (i Haskell) obejmują rekurencję.
Chociaż nie jestem guru w żadnym z tych języków, spędziłem trochę czasu z każdym z nich, z wyjątkiem Erlang i Forth, i wszystkie dały mi otwierające oczy i interesujące doświadczenia edukacyjne, ponieważ każdy z nich podchodzi do rozwiązywania problemów z innej perspektywy .
Tak więc, chociaż może się wydawać, że zignorowałem część dotyczącą tego, że nie masz czasu na wypróbowanie kilku języków, myślę raczej, że czas spędzony z którymkolwiek z nich nie pójdzie na marne i powinieneś przyjrzeć się im wszystkim.
źródło
Co powiesz na język programowania zorientowany na stos ? Kot osiąga najlepsze wyniki. To jest:
Dr Dobbs opublikował krótki artykuł o Cat w 2008 roku, chociaż język nieco się zmienił.
źródło
Jeśli chcesz mieć silnie napisany Prolog, Mercury jest interesującym wyborem. Parałem się tym w przeszłości i podobała mi się inna perspektywa, jaką mi dała. Ma również modację (które parametry muszą być wolne / stałe) i determinizm (ile jest wyników?) W systemie typów.
Clean jest bardzo podobny do Haskella, ale ma unikalne typowanie, które jest używane jako alternatywa dla monad (a dokładniej monady IO). Wpisywanie unikalności ma również interesujący wpływ na pracę z tablicami.
źródło
Trochę się spóźniłem, ale widzę, że nikt nie wspomniał o kilku paradygmatach i powiązanych językach, które mogą Cię zainteresować ze względu na ich wysoki poziom abstrakcji i ogólności:
źródło
Pomimo niespełnienia jednego z twoich dużych kryteriów (wpisywanie statyczne *), zamierzam przedstawić argumenty za Pythonem. Oto kilka powodów, dla których myślę, że powinieneś się temu przyjrzeć:
Rozumiem, jeśli szukasz czegoś innego. Na przykład programowanie logiczne może być na twojej drodze, jak sugerowali inni.
* Zakładam, że masz na myśli wpisywanie statyczne, ponieważ chcesz zadeklarować typy. Z technicznego punktu widzenia Python jest językiem silnie typizowanym, ponieważ nie można dowolnie interpretować, powiedzmy, ciągu znaków jako liczby. Co ciekawe, istnieją pochodne Pythona, które pozwalają na statyczne pisanie, takie jak Boo .
źródło
map
,filter
itp Ale nadal, generatory i wyrażenia generatorów poczuje zna kogoś, kto zna oceny leniwy i wspomnianej funkcji.Polecam Erlang. Nie jest to silny język maszynowy i powinieneś go wypróbować. Jest to zupełnie inne podejście do programowania i może się okazać, że istnieją problemy, w których silne pisanie nie jest najlepszym narzędziem (TM). W każdym razie Erlang zapewnia narzędzia do statycznej weryfikacji typu (typer, dializator) i możesz używać silnego pisania na częściach, w których uzyskujesz z tego korzyści. To może być dla Ciebie interesujące doświadczenie, ale bądź przygotowany, będzie to zupełnie inne uczucie. Jeśli szukasz „konceptualnie interesującego paradygmatu”, możesz je znaleźć w Erlangu, przekazywaniu wiadomości, rozdzielaniu pamięci zamiast dzielenia się, dystrybucji, OTP, obsłudze błędów i propagacji błędów zamiast „zapobiegania” błędom i tak dalej. Erlang może być daleko od twojego obecnego doświadczenia, ale nadal łaskotać mózg, jeśli masz doświadczenie z C i Haskellem.
źródło
Biorąc pod uwagę twój opis, sugerowałbym Ocaml lub F # .
Rodzina ML jest ogólnie bardzo dobra pod względem mocnego systemu czcionek. Wyraźny jest również nacisk na rekursję w połączeniu z dopasowywaniem wzorców.
Trochę się waham, jeśli chodzi o satysfakcjonującą część nauki . Bez wątpienia uczenie się ich było dla mnie satysfakcjonujące. Ale biorąc pod uwagę twoje ograniczenia i twój opis tego, czego chcesz, wydaje się, że tak naprawdę nie szukasz czegoś znacznie bardziej odmiennego niż Haskell.
Gdybyś nie narzucił swoich ograniczeń, zasugerowałbym Pythona lub Erlanga , które wyprowadziłyby cię ze strefy komfortu.
źródło
Z mojego doświadczenia wynika, że mocne pisanie + nacisk na rekurencję oznacza kolejny funkcjonalny język programowania. Z drugiej strony zastanawiam się, czy to bardzo satysfakcjonujące, biorąc pod uwagę, że żaden z nich nie będzie tak „czysty” jak Haskell.
Jak sugerowały inne plakaty, Prolog i Lisp / Scheme są ładne, mimo że oba są dynamicznie wpisywane. Opublikowano wiele wspaniałych książek o silnym teoretycznym „upodobaniu” do nich, w szczególności na temat Schematu. Spójrz na SICP , który również przekazuje wiele ogólnej wiedzy informatycznej (interpretery meta-okólne i tym podobne).
źródło
Factor będzie dobrym wyborem.
źródło
Możesz zacząć przeglądać Lispa .
Prolog to też fajny język.
źródło
Jeśli zdecydujesz się odejść od preferowanego systemu typów, możesz być zainteresowany językiem programowania J. Wyróżnia się tym, jak podkreśla kompozycję funkcji. Jeśli lubisz styl bez punktów w Haskell, cicha forma J będzie satysfakcjonująca. Uważam, że jest to niezwykle prowokujące do myślenia, zwłaszcza w odniesieniu do semantyki.
To prawda, że nie pasuje to do twoich uprzedzeń co do tego, co chcesz, ale spójrz na to. Warto wiedzieć, że jest tam, gdzie jest. Jedynym źródłem kompletnych wdrożeń jest J Software, jsoftware.com.
źródło
Idź z jednym z głównych strumieni. Biorąc pod uwagę dostępne zasoby, przyszłą atrakcyjność rynkową Twoich umiejętności, bogaty ekosystem programisty, myślę, że powinieneś zacząć od języka Java lub C # .
źródło
Świetne pytanie - ostatnio zadawałem to sobie pytanie, po tym jak spędziłem kilka miesięcy na dokładnej zabawie z Haskellem, chociaż moje doświadczenie jest zupełnie inne (chemia organiczna).
Tak jak ty, C i jemu podobni nie wchodzą w grę.
Oscylowałem między Pythonem i Ruby jako dwoma praktycznymi językami skryptowymi dla koni roboczych (muły?), Które mają pewne funkcjonalne komponenty, aby mnie uszczęśliwić. Nie rozpoczynając tutaj żadnych debat o Rubyistach / Pythonistach, ale moja osobista pragmatyczna odpowiedź na to pytanie brzmi:
Naucz się tego (Python lub Ruby), do którego jako pierwszy masz pretekst.
źródło