Jakie są zalety używania języka C # w porównaniu z F # lub F # w porównaniu z C #? [Zamknięte]

93

Pracuję dla firmy technologicznej, która zajmuje się bardziej prototypowaniem niż wysyłką produktów. Właśnie zostałem zapytany, jaka jest różnica między C # i F #, dlaczego MS utworzył F # i jakie scenariusze byłyby lepsze niż C #.

Używam tego języka już od jakiegoś czasu i uwielbiam go, więc z łatwością mogłem mówić o wspaniałych funkcjach F #, jednak brakuje mi doświadczenia w C #, aby powiedzieć, dlaczego powinniśmy używać jednego nad drugim.

Jakie są zalety używania języka C # w porównaniu z F # lub F # w porównaniu z C #?

gradbot
źródło
4
Wydaje mi się, że na SO jest już sporo pytań, które przynajmniej częściowo odpowiadają na Twoje pytanie. Czy próbowałeś wyszukiwać przy użyciu „[F #] słowa kluczowego” zamiast „f # słowa kluczowego”? (na przykład „[f #] zalety”)
Benjol,

Odpowiedzi:

86

Ogólne zalety programowania funkcyjnego w porównaniu z językami imperatywnymi:

Możesz sformułować wiele problemów znacznie łatwiej, bliżej ich definicji i bardziej zwięźle w funkcjonalnym języku programowania, takim jak F #, a Twój kod jest mniej podatny na błędy (niezmienność, mocniejszy system typów, intuicyjne algorytmy rekurencyjne). Możesz zakodować to, co masz na myśli, zamiast tego, co komputer chce, żebyś powiedział ;-) Znajdziesz wiele takich dyskusji, kiedy to wyszukasz w Google lub nawet wyszukasz w SO.

Specjalne zalety języka F #:

  • Programowanie asynchroniczne jest niezwykle łatwe i intuicyjne dzięki async {}-wyrażeniom - nawet w przypadku ParallelFX odpowiedni kod C # jest znacznie większy

  • Bardzo łatwa integracja kompilatorów kompilatorów i języków specyficznych dla domeny

  • Rozszerzanie języka według potrzeb: LOP

  • Jednostki miary

  • Bardziej elastyczna składnia

  • Często krótsze i bardziej eleganckie rozwiązania

Spójrz na ten dokument

Zaletą języka C # jest to, że jest on często dokładniejszy w zastosowaniach „imperatywnych” (interfejs użytkownika, algorytmy imperatywne) niż funkcjonalny język programowania, a platforma .NET Framework, której używa, jest zaprojektowana w sposób imperatywny i że jest bardziej rozpowszechniona.

Co więcej, możesz mieć F # i C # razem w jednym rozwiązaniu, dzięki czemu możesz połączyć zalety obu języków i używać ich tam, gdzie są potrzebne.

Dario
źródło
16
Łączą się w bardzo dziwny sposób. Na przykład możesz przeciążyć operator> w F #. Programiści C # mogą go następnie używać. Jednak programiści F # nie mogą. Zgadza się, F # może emitować przeciążenia operatora, których nie może zużywać.
Jonathan Allen
link „ten dokument” jest uszkodzony ...
Eduardo Brites,
36

To tak, jakby zapytać, jaką korzyść ma młotek nad śrubokrętem. Na bardzo wysokim poziomie oba robią zasadniczo to samo, ale na poziomie implementacji ważne jest, aby wybrać optymalne narzędzie do tego, co próbujesz osiągnąć. Są zadania, które są trudne i czasochłonne w języku c #, ale łatwe w języku f # - jak próba wbicia gwóźdź śrubokrętem. Na pewno możesz to zrobić - to po prostu nie jest idealne.

Manipulacja danymi jest jednym z przykładów, które osobiście mogę wskazać, gdzie f # naprawdę świeci, a c # może być potencjalnie nieporęczny. Z drugiej strony powiedziałbym (ogólnie), że złożony stanowy interfejs użytkownika jest łatwiejszy w OO (c #) niż funkcjonalnym (f #). (Prawdopodobnie byliby ludzie, którzy się z tym nie zgadzają, ponieważ "fajnie" jest teraz "udowodnić", jak łatwo jest zrobić cokolwiek w F #, ale ja się tym trzymam). Jest wielu innych.

Rex M
źródło
22
Jeśli masz tylko młotek, wszystko wygląda jak gwóźdź. -Maslow
Charlie Salts
20
Nie zamierzam głosować za tym, ponieważ nie podaje on żadnych konkretnych szczegółów poza jednym przykładem danych. Wiem, że to różne narzędzia. Pytam, w jakich pracach te dwa narzędzia są najlepsze, a jakie najgorsze w porównaniu ze sobą. Wiem, że philips jest często najlepszym narzędziem do tego zadania, nawet jeśli mniejszy płaski głowica będzie działać.
gradbot
1
Haha, dzięki @Spencer;) @gradbot - nie ma problemu! Przepraszam, że moja odpowiedź nie jest dokładnie tym, czego szukasz ... mam nadzieję, że inni uznają ją za przydatną.
Rex M
14
Jeśli masz tylko młotek, wszystko wygląda jak kciuk.
Ed Power
6
Zgadzam się z gradbotem, to dobra odpowiedź, więc nie mam ode mnie negatywnego głosu, jednak tak naprawdę nie prowadzi to do szczegółów oryginalnych pytań. Ta odpowiedź jest tylko niejasnym wyjaśnieniem pojęciowym, ale tak naprawdę mija się z celem dokładnej odpowiedzi na pytanie.
Stan R.
27
  • F # ma lepszą wydajność niż C # w matematyce
  • Możesz używać projektów F # w tym samym rozwiązaniu z C # (i wywoływać między nimi)
  • F # jest naprawdę dobry w przypadku złożonych zastosowań programowania algorytmicznego, finansowych i naukowych
  • F # logicznie jest naprawdę dobry do wykonywania równoległego (łatwiej jest wykonać kod F # na rdzeniach równoległych, niż C #)
Rinat Abdullin
źródło
6
O F # mając lepszą wydajność niż C # dla matematyki: Najwyraźniej to nieprawda. Zobacz thinkfulcode.wordpress.com/2010/12/30/…
Joh
3
@Joh: inlinejest oczywistym przykładem czegoś, co może zapewnić znaczną poprawę wydajności w języku F #, której C # nie może wyrazić.
JD
@Jon Harrop: Odniosłem się konkretnie do wpisu na blogu Rinata. Wygląda na to, że czasy na korzyść F #, które otrzymał, wynikały z nieoptymalnego kodu C #.
Joh
27

Aby odpowiedzieć na twoje pytanie tak, jak je rozumiem: Dlaczego używać C #? (Mówisz, że jesteś już sprzedany na F #.)

Po pierwsze. Nie chodzi tylko o „funkcjonalność kontra OO”. To „Funkcjonalne + OO kontra OO”. Funkcje funkcjonalne języka C # są dość podstawowe. F # nie są. W międzyczasie F # wykonuje prawie wszystkie funkcje OO języka C #. W większości F # kończy się jako nadzbiór funkcji języka C #.

Jest jednak kilka przypadków, w których F # może nie być najlepszym wyborem:

  • Interop. Istnieje wiele bibliotek, które po prostu nie będą zbyt wygodne w języku F #. Być może wykorzystują pewne rzeczy C # OO, których F # nie robi tego samego, albo może polegają na wewnętrznych elementach kompilatora C #. Na przykład Expression. Chociaż można łatwo przekształcić cytat F # w wyrażenie, wynik nie zawsze jest dokładnie tym, co utworzyłby C #. Niektóre biblioteki mają z tym problem.

    • Tak, interop to dość duża sieć i może powodować pewne tarcia z niektórymi bibliotekami.

    • Uważam, że interop obejmuje również, jeśli masz dużą istniejącą bazę kodu. Pisanie części w języku F # może nie mieć sensu.

  • Narzędzia projektowe. F # nie ma żadnych. Nie oznacza to, że nie może ich mieć, ale teraz nie możesz uruchomić aplikacji WinForms za pomocą kodu F #. Nawet tam, gdzie jest obsługiwana, na przykład na stronach ASPX, obecnie nie jest dostępna technologia IntelliSense. Musisz więc dokładnie rozważyć, jakie będą twoje granice dla wygenerowanego kodu. W przypadku naprawdę małego projektu, w którym prawie wyłącznie korzystają różni projektanci, może nie być warto używać F # do „kleju” lub logiki. W przypadku większych projektów może to stać się mniejszym problemem.

    • To nie jest wewnętrzny problem. W przeciwieństwie do odpowiedzi Rexa M, nie widzę niczego wewnętrznego w C # lub F #, co czyniłoby je lepszymi do tworzenia interfejsu użytkownika z wieloma zmiennymi polami. Może odnosił się do dodatkowego obciążenia związanego z napisaniem „mutable” i użyciem <- zamiast =.

    • Zależy również od używanej biblioteki / projektanta. Uwielbiamy używać ASP.NET MVC z F # dla wszystkich kontrolerów, a następnie projekt sieci Web C #, aby uzyskać projektantów ASPX. W zależności od tego, czego potrzebujemy na tej stronie, mieszamy rzeczywisty „kod wbudowany” ASPX między C # i F #. (IntelliSense a typy F #).

  • Inne narzędzia. Mogą po prostu oczekiwać tylko języka C # i nie wiedzieć, jak radzić sobie z projektami F # lub skompilowanym kodem. Ponadto biblioteki F # nie są dostarczane jako część .NET, więc masz trochę więcej do wysłania.

  • Ale problem numer jeden? Ludzie. Jeśli żaden z twoich programistów nie chce uczyć się F # lub, co gorsza, nie ma poważnych trudności ze zrozumieniem pewnych aspektów, prawdopodobnie masz toast. (Chociaż w takim przypadku i tak uważam, że jesteś upieczony.) Och, a jeśli kierownictwo powie nie, to może być problem.

Pisałem o tym jakiś czas temu: Dlaczego NIE F #?

MichaelGG
źródło
6

Prosisz o porównanie między językiem proceduralnym a językiem funkcjonalnym, więc czuję, że odpowiedź na twoje pytanie można znaleźć tutaj: Jaka jest różnica między programowaniem proceduralnym a programowaniem funkcjonalnym?

Jeśli chodzi o to, dlaczego MS stworzyło F #, odpowiedź jest prosta: stworzenie języka funkcjonalnego z dostępem do biblioteki .Net po prostu rozszerzyło ich bazę rynkową. A widząc, że składnia jest prawie identyczna z OCaml, naprawdę nie wymagało to dużego wysiłku z ich strony.

Spencer Ruport
źródło
1
Chociaż myślę, że twoja ogólna odpowiedź jest prawidłowa, że ​​prawdziwe pytanie dotyczy porównania paradygmatów programowania, a nie języków, czuję, że odpowiedź w pytaniu, o którym mówisz, jest trochę płytka.
Jeroen Huinink
Jeśli masz lepsze, możesz zasugerować inne pytanie. To najwyżej oceniony wynik, jaki znalazłem w wyszukiwarce Google.
Spencer Ruport
1
Myślę, że starał się być miły, jeśli chodzi o to, że brzmiałeś jak osioł, że powiedział, że F # nie wymagało dużego wysiłku ze strony Micrsoft.
Matthew Whited
1
Nie kupuję tego innego linku, odpowiadającego na moje pytanie. C # obsługuje wiele konstrukcji funkcjonalnych w nowszych wersjach.
gradbot
C # vs F #! = Proceduralne vs funkcjonalne.
JD,
5

F # nie jest jeszcze innym językiem programowania, jeśli porównujesz go z C #, C ++, VB. C #, C, VB to imperatywne lub proceduralne języki programowania. F # to funkcjonalny język programowania.

Dwie główne zalety języków programowania funkcyjnego (w porównaniu z językami imperatywnymi) to: 1. brak efektów ubocznych. To znacznie ułatwia matematyczne rozumowanie na temat właściwości twojego programu. 2. że funkcje są obywatelami pierwszej kategorii. Możesz przekazywać funkcje jako parametry do innych funkcji równie łatwo, jak inne wartości.

Zarówno imperatywne, jak i funkcjonalne języki programowania mają swoje zastosowania. Chociaż nie wykonałem jeszcze żadnej poważnej pracy w F #, obecnie wdrażamy komponent planowania w jednym z naszych produktów w oparciu o C # i zamierzamy przeprowadzić eksperyment, kodując ten sam harmonogram w F #, aby sprawdzić, czy poprawność implementację można zweryfikować łatwiej niż w przypadku jej odpowiednika w języku C #.

Jeroen Huinink
źródło
4
-1. F # jest językiem wieloparadygmatowym (OO + FP). Tylko języki czysto funkcjonalne nie mają skutków ubocznych (jak Haskell), ale F # nie jest czysty.
Mauricio Scheffer
5

F # to zasadniczo C ++ języków programowania funkcjonalnego. Zachowali prawie wszystko z Objective Caml, w tym naprawdę głupie części, i wrzucili go do środowiska uruchomieniowego .NET w taki sposób, że zawiera również wszystkie złe rzeczy z .NET.

Na przykład w przypadku Objective Caml otrzymujesz jeden typ wartości null, opcję <T>. Za pomocą F # otrzymujesz trzy typy wartości null, option <T>, Nullable <T> i odwołania do wartości null. Oznacza to, że jeśli masz opcję, musisz najpierw sprawdzić, czy jest to „Brak”, a następnie musisz sprawdzić, czy jest to „Niektóre (null)”.

F # jest jak stary klon Java J #, tylko po to, by przyciągnąć uwagę. Niektórym się spodoba, kilku nawet będzie go używać, ale ostatecznie jest to nadal dwudziestoletni język dołączony do CLR.

Jonathan Allen
źródło
Mam nadzieję, że masy nadadzą im trochę sensu, a F # 5 będzie nieco bardziej pragmatyczny.
Jonathan Allen
1
Zgadzam się, że Nullable <T> powinien mieć kompilator do wykonania za nas magicznego aliasingu. Nie jestem pewien, czy ustawienie „Some null” jako odpowiednika None zawsze zadziała - jakiś kod międzyoperacyjny może na tym polegać. Ale odniesienie zerowe? Jak zamierzasz obejść poważną lukę w .NET? Owinąć każdy typ odniesienia w opcji? W praktyce wydaje się to problemem tylko w przypadku niektórych scenariuszy międzyoperacyjnych.
MichaelGG
12
FWIW, od kilku lat profesjonalnie programuję w języku F # (dłużej niż prawie ktokolwiek inny na świecie) i Some nullnigdzie nie widziałem tego problemu ani kodu w żadnym kodzie F #. Ze wszystkich rzeczy, ludzie mogą narzekać o, to musi być waaay w dół na liście ...
JD
1
Porównanie F # z C ++ jest nieco naciągane. Wiele części C ++ ma niezdefiniowaną lub niejasną semantykę, F # jest prosty i dobrze zdefiniowany. Jakość środowiska uruchomieniowego .NET nie może być porównywana z F #, ponieważ każdy język .NET będzie miał te same problemy.
Joh
1
W ciągu ponad 2 lat profesjonalnego programowania F #, takiego jak @Jon, nigdy nie widziałem żadnego problemu związanego z „Some null”. Z drugiej strony, ogromnie skorzystałem na funkcjach frameworka .Net.
Marc Sigrist
5

Jednym z aspektów .NET, które najbardziej lubię, są generyczne. Nawet jeśli piszesz kod proceduralny w języku F #, nadal będziesz korzystać z wnioskowania o typie. Ułatwia pisanie kodu ogólnego.

W języku C # domyślnie piszesz konkretny kod i musisz włożyć trochę dodatkowej pracy, aby napisać kod ogólny.

W języku F # domyślnie piszesz kod ogólny. Po ponad roku programowania w językach F # i C # stwierdzam, że kod biblioteki, który piszę w języku F #, jest zarówno bardziej zwięzły, jak i bardziej ogólny niż kod, który piszę w C #, a zatem jest również bardziej wielokrotnego użytku. Brakuje mi wielu okazji do pisania kodu ogólnego w C #, prawdopodobnie dlatego, że oślepiają mnie obowiązkowe adnotacje typu.

Są jednak sytuacje, w których preferowane jest używanie języka C #, w zależności od gustu i stylu programowania.

  • C # nie narzuca kolejności deklaracji między typami i nie jest wrażliwy na kolejność, w jakiej są kompilowane pliki.
  • C # ma pewne niejawne konwersje, na które F # nie może sobie pozwolić z powodu wnioskowania o typie.
Joh
źródło