Michał Kuliński
2018-12-21 14:36

Dlaczego nauka programowania funkcyjnego jest ważna, mimo, że nie zalewa nas fala procesorów z setkami rdzeni pisze Wujek Bob Martin: https://michalkulinski.blogsp[...]-programowanie-funkcyjne.html

elwis

Pewnie, uwielbiam programowanie funkcyjne z powodów, które wymieniasz: łatwiej pisać, łatwiej dochodzić co się w kodzie dzieje, łatwiej robić refactor (bo można skopiować kawałek kodu nie zastanawiając się czy są jakieś zależności poza parametrami). Ponadto dobrze napisany kod w paradygmacie funkcyjnym skompilowany poprawnie będzie działać poprawnie, to oszczędza czasu i nerwu w szukaniu błędów. Nawet w pisząc w językach imperatywnych tylko najniższe części kodu piszę imperatywnie, aby utrzymać porządek.
Nie wiem jak można uważać, że PF wyklucza OO, scala jest wspaniałym przykładem, że te paradygmaty świetnie się uzupełniają. Bardzo lubię ten język.
Co do kwestii wielu rdzeni, trzeba pamiętać, że nie jest wcale powiedziane, że te rdzenie muszą być na tej samej maszynie. Można przecież prowadzić obliczenia rozproszone (jak choćby [email protected]) i takie zadanie również jest łatwiejsze jeśli kod jest napisany funkcyjnie.
Wiadomo, na początku trzeba było się przestawić na inny sposób myślenia, ale warto. Zwłaszcza w przypadku Scali, która bardzo mocno przypomina Javę, tylko jest o wiele wiele lepsza. :)

cerrato

@Michał Kuliński: "Prędkość światło została osiągnięta" -> prędkość światła :P

Michał Kuliński

@elwis Errata: pisze Robert Cecil "Wujek Bob" Martin. Ja tłumaczę. To, co napisałeś w komentarzu to miód na mą zbolałą, programistyczną duszę.

siloam

Czemu żaden język funkcyjny nie jest nawet w połowie tak popularny jak Java? Może dlatego, że chociaż zwracany jest przez funkcje za każdym razem nowy stan programu to i tak się go śledzi, i tak pisze się testy, i tak trzeba debugować kod. Samo używanie funkcji, które nie mają zależności poza parametrami to jeszcze nie jest programowanie funkcyjne. A Java, wujaszku, nie ma funkcji tylko metody. -.-

siloam

@elwis: "Zwłaszcza w przypadku Scali, która bardzo mocno przypomina Javę, tylko jest o wiele wiele lepsza. :)" Sorry, ale jeżeli ktoś pisze w Scali kod przypominający kod Javy to w większości przypadków znaczy, że nie zna Scali.

elwis

@siloam: To co mam na myśli to składnia. LISP czy Haskell mają dziwną składnię dla kogoś kto dotąd programował w jakimkolwiek popularnym języku. Składnia Scali to, z małymi odstępstwami, składnia Javy z paroma udoskonaleniami. To, że inaczej się porządkuje kod to już inna sprawa. Poza tym dostęp do całej biblioteki standardowej Javy to też wielkie ułatwienie. To podobna sytuacja jak C i C++, niby C++ jest kompatybilne wstecznie, ale jak ktoś pisze kod podobny do C w C++ to znaczy, że nie zna C++. ;))
Czemu nie są popularne? Może dlatego, że wymagaja więcej dyscypliny, trudniej w nich działać na oślep? A może po prostu dlatego, że języki imperatywne są mocno ugruntowane na rynku, więc większość ludzi je zna, więc na to jest największy nacisk na studiach i kursach, tego uczy się każdy kto chce pracować w branży itd. Natomiast zmienić sposób myślenia na funkcyjny to już potrzeba czasu... Z resztą język programowania to coś co się wdraża bardzo powoli. Języki funkcyjne wchodzą pod strzechy, ale to jeszcze kwestia lat zanim będą bardziej popularne.

siloam

Programy pisane w Scali powinny bardziej przypominać składniowo raczej F# lub Ocaml'a niż Javę. Scala to nie jest język czysto funkcyjny, ale funkcje wyższego rzędu powinny być używane tam jak najczęściej. Podobnie pattern matching, kompozycja, currying, rekurencja ogonowa etc. Normalnie kod pisany w Scali nie powinien być podobny do kodu Javy - może poza tworzeniem obiektów. Jeżeli ktoś pisze kod w Scali "mocno przypominający" kod Javy znaczy, że nie zna Scali i nie wie czym jest FP. Języki funkcyjne są stare (LISP, Scheme, ML). Miały już czas stać się popularne, ale tak się jednak nie stało. Co więcej FP nie nadaje się do wszystkiego. Np. zwracanie ciągle nowego bufora odtwarzając video jest skrajnie nieefektywne. Znaczniej bardziej optymalnie jest modyfikować jego stan i tak się to robi w praktyce. FP ma jedną sporą zaletę. Narzuca pewną dyscyplinę w pisaniu kodu, ale języków czysto funkcyjnych jest garstka. Większość z nich i tak dopuszcza pisanie zwykłego kodu imperatywnego oraz modyfikowanie stanu, więc same w sobie wcale nie chronią przed błędami typowymi dla innych języków. Języki funkcyjne są też bardziej zwięzłe, wymagają zazwyczaj mniejszej ilości kodu. Wszystko jednak zależy od programisty - nie ważne czy pisze w Scali czy Javie, bo jak ktoś pisze w Scali kod "a la Java" to lepiej niech już używa czystej Javy. To nie jest taka sama sytuacja jak z C i C++. Scala nie wyewoluowała z Javy chociaż zapewnia możliwość zgodności z Javą pod względem kodu bajtowego. To są jednak de facto odrębne języki o innych paradygmatach.

Michał Kuliński

@siloam: Jednym z paradygmatów jednego z najbardziej popularnego języka świata, o ile nie najpopularniejszego, wieloparadygmatowego języka Javascript jest paradygmat funkcyjny.

lion137

O! Wujek Bob odkrył Clojure:)

siloam

@Michał Kuliński: W Pythonie też można pisać funkcyjnie (choć lambdy są tam dość szkaradne, ładniej wyglądają z http://coconut-lang.org/).

elwis

@siloam: czy zdajesz sobie sprawę, że "podobny" to cecha, która ma wiele stopni? Chodziło mi głównie o to, że choć scala daje wiele konstrukcji, których nie ma w Javie, to jednak te konstrukcje są tak skonstruowane, że ich znaczenie jest jasne. Jeśli mamy definicję funkcji, zwykle zamiast klamerek i ciała funkcji mamy znak równości i wyrażenie. To nie jest składnia z javy, ale jest intuicyjne. W scali jest dużo konstrukcji match, nie ma ich w javie? No nie ma, ale łudząco przypominają konstrukcję switch. Klasy w scali mają parametry i mogą nie mieć ciała explicite, ale to też jest super, to po prostu oszczędność pisania. Wiesz ile czasu się do tego przyzwyczajałem? W ogóle! Tak samo z traitami, objectami i innymi. To co je łączy to to, że każdy z tych elementów jest odrobinę inne od tego co już znamy, dzięki temu szybko wchodzi w nawyk. Jak spojrzysz ja Haskella czy OCAMLa tam wszystko jest inne, więc ciężej się do nich przyzwyczaić. Analogicznie znacznie łatwiej nam się nauczyć rosyjskiego niż angielskiego, bo jest bardzo podobny do polskiego.
Fakt, programowanie funkcyjne nie jest nowe, ale jak sam wspomniałeś, realizowanie go na poziomie kodu maszynowego jest zwykle bardzo niewydajne (jak choćby w przypadku wspomnianych przez ciebie buforów). Tyle tylko, że teraz mamy szybsze komputery i lepsze kompilatory, więc tam gdzie można wykonać tworzenie nowego obiektu poprzez zmianę starego w miejscu, kompilator może to zrobić i nawet gcc -O3 to robi. Wiadomo, że to bywa zawodne, ale może lepiej podrasować narzędzia, a nie obrażać się na paradygmat, który jest dobry?

siloam

Match to słowo kluczowe znane z języków funkcyjnych. To że jest podobne w idei do switch wcale nie zmienia faktu, że Scala jest bardziej podobna do Ocaml'a niż do Javy z której zapożycza głównie model obiektowy. Sposób programowania w tych językach jest (powinien być) zupełnie inny. W Ocamlu czy F# właśnie jednym ze słów kluczowych jest match i ma ono taką samą funkcję jak w Scali. Kod funkcyjny jest bardziej zwięzły i przenośny. Świetnie sprawdza się przy tworzeniu bibliotek oraz tworzeniu modułów danego programu. Nie obrażam się na paradygmat funkcyjny. Wręcz przeciwnie. Sam go często stosuję, ale nie jestem fanatykiem, który czyni z niego jakieś panaceum na błędy programisty.

elwis

Ja też nie czynię z niego panaceum. Nic nie zastąpi umiejętności i samodyscypliny programisty. Mam też projekty w innych językach gdzie lepiej sprawdzają się. I zgadzam się, że w języku funkcyjnym programuje się inaczej. Tylko podkreślam, że język funkcjonalny pomaga pisać dobre programy, a łatwiej się przestawić jeśli chociaż składnia jest czymś co wygląda znajomo. To wszystko.