Wiele innych odpowiedzi skupiało się na stronie wydajności (równoległości) programowania funkcjonalnego, co moim zdaniem jest bardzo ważne. Jednak zapytałeś konkretnie o produktywność, na przykład, czy możesz zaprogramować to samo szybciej w paradygmacie funkcjonalnym niż w imperatywnym.
Właściwie (z własnego doświadczenia) uważam, że programowanie w języku F # pasuje do sposobu, w jaki myślę, lepiej, więc jest łatwiej. Myślę, że to największa różnica. Programowałem zarówno w F #, jak i C #, aw F # jest dużo mniej „walki z językiem”, co uwielbiam. Nie musisz myśleć o szczegółach w F #. Oto kilka przykładów tego, co naprawdę mi się podoba.
Na przykład, mimo że F # jest wpisywany statycznie (wszystkie typy są rozwiązywane w czasie kompilacji), wnioskowanie o typie określa, jakie typy masz, więc nie musisz tego mówić. A jeśli nie może tego zrozumieć, automatycznie tworzy funkcję / klasę / cokolwiek ogólnego. Więc nigdy nie musisz pisać żadnych ogólnych, wszystko dzieje się automatycznie. Uważam, że oznacza to, że spędzam więcej czasu na myśleniu o problemie, a mniej na tym, jak go wdrożyć. W rzeczywistości za każdym razem, gdy wracam do C #, odkrywam, że naprawdę tęsknię za tego typu wnioskami, nigdy nie zdajesz sobie sprawy, jak rozpraszające to jest, dopóki nie musisz już tego robić.
Również w języku F #, zamiast pisać pętle, wywołujesz funkcje. To subtelna zmiana, ale znacząca, ponieważ nie musisz już myśleć o konstrukcji pętli. Na przykład, oto fragment kodu, który mógłby przejść i dopasować coś (nie pamiętam co, to z projektu układanki Euler):
let matchingFactors =
factors
|> Seq.filter (fun x -> largestPalindrome % x = 0)
|> Seq.map (fun x -> (x, largestPalindrome / x))
Zdaję sobie sprawę, że zrobienie filtru, a potem mapy (czyli konwersji każdego elementu) w C # byłoby całkiem proste, ale trzeba myśleć na niższym poziomie. W szczególności musiałbyś napisać samą pętlę i mieć własną wyraźną instrukcję if i tego typu rzeczy. Od kiedy nauczyłem się F #, zdałem sobie sprawę, że łatwiej jest kodować w sposób funkcjonalny, gdzie jeśli chcesz filtrować, piszesz „filtr”, a jeśli chcesz mapować, piszesz „mapa”, zamiast implementować każdy szczegół.
Uwielbiam także operator |>, który moim zdaniem oddziela F # od ocaml i być może innych języków funkcjonalnych. Jest to operator potoku, który pozwala ci "potokować" wyjście jednego wyrażenia do wejścia innego wyrażenia. To sprawia, że kod podąża za tym, jak myślę. Podobnie jak w powyższym fragmencie kodu, to mówi: „weź sekwencję czynników, przefiltruj ją, a następnie zmapuj”. To bardzo wysoki poziom myślenia, którego nie opanujesz w imperatywnym języku programowania, ponieważ jesteś tak zajęty pisaniem pętli i instrukcji if. To jedyna rzecz, której najbardziej brakuje mi, gdy przechodzę na inny język.
Tak więc ogólnie, mimo że mogę programować zarówno w C #, jak i F #, łatwiej mi jest używać F #, ponieważ można myśleć na wyższym poziomie. Twierdzę, że ponieważ mniejsze szczegóły zostały usunięte z programowania funkcjonalnego (przynajmniej w F #), jestem bardziej produktywny.
Edycja : Widziałem w jednym z komentarzy, że prosiłeś o przykład „stanu” w funkcjonalnym języku programowania. F # można napisać imperatywnie, więc oto bezpośredni przykład tego, jak można mieć zmienny stan w F #:
let mutable x = 5
for i in 1..10 do
x <- x + i