Jakie są podstawowe różnice między Haskell i F #? [Zamknięte]

135

Szukałem w Internecie porównań między F # i Haskellem, ale nie znalazłem niczego naprawdę ostatecznego. Jakie są podstawowe różnice i dlaczego miałbym wybierać jedną z nich?

ljs
źródło
1
Zaletą języka F # jest to, że ze względu na swój mieszany paradygmat zapewnia lepszy punkt wyjścia dla programisty obiektowego. Potrafi stopniowo przyspieszyć myślenie funkcjonalne i nadal korzystać z dobrze znanych bibliotek obiektów obiektowych, tak jak w C #. Haskell wymusza na tobie całą funkcjonalną enchiladę naraz.
Mario
Należy zauważyć, że F # nie jest funkcjonalnym językiem programowania. Jednak trochę zaadoptował z FP, więc można znaleźć być może wiele podobieństw, ale przede wszystkim powiedziałbym, że są to całkowicie różne języki.
MasterMastic

Odpowiedzi:

128

Haskell jest „czystym” językiem funkcjonalnym, w którym F # ma aspekty zarówno języków imperatywnych / obiektowych, jak i funkcjonalnych. Haskell ma również leniwą ocenę, co jest dość rzadkie wśród języków funkcjonalnych.

Co to oznacza? Czysty język funkcjonalny oznacza, że ​​nie ma żadnych skutków ubocznych (lub zmian w stanie współdzielonym, gdy wywoływana jest funkcja), co oznacza, że ​​masz gwarancję, że jeśli wywołasz f (x), nic innego się nie dzieje poza zwróceniem wartości z funkcji, takie jak dane wyjściowe konsoli, dane wyjściowe bazy danych, zmiany zmiennych globalnych lub statycznych ... i chociaż Haskell może mieć nieczyste funkcje (za pośrednictwem monad), musi być „jawnie” implikowane poprzez deklarację.

Czysto funkcjonalne języki i programowanie bez efektów ubocznych zyskały ostatnio popularność, ponieważ dobrze nadają się do współbieżności wielordzeniowej, ponieważ znacznie trudniej jest popełnić błąd bez współdzielonego stanu, niż niezliczone blokady i semafory.

Leniwa ocena ma miejsce, gdy funkcja NIE jest oceniana, dopóki nie jest to absolutnie konieczne. co oznacza, że ​​wielu operacji można uniknąć, gdy nie są one konieczne. Pomyśl o tym w podstawowej C # klauzuli if, takiej jak ta:

if(IsSomethingTrue() && AnotherThingTrue())
{
    do something;
}

Jeśli IsSomethingTrue()jest fałszywe, AnotherThingTrue()metoda nigdy nie jest oceniana.

Chociaż Haskell jest niesamowitym językiem, główną zaletą F # (na razie) jest to, że znajduje się on na szczycie CLR. To nadaje się do programowania poliglotów. Pewnego dnia możesz napisać swój internetowy interfejs użytkownika w ASP.net MVC, logikę biznesową w C #, podstawowe algorytmy w języku F #, a testy jednostkowe w Ironruby ... Wszystko to w ramach .Net.

Posłuchaj radia Software Engineering z Simonem Peytonem Jonesem, aby uzyskać więcej informacji na temat Haskell: Episode 108: Simon Peyton Jones on Functional Programming and Haskell

Xian
źródło
8
Inną potencjalną główną zaletą języka F # (w zależności od sytuacji) jest to, że nie jest leniwy, co oznacza, że ​​krzywa uczenia się rozumowania zachowań czasoprzestrzennych będzie znacznie prostsza dla praktycznie każdego.
cjs
5
Bezpośredni link do odcinka 108 se-radio (Simon Peyton Jones): se-radio.net/podcast/2008-08/…
Herrmann
9
Inną cechą, na którą warto zwrócić uwagę, jest to, że język, który wymusza czyste programowanie, kompilator ma DUŻO więcej swobody w wielu optymalizacjach. Języki takie jak F #, które zachęcają do czystości, ale nadal pozwalają na upuszczenie niesprawdzonych nieczystych operacji w dowolnym bloku kodu, tracą na niektórych potencjalnych optymalizacjach, ponieważ kompilator jest zmuszony założyć, że każde wywołanie zawiera niezbędne efekty uboczne.
Ben
12
@JonHarrop: To stwierdzenie dotyczące algorytmów, które nie ma związku z zastosowaniem optymalizacji kompilatora. Języki o wymuszonej czystości generalnie pozwalają na pisanie jawnie nieczystego kodu, jeśli naprawdę tego potrzebujesz (jeśli nic innego, używając FFI do wywołania C). Kompilator może swobodniej stosować transformacje kodu, gdy nie jest zobowiązany do zachowania kolejności (nieznanych) efektów ubocznych. W językach „zachęty do czystości” piszesz w większości podobny kod, więc te same optymalizacje będą miały zastosowanie, tylko że mogą unieważnić efekty uboczne (których nie ma, ale kompilator nie może tego założyć).
Ben
3
@JonHarrop Kiedy stwierdziłem, że wszystkie były algorytmami? W każdym razie porównujemy język Haskell i F #, a nie Haskell i C. F # jest językiem „zachęcanej czystości”, więc często piszesz czysty kod. Twierdzę tylko, że ten sam kod może być często lepiej zoptymalizowany przez kompilator w ustawieniu „wymuszonej czystości”, ponieważ kompilator F # musi założyć, że wywołania mają skutki uboczne. Mówisz o przepisaniu kodu tak, aby używał innego algorytmu (takiego, który zależy od efektów ubocznych); Zajmuję się „optymalizacją” czystego kodu w F # w porównaniu z Haskellem.
Ben
53

Duże różnice:

  • Platforma
  • Orientacja obiektu
  • Lenistwo

Podobieństwa są ważniejsze niż różnice. Zasadniczo powinieneś używać F #, jeśli jesteś już na .NET, Haskell w przeciwnym razie. Poza tym OO i lenistwo oznaczają, że F # jest bliższy temu, co (prawdopodobnie) już wiesz, więc prawdopodobnie łatwiej się go nauczyć.

Platforma: Haskell ma własne środowisko uruchomieniowe, F # używa .NET. Nie wiem, jaka jest różnica w wydajności, chociaż podejrzewam, że przeciętny kod jest mniej więcej taki sam przed optymalizacją. F # ma tę zaletę, że potrzebujesz bibliotek .NET.

Orientacja obiektowa: F # ma OO i jest bardzo ostrożny, aby upewnić się, że klasy .NET są łatwe w użyciu, nawet jeśli twój kod nie jest OO. Haskell ma klasy typów, które pozwalają ci zrobić coś takiego jak OO, w dziwny sposób. Są jak mixiny Ruby skrzyżowane z funkcjami generycznymi Common Lisp. Są trochę jak interfejsy Java / C #.

Lenistwo: Haskell jest leniwy, F # nie. Lenistwo umożliwia kilka fajnych sztuczek i sprawia, że ​​niektóre rzeczy, które wyglądają na wolne, w rzeczywistości wykonują się szybko. Ale o wiele trudniej jest zgadnąć, jak szybko będzie działać mój kod. Oba języki pozwalają na użycie drugiego modelu, po prostu musisz wyraźnie o tym powiedzieć w swoim kodzie.

Drobne różnice:

  • Składnia: Haskell ma moim zdaniem nieco ładniejszą składnię. Jest trochę bardziej zwięzły i regularny, a ja lubię deklarować typy w osobnym wierszu. YMMV.
  • Narzędzia: F # ma doskonałą integrację z Visual Studio, jeśli lubisz takie rzeczy. Haskell ma również starszą wtyczkę Visual Studio , ale nie sądzę, by kiedykolwiek wyszła z wersji beta. Haskell ma prosty tryb emacsa i prawdopodobnie możesz użyć trybu tuareg w OCaml do edycji F #.
  • Efekty uboczne: Oba języki zrobić to dość oczywiste, kiedy ty się mutacji zmienne. Ale kompilator Haskella zmusza cię również do zaznaczania efektów ubocznych za każdym razem, gdy ich używasz. Praktyczna różnica polega na tym, że musisz być dużo bardziej świadomy, kiedy używasz również bibliotek z efektami ubocznymi.
Nathan Shively-Sanders
źródło
1
zobacz wydajność . Nie jestem pewien, jak to jest
legalne
35

F # należy do rodziny języków ML i jest bardzo zbliżony do OCaml. Możesz przeczytać tę dyskusję na temat różnic między Haskell i OCaml .

Mark Cidade
źródło
6
Chociaż ten link może odpowiedzieć na pytanie, lepiej jest zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia. Odpowiedzi zawierające tylko łącze mogą stać się nieprawidłowe, jeśli połączona strona ulegnie zmianie. - Z recenzji
mirabilos
33

Główną różnicą, która prawdopodobnie wynika z czystości, ale mniej widzę, o czym wspomniano, jest wszechobecne stosowanie monad. Jak często się podkreśla, monady można budować w większości języków, ale życie zmienia się znacznie, gdy są one powszechnie używane w bibliotekach, a sam ich używasz.

Monady zapewniają coś, co można zobaczyć w innych językach w znacznie bardziej ograniczony sposób: abstrakcję kontroli przepływu. Są niesamowicie przydatne i eleganckie sposoby robienia różnych rzeczy, a rok Haskella całkowicie zmienił sposób, w jaki programuję, w taki sam sposób, w jaki przejście od programowania imperatywnego do programowania obiektowego wiele lat temu zmieniło to, lub znacznie później, używając funkcji wyższego rzędu.

Niestety, w takiej przestrzeni nie ma sposobu, aby zapewnić wystarczające zrozumienie, abyś mógł zobaczyć, jaka jest różnica. W rzeczywistości żadna ilość pisania tego nie zrobi; po prostu musisz poświęcić wystarczająco dużo czasu na naukę i pisanie kodu, aby uzyskać prawdziwe zrozumienie.

Co więcej, F # czasami może stać się nieco mniej funkcjonalny lub bardziej niezręczny (z punktu widzenia programowania funkcjonalnego), gdy łączysz się z platformą / bibliotekami .NET, ponieważ biblioteki zostały oczywiście zaprojektowane z punktu widzenia OO.

Więc możesz rozważyć swoją decyzję w ten sposób: czy chcesz wypróbować jeden z tych języków, aby uzyskać szybki, stosunkowo niewielki przyrost ulepszeń, czy też chcesz poświęcić więcej czasu i uzyskać mniej natychmiastowych korzyści z czegoś większego w długoterminowy. (Lub przynajmniej, jeśli nie dostaniesz czegoś większego, łatwej możliwości szybkiego przełączenia się na drugie?) Jeśli pierwszy, wybierz F #, jeśli drugi, Haskell.

Kilka innych niepowiązanych punktów:

Haskell ma nieco ładniejszą składnię, co nie jest zaskoczeniem, ponieważ projektanci Haskella dość dobrze znali ML. Jednak „lekka” składnia języka F # znacznie przyczynia się do ulepszenia składni ML, więc nie ma tam dużej luki.

Jeśli chodzi o platformy, F # to oczywiście .NET; jak dobrze to zadziała na Mono, nie wiem. GHC kompiluje się do kodu maszynowego z własnym środowiskiem wykonawczym, działającym dobrze zarówno w systemie Windows, jak i Unix, który porównuje się z .NET w taki sam sposób, jak, powiedzmy, C ++. W pewnych okolicznościach może to być zaletą, zwłaszcza jeśli chodzi o szybkość i dostęp do maszyny na niższych poziomach. (Na przykład nie miałem problemu z pisaniem serwera DDE w Haskell / GHC; nie sądzę, abyś mógł to zrobić w jakimkolwiek języku .NET, a mimo to MS z pewnością nie chce, abyś to robił.)

cjs
źródło
2

Cóż, powiedziałbym, że główną zaletą jest to, że F # kompiluje się na platformie .NET, co ułatwia wdrażanie w systemie Windows. Widziałem przykłady, które wyjaśniły użycie F # w połączeniu z ASP.NET do tworzenia aplikacji internetowych ;-)

Z drugiej strony Haskell jest w pobliżu już od dłuższego czasu, więc myślę, że grupa ludzi, którzy są prawdziwymi ekspertami w tym języku, jest znacznie większa.

W przypadku języka F # do tej pory widziałem tylko jedną prawdziwą implementację, która jest systemem operacyjnym typu dowód osobliwości. Widziałem więcej implementacji Haskella w świecie rzeczywistym.

Erik van Brakel
źródło
4
F # miał już kilka znaczących historii sukcesu (Halo 3, AdCenter, F # dla wizualizacji), które przyćmiewają wszystko, co Haskell ma najbliżej historii sukcesu (Darcs).
JD
Warto zauważyć, że ma to oczywiście swoje wady. (Ograniczenia CLR)
MasterMastic