Wątek przeniesiony 2021-03-22 10:23 z Nietuzinkowe tematy przez cerrato.

Programowanie funkcyjne - Haskell, Lisp etc.

1

O co ten cały szum z programowanie funkcyjnym? Dla mnie naturalne rozumienie komputera to programowanie imperatywne (chyba że deklaratywny SQL). Rozumiem, że są przydatne elementy programowania funkcyjnego w JavaScript czy Javie. W korporacjach można też stosować różne immutable struktury. Ale jakie jest zastosowanie języków prawdziwie funkcyjnych jak Haskell czy Lisp w realnej gospodarce? Czy są to języki od dziesięcioleci wyłącznie badawcze na uczelniach, formalizmy matematyczne do rozwiązywania prostych zagadek, czy mają albo mogą mieć w przyszłości jakieś praktyczne zastosowanie?

0

2

Nie znam sie, ale wypowiem. Niektóre algorytmy są bardzo wygodne implementacji w językach funkcyjnych. Generalnie algorytmy rekurencyjne bardzo fajnie się pisze funkcyjnie. a potem np można stosować elementy z f# w c# co też jest bardzo spoko.

2

Powiem wam tylko tyle że podczas kompilacji kod Haskella przekształcany jest do języka C. W kolejnej fazie kompilator C tworzy plik wynikowy. Wydaje się wam, że to Haskell a to jest specjalna wersja języka C...

6
randomowy napisał(a):

Dla mnie naturalne rozumienie komputera to programowanie imperatywne (chyba że deklaratywny SQL).

Tylko tak Ci się wydaje, bo nauka programowania u każdej znanej mi osoby zaczyna się od programowania imperatywnego. To, że potrafisz tak rozumować nie znaczy, że jest to naturalne - po prostu masz z tym większe doświadczenie. Imperatywność jest naturalna dla maszyny, nie dla człowieka.

ple napisał(a):

Powiem wam tylko tyle że podczas kompilacji kod Haskella przekształcany jest do języka C. W kolejnej fazie kompilator C tworzy plik wynikowy. Wydaje się wam, że to Haskell a to jest specjalna wersja języka C...

XD A C to specjalna wersja asemblera, podobnie jak większość języków.

3

Programując funkcyjnie łatwo utrzymać porządek w kodzie. Jak masz czystą funkcję, łatwiej jest określić czy jest poprawna czy nie. Poza tym, ułatwia to zrównoleglanie kodu.

3

Serwis lichess.org jest napisany w Scali i działa wybornie w porównaniu z chess.com, który jest napisany w cholera-wie-czym, więc domniemuję, że w funkcyjności jest jakaś wartość dodana. Natomiast należy wiedzieć kiedy warto a kiedy nie warto stosować.

Programy funkcyjne łatwiej się analizuje, bo masz tak jakby jeden wymiar mniej - nie jest istotna kolejność wykonania operacji, a jedynie ich wzajemne zależności. Zrównoleglanie też zwykle przychodzi łatwiej. Natomiast z drugiej strony trudniej o dobrą wydajność (w sensie wydajności z jednego rdzenia). Struktury niemutowalne zwykle wprowadzają znaczny narzut w porównaniu z odpowiednikami mutowalnymi.

1

Programowanie funkcyjne nadaje pewne właściwości funkcją, skopiuje je z książki dla ułatwienia:
They are idempotent
They offer referential transparency
They are memoizable
They can be lazy
They’re easier to reason about
They’re easier to combine
They’re easier to test
They’re easier to debug
They’re easier to parallelize

Skoro funkcja X nie zapisuje stanów wewnętrznych i nie odczytuje ich (np zmienna klasy, funkcja rand(), odczytywanie z pliku) oznacza to, że wynik funkcji X będzie zawsze taki sam. Bo polega ona tylko na swoim wewnętrznym stanie. Dzięki temu zachodzi np. właściwość referential transparency

Skoro funkcja X nie zapisuje stanów wewnętrznych i nie odczytuje ich, oznacza to, że nie mamy powodu wywoływania ją póki nie będziemy potrzebować jej wyniku, więc zróbmy ją lazy

Skoro funkcja X nie zapisuje stanów wewnętrznych i nie odczytuje ich, oznacza to, że nie da się napisać tak funkcji, żeby miała sens i zwracała void, tzn

void func(String s) {
 //wpisz coś do tej funkcji sensownego, że nie zapisuje stanów wewnętrznych i nie odczytuje ich, ale ktoś nadal będzie potrzebował tej funkcji (funkcje haczyki się nie liczą)
}

nie ma takiej funkcji, oznacza to, że wystarczy przetestować co funkcja zwraca (czy to testy manualne czy jednostkowe). Dodatkowo, takie testy jednostkowe będą nastawione na zwracany stan nie behawioralność funkcji

ITP ITD

1

W przeszłości były podejmowane próby komercjalizacji e.g. https://en.wikipedia.org/wiki/Lisp_machine, jak widzisz nie bardzo to wypaliło.

Osobiście uważam że języki czysto funkcyjne (zwłaszcza Haskell) są tworzone przez oszołomów matematyków, dla których czytelność kodu czy cała otoczka inżynieryjna projektu (unit testy, benchmarki, system build'u i zarządzania zależnościami, IDE, debuggery, lintery itp). nie istnieje. Jeżeli już takie języki miały by gdzieś znaleźć zastosowanie to raczej w firmach typu Google, ale te w przekorny sposób stawiają na sprawdzone w boju technologie typu Java i C++ (a ostatnio także Go). Facebook używał Ocamla do tworzenia kompilatorów swojego Hack'a ale to też bardziej sfera badań i rozwoju.

Nota bene warto również zauważyć ze czysto obiektowe języki typu Smalltalk również się nie przyjęły. W przypadku SmallTalk'a powód był podobny, zapomniano o współpracy z istniejącymi bibliotekami, kod nie był traktowany jako tekst (Class Browser), deployment był dziwny (trzeba było wgrywać obraz maszyny wirtualnej SmallTalka).

Z drugiej strony "brzydkie" języki programowania, które nie mają oporów przed dodawaniem pragmatycznych funkcjonalności jak JS, Java i C++ mają się bardzo dobrze...

W sumie dla mnie jedyny "czysto" funkcyjny język który ma jako takie szanse na szerszą adopcję to F# (Scala to raczej chimera FP i OOP).

PS. Warto jeszcze popatrzeć na zmianę języka z punktu widzenia biznesu. Dawno dawno temu przejście assembler -> prog. strukturalne dawało olbrzymie zyski z produktywności i spadek liczby błędów. Potem nastąpiła długa era panowania C i Pascala aż w końcu dotarliśmy do ściany o nazwie duże projekty z olbrzymią (jak na tamte czasy) liczbą programistów i linii kodu. C bez przestrzeni nazw, paczek itp. nie pozwalał w wydajny sposób zarządzać dużymi bazami kodu. I tak na scenę wtoczył się C++ zapewniając właśnie to, ładne grupowanie metod w obiekty. Rozszerzało to znacznie przestrzeń nazw bo teraz 100 obiektów mogło mieć metodę add i nie było żadnych konfliktów. Potem projekty nadal rosły, na scenie pojawił się internet - jest to moment wzrostu znaczenia języków skryptowych takich jak Perl i potem PHP które oferowały dużą produktywność w pracy z siecią Web. Moment ten wykorzystała też Java, rozwiązując po stronie backendu problemy C++ - to jest brak biblioteki standardowej + GC.
FF 20 lat i jesteśmy w 2021, czy istnieje obecnie język FP który ma killer feature? Wydaje mi się że nie. Kilka lat temu wydawało się że takim killer feature'em będzie programowanie równoległe ale zarówno C# jak i Java rozwiązały ten problem za pomocą bibliotek (do tego doszło programowanie reaktywne).

Powyższe rozumownie wyjaśnia też dlaczego np. Kotlin ma takie trudności z adopcją. Biznes nie zmieni języka tylko dlatego żeby programistom się lepiej pisało (a przynajmniej nie do czas aż Ci masowo zaczną składać wypowiedzenia lub będzie bardzo duży problem z rekrutacją nowych ludzi). Żeby nastąpił zmiana nowy język musi dostarczać czego co zagwarantuje olbrzymi wzrost produktywności. Ostatnią taką rzeczą była chmura. Można się zastanowić czy w językach programowania taki wzrost jest jeszcze w ogóle możliwy?

2
randomowy napisał(a):

O co ten cały szum z programowanie funkcyjnym? Dla mnie...

Dla ciebie może i tak, dla coraz większej liczby osób nie.

Ale jakie jest zastosowanie języków prawdziwie funkcyjnych jak Haskell czy Lisp w realnej gospodarce?

Nie wiem jak z Haskellem czy LISPem, ale modele event-based (czyli bardzo duża część gospodarki, od czujników zaczynając) są czymś naturalnym dla programowania funkcyjnego, natomiast w modelu imperatywnym trzeba tworzyć różne dziwne fikołki.

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0