Ostatnio dużo mówiłem o używaniu języków funkcjonalnych, takich jak Haskell. Jakie są duże różnice, zalety i wady programowania funkcjonalnego w porównaniu z programowaniem obiektowym?
Ostatnio dużo mówiłem o używaniu języków funkcjonalnych, takich jak Haskell. Jakie są duże różnice, zalety i wady programowania funkcjonalnego w porównaniu z programowaniem obiektowym?
Odpowiedzi:
Powiedziałbym, że jest bardziej Programowanie funkcyjne vs Imperatyw Programowanie .
Największa różnica polega na tym, że programowanie imperatywne dotyczy przepływu sterowania, podczas gdy programowanie funkcjonalne dotyczy przepływu danych . Innym sposobem jest powiedzenie, że programowanie funkcjonalne używa tylko wyrażeń, podczas gdy w programowaniu imperatywnym używane są zarówno wyrażenia, jak i instrukcje .
Na przykład w imperatywnym programowaniu zmienne i pętle są powszechne podczas obsługi stanu, podczas gdy w programowaniu funkcjonalnym stan jest obsługiwany przez przekazywanie parametrów, co pozwala uniknąć efektów ubocznych i przypisań.
Pseudo-kod imperatywny dla funkcji do obliczania sumy listy (suma jest przechowywana w zmiennej):
int sumList(List<int> list) {
int sum = 0;
for(int n = 0; n < list.size(); n++) {
sum = sum + list.get(n);
}
return sum;
}
Funkcjonalny pseudo-kod dla tej samej funkcji (suma jest przekazywana jako parametr):
fun sumList([], sum) = sum
| sumList(v::lst, sum) = sumList(lst, v+sum)
Polecam prezentację Taming Effects with Functional Programming autorstwa Simona Peytona-Jonesa, która stanowi dobre wprowadzenie do koncepcji funkcjonalnych.
Programowanie funkcjonalne oparte jest na modelu deklaratywnym i wywodzi się z rachunku lambda. Oferuje wiele świetnych koncepcji, które można wypożyczyć z bardziej imperatywnych języków, takich jak C ++ i C #.
Niektóre przykłady obejmują przejrzystość referencyjną, funkcje lambda, funkcje pierwszej klasy, leniwe i chętne oceny oraz niezmienność.
Jeśli na nic innego uczenie się programowania funkcjonalnego jest przydatne dla zawartych w nim pojęć. Zmieni to sposób programowania i myślenia o programowaniu. Sądzę, że w przyszłości programowanie funkcjonalne będzie równie ważne, jak programowanie obiektowe.
Aby rozpocząć, możesz użyć czysto funkcjonalnego języka, takiego jak Haskell, lub możesz użyć języka hybrydowego, takiego jak F # .
Większość dobrych uniwersytetów będzie zajmować się programowaniem funkcjonalnym, a jeśli pójdziesz do szkoły, bardzo sugeruję, abyś wybrał ten kurs.
Jakie są duże różnice, zalety i wady programowania funkcjonalnego w porównaniu z programowaniem obiektowym?
Dobrze zorientowane obiektowo programowanie jest dobre, ponieważ pozwala modelować złożony problem w hierarchie, dzięki czemu można uprościć problem. Ale staje się bardzo trudne, gdy zaczynasz rozważać programowanie wielowątkowe podczas korzystania ze zmiennych obiektów. W takich przypadkach musisz intensywnie korzystać z obiektów synchronizacji, a doskonalenie dużej aplikacji jest prawie niemożliwe.
W tym miejscu pojawia się programowanie funkcjonalne. Z powodu niezmienności programowanie funkcjonalne naprawdę upraszcza programy wielowątkowe. To sprawia, że prawie w prosty sposób można zrównoleglić coś, gdy wiesz, że dane wejście X do funkcji zawsze będzie generować Y. Ponadto wiesz, że zmienna (lub wartość w programowaniu funkcjonalnym) nie może zmienić środka użycia z innego wątku.
(Ta odpowiedź jest dostosowywana z odpowiedzi na pytanie zamknięte w StackOverflow .)
Jedną z dużych różnic między programowaniem funkcjonalnym a programowaniem obiektowym jest to, że każdy z nich jest lepszy w różnego rodzaju ewolucji oprogramowania:
Języki zorientowane obiektowo są dobre, gdy masz ustalony zestaw operacji na rzeczach , a wraz z rozwojem kodu dodajesz przede wszystkim nowe rzeczy. Można to osiągnąć przez dodanie nowych klas, które implementują istniejące metody, a istniejące klasy pozostawia się w spokoju.
Języki funkcjonalne są dobre, gdy masz stały zestaw rzeczy , a wraz z ewolucją kodu dodajesz przede wszystkim nowe operacje na istniejących rzeczach. Można to osiągnąć przez dodanie nowych funkcji, które obliczają z istniejącymi typami danych, a istniejące funkcje są pozostawione same sobie.
Kiedy ewolucja idzie w złym kierunku, masz problemy:
Dodanie nowej operacji do programu obiektowego może wymagać edycji wielu definicji klas w celu dodania nowej metody.
Dodanie nowego rodzaju rzeczy do programu funkcjonalnego może wymagać edycji wielu definicji funkcji, aby dodać nowy przypadek.
Problem ten jest dobrze znany od wielu lat; w 1998 roku Phil Wadler nazwał to „problemem ekspresji” . Chociaż niektórzy badacze uważają, że problem z ekspresją można rozwiązać za pomocą takich cech językowych, jak mixiny, powszechnie akceptowane rozwiązanie nie znalazło się jeszcze w głównym nurcie.
Nie ma prawdziwego kontra. Mogą się doskonale uzupełniać. Istnieją języki FP, które obsługują OOP. Ale społeczności różnią się sposobem obsługi modułowości.
Użytkownicy języków FP mają tendencję do osiągania modułowości dzięki prawom matematyki. I wolą dowody potwierdzające zgodność z ich przepisami.
W trybie bezwzględnym użytkownicy OOP mają tendencję do rejestrowania zachowania obiektu w przypadkach testowych, które mogą być uruchomione ponownie, jeśli obiekt się zmienił i uzyskują w ten sposób modułowość.
To tylko mały aspekt, ale myślę, że warto o tym wspomnieć.
Analogia:
Otrzymałeś podanie o pracę. Podajesz swoje imię i nazwisko, dane kontaktowe i historię pracy. Po zakończeniu nie będziesz już mieć pustej aplikacji.
Zamiast tego wyobraź sobie, że przed napisaniem nałóż ją na przezroczystą warstwę celofanu. Piszesz swoje imię Dodajesz kolejny arkusz celofanu. Podajesz swoje dane kontaktowe. Więcej celofanu. Piszesz swoją historię pracy. Po zakończeniu nadal pozostaje pusta aplikacja. Masz również trzy arkusze celofanu, z których każdy uchwycił efekt pojedynczej, dyskretnej zmiany.
Pierwszy (OOP) popiera pomysł zmiany rzeczy na miejscu, podczas gdy drugi (FP) odrzuca go. Oba są paradygmatami zarządzania stanem. Obie mogą, stosując różne strategie, uchwycić efekt wypełnienia podania o pracę. OOP zmienia instrument początkowy bezpośrednio, podczas gdy FP nakłada się na to, co było wcześniej, aby wpłynąć na pojawienie się zmiany .