Zawsze myślałem, że programowanie funkcjonalne można wykonać w języku Python. Byłem więc zaskoczony, że Python nie otrzymał wiele wzmianek w tym pytaniu, a kiedy zostało wspomniane, zwykle nie było zbyt pozytywne. Podano jednak niewiele przyczyn (wspomniano o braku dopasowania wzorca i algebraicznych typach danych). Więc moje pytanie brzmi: dlaczego Python nie jest zbyt dobry do programowania funkcjonalnego? Czy istnieje więcej powodów niż brak dopasowania wzorca i algebraiczne typy danych? Czy te koncepcje są tak ważne dla programowania funkcjonalnego, że język, który ich nie obsługuje, może być sklasyfikowany jako funkcjonalny język programowania drugiej klasy? (Należy pamiętać, że moje doświadczenie z programowaniem funkcjonalnym jest dość ograniczone).
źródło
Odpowiedzi:
Pytanie, do którego się odwołujesz, dotyczy tego, które języki promują zarówno program OO, jak i programowanie funkcjonalne. Python nie promuje programowania funkcjonalnego, chociaż działa dość dobrze.
Najlepszym argumentem przeciwko programowaniu funkcjonalnemu w Pythonie jest to, że przypadki użycia imperative / OO są uważnie rozważane przez Guido, podczas gdy przypadki użycia programowania funkcjonalnego nie są. Kiedy piszę imperatywny Python, jest to jeden z najładniejszych języków, jakie znam. Kiedy piszę funkcjonalnego Pythona, staje się on tak brzydki i nieprzyjemny, jak przeciętny język, który nie ma BDFL .
Nie znaczy to, że jest źle, wystarczy, że będziesz musiał pracować ciężej, niż gdybyś przeszedł na język, który promuje funkcjonalne programowanie lub na pisanie OO Python.
Oto funkcjonalne rzeczy, za którymi tęsknię w Pythonie:
list
jeśli chcesz wytrwałości. (Iteratory są jednorazowe)źródło
Guido ma dobre wyjaśnienie tego tutaj . Oto najbardziej odpowiednia część:
Wyciągam z tego dwie rzeczy:
źródło
Schemat nie ma algebraicznych typów danych ani dopasowywania wzorców, ale z pewnością jest to język funkcjonalny. Irytujące rzeczy dotyczące Pythona z funkcjonalnego punktu widzenia programowania:
Crippled Lambdas. Ponieważ Lambdas może zawierać tylko wyrażenie i nie możesz zrobić wszystkiego tak łatwo w kontekście wyrażenia, oznacza to, że funkcje, które możesz zdefiniować „w locie” są ograniczone.
Jeśli są wyrażeniami, a nie wyrażeniami. Oznacza to, między innymi, że nie możesz mieć lambda z If w środku. (Jest to naprawione przez trójskładniki w Pythonie 2.5, ale wygląda brzydko.)
Guido grozi usunąć mapę, filtr i zmniejszyć raz na jakiś czas
Z drugiej strony, python ma leksykalne zamknięcia, Lambdas i wyrażenia listowe (które są tak naprawdę „funkcjonalną” koncepcją, niezależnie od tego, czy Guido to dopuszcza). W Pythonie dużo programuję w stylu „funkcjonalnym”, ale nie powiedziałbym, że jest idealny.
źródło
Nigdy nie nazwałbym Pythona „funkcjonalnym”, ale za każdym razem, gdy programuję w Pythonie, kod niezmiennie kończy się prawie wyłącznie funkcjonalnym.
Trzeba przyznać, że wynika to głównie z wyjątkowo miłego zrozumienia listy. Niekoniecznie więc sugerowałbym Python jako funkcjonalny język programowania, ale sugerowałbym programowanie funkcjonalne dla każdego, kto używa Pythona.
źródło
Pokażę kawałek kodu zaczerpnięty z odpowiedzi na „funkcjonalne” pytanie Pythona dotyczące SO
Pyton:
Haskell:
Główną różnicą jest to, że biblioteka standardowa Haskell zawiera użyteczne funkcje programowania funkcyjnego: w tym przypadku
iterate
,concat
i(!!)
źródło
grandKids()
ciała z generatora wyrażeń:return reduce(lambda a, v: concat((x for x in kidsFunc(v)) for v in a), xrange(generation), [val])
.concat
też:return reduce(lambda a, v: (x for v in a for x in kidsFunc(v)), xrange(generation), [val])
itertools.chain.from_iterable
Jedną z rzeczy, która jest naprawdę ważna dla tego pytania (i odpowiedzi) jest: Co to do cholery jest funkcjonalne programowanie i jakie są najważniejsze jego właściwości. Spróbuję przedstawić mój pogląd na to:
Programowanie funkcjonalne przypomina pisanie matematyki na tablicy. Kiedy piszesz równania na tablicy, nie myślisz o poleceniu wykonania. Nie ma (zazwyczaj) mutacji. Nie wrócisz pojutrze i nie spojrzysz na to, a kiedy ponownie wykonasz obliczenia, uzyskasz inny wynik (a może, jeśli napijesz się świeżej kawy :)). Zasadniczo to, co jest na tablicy, a odpowiedź już tam była, kiedy zacząłeś spisywać rzeczy, po prostu nie zdawałeś sobie sprawy, co to jest.
Programowanie funkcjonalne jest bardzo podobne; nie zmieniasz rzeczy, po prostu oceniasz równanie (lub w tym przypadku „program”) i zastanawiasz się, jaka jest odpowiedź. Program jest nadal niezmodyfikowany. To samo z danymi.
Za najważniejsze cechy programowania funkcjonalnego uznałbym: a) przejrzystość referencyjną - jeśli ocenisz to samo zdanie w innym miejscu i czasie, ale przy tych samych wartościach zmiennych, będzie to nadal oznaczać to samo. b) brak efektu ubocznego - bez względu na to, jak długo patrzysz na tablicę, równanie, na które patrzy inny facet, nie zmieni się przypadkowo. c) funkcje też są wartościami. które można przekazywać i stosować z innymi zmiennymi lub do nich. d) składanie funkcji, możesz zrobić h = g · f, a tym samym zdefiniować nową funkcję h (..), która jest równoważna wywołaniu g (f (..)).
Ta lista jest w mojej kolejności według priorytetów, więc przejrzystość referencyjna jest najważniejsza, a po niej nie występują żadne skutki uboczne.
Teraz, jeśli przejdziesz przez python i sprawdzisz, jak dobrze język i biblioteki obsługują i gwarantują te aspekty - jesteś na dobrej drodze, aby odpowiedzieć na swoje własne pytanie.
źródło
Python jest prawie językiem funkcjonalnym. To „funkcjonalna lite”.
Ma dodatkowe funkcje, więc dla niektórych nie jest wystarczająco czysty.
Brakuje również niektórych funkcji, więc dla niektórych nie jest wystarczająco kompletny.
Brakujące funkcje są stosunkowo łatwe do napisania. Sprawdź posty jak ten na FP w Pythonie.
źródło
Innym powodem nie wymienionym powyżej jest to, że wiele wbudowanych funkcji i metod typów wbudowanych modyfikuje obiekt, ale nie zwraca zmodyfikowanego obiektu. Gdyby te zmodyfikowane obiekty zostały zwrócone, kod funkcjonalny byłby czystszy i bardziej zwięzły. Na przykład, jeśli some_list.append (some_object) zwrócił some_list z dołączonym some_object.
źródło
Oprócz innych odpowiedzi, jednym z powodów, dla których Python i większość innych języków z wieloma paradygmatami nie są odpowiednie dla prawdziwego programowania funkcjonalnego, jest to, że ich kompilatory / maszyny wirtualne / czasy działania nie obsługują optymalizacji funkcjonalnej. Tego rodzaju optymalizację osiąga kompilator rozumiejący reguły matematyczne. Na przykład wiele języków programowania obsługuje
map
funkcję lub metodę. Jest to dość standardowa funkcja, która przyjmuje funkcję jako jeden argument, a iterowalną jako drugi argument, a następnie stosuje tę funkcję do każdego elementu w iteracji.W każdym razie okazuje się, że
map( foo() , x ) * map( foo(), y )
jest taki sam jakmap( foo(), x * y )
. Drugi przypadek jest w rzeczywistości szybszy niż pierwszy, ponieważ pierwszy wykonuje dwie kopie, podczas gdy drugi wykonuje jedną.Lepsze języki funkcjonalne rozpoznają te matematyczne zależności i automatycznie przeprowadzają optymalizację. Języki, które nie są dedykowane do paradygmatu funkcjonalnego, prawdopodobnie się nie zoptymalizują.
źródło
map( foo() , x ) * map( foo(), y ) == map( foo(), x * y )
nie jest prawdziwe dla wszystkich funkcji. Na przykład rozważmy przypadek przyfoo
obliczaniu pochodnej.+
zamiast*
.