Programowanie funkcjonalne i programowanie niefunkcjonalne

Na drugim roku studiów "uczono nas" Haskella, prawie nic o tym Nie wiem, a jeszcze mniej o programowaniu funkcyjnym.

Co to jest programowanie funkcyjne, dlaczego i / xor gdzie chciałbym go używać zamiast programowania niefunkcjonalnego i czy mam rację myśląc, że C jest niefunkcjonalnym językiem programowania?

Author: Braiam, 2008-08-23

9 answers

Jedną z kluczowych cech języka funkcjonalnego jest pojęcie funkcji pierwszej klasy. Chodzi o to, że można przekazywać funkcje jako parametry innym funkcjom i zwracać je jako wartości.

Programowanie funkcyjne polega na pisaniu kodu, który nie zmienia stanu. Głównym powodem tego jest to, że kolejne wywołania funkcji dadzą ten sam wynik. Możesz pisać kod funkcyjny w dowolnym języku, który obsługuje funkcje pierwszej klasy, ale istnieją pewne języki, takie jak Haskell, które nie pozwalają na zmianę stanu. W rzeczywistości nie powinieneś robić żadnych efektów ubocznych (takich jak drukowanie tekstu) - co brzmi, jakby mogło być całkowicie bezużyteczne.

Haskell zamiast tego stosuje inne podejście do IO: monads. Są to obiekty, które zawierają żądaną operację IO do wykonania przez najwyższy poziom interpretera. Na każdym innym poziomie są po prostu obiektami w systemie.

Jakie korzyści daje programowanie funkcjonalne? Funkcjonalne programowanie pozwala na kodowanie z mniejszym potencjałem błędów, ponieważ każdy komponent jest całkowicie izolowany. Ponadto użycie funkcji rekurencyjnych i pierwszorzędnych pozwala na proste dowody poprawności, które zazwyczaj odzwierciedlają strukturę kodu.

 84
Author: Kyle Cronin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-23 15:39:15

Czym jest programowanie funkcyjne

Istnieją dwie różne definicje "programowania funkcyjnego" w powszechnym użyciu dzisiaj:

Starsza definicja (pochodząca z Lispu) mówi, że programowanie funkcyjne polega na programowaniu przy użyciu funkcji pierwszej klasy, tzn. gdzie funkcje są traktowane jak każda inna wartość, dzięki czemu można przekazać funkcje jako argumenty do innych funkcji, a funkcja może zwracać funkcje między zwracanymi wartościami. Kończy się to wykorzystaniem funkcje wyższego rzędu, takie jak map i reduce (Być może słyszałeś o mapReduce jako pojedynczej operacji używanej w dużym stopniu przez Google i, co zaskakujące, jest to bliski krewny!). Typy. NET System.Func i System.Action sprawiają, że funkcje wyższego rzędu są dostępne w C#. Chociaż currying jest niepraktyczny w C#, Funkcje akceptujące inne funkcje jako argumenty są powszechne, np. funkcja Parallel.For.

Młodsza definicja (spopularyzowana przez Haskella) jest taka, że programowanie funkcjonalne to także minimalizacja i kontrolowanie efektów ubocznych, w tym mutacji, czyli pisanie programów rozwiązujących problemy poprzez komponowanie wyrażeń. Jest to potocznie nazywane "programowaniem czysto funkcjonalnym". Jest to możliwe dzięki szalenie różnym podejściom do struktur danych zwanych "czysto funkcjonalnymi strukturami danych". Jednym z problemów jest to, że tłumaczenie tradycyjnych algorytmów imperatywnych na wykorzystanie czysto funkcjonalnych struktur danych zwykle powoduje, że wydajność jest 10x gorsza. Haskell jest jedynym zachowanym programowaniem czysto funkcjonalnym język, ale pojęcia wkradły się do głównego nurtu programowania z bibliotekami takimi jak Linq na .NET.

Gdzie chciałbym go używać zamiast programowania niefunkcjonalnego

Wszędzie. Lambda w C# wykazały teraz duże korzyści. C++11 ma lambda. Nie ma wymówki, żeby nie używać funkcji wyższego rzędu. Jeśli możesz używać języka takiego jak F#, skorzystasz również z wnioskowania typu, automatycznego uogólniania, curryingu i częściowego zastosowania (a także wielu innych funkcji językowych!).

Czy mam rację myśląc, że C jest niefunkcjonalnym językiem programowania?

Tak. C jest językiem proceduralnym. Jednak można uzyskać niektóre korzyści z programowania funkcyjnego za pomocą wskaźników funkcji i void * W C.
 21
Author: Jon Harrop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-27 16:15:40

Może warto zajrzeć do tego artykułu na F# "101" Na CoDe Mag Ostatnio dodane.

Ponadto, Dustin Campbell ma świetny blog , gdzie opublikował wiele artykułów na temat swoich przygód na temat bycia na bieżąco z F#..

Mam nadzieję, że ci się przydadzą:)

EDIT:

Ponadto, aby dodać, moje rozumienie programowania funkcyjnego jest takie, że Wszystko jest funkcją lub parametrami funkcji, a nie instancjami / obiektami stanu.. Ale Ja could be wrong F # is something I am dying to get in to but just dont have the time! :)

 6
Author: Rob Cooper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-23 15:08:20

John the Statistician 's example code does not show functional programming, because when you' re doing functional programming, the key is that the code does not ASSIGNMENTS (record = thingConstructor(t) is an assignment), and it has NO SIDE EFFECTS (localMap.put(record) is a statement with a side effect). W wyniku tych dwóch ograniczeń wszystko, co robi Funkcja, jest w pełni przechwytywane przez jej argumenty i jej wartość zwracaną. Przepisanie kodu Statystyka tak, jak musiałby wyglądać, jeśli chcesz emulacja języka funkcyjnego za pomocą C++:

RT getOrCreate(const T thing, 
                  const Function<RT<T>> thingConstructor, 
                  const Map<T,RT<T>> localMap) {
    return localMap.contains(t) ?
        localMap.get(t) :
        localMap.put(t,thingConstructor(t));
}

W wyniku Zasady no side-effects każde polecenie jest częścią zwracanej wartości (stąd return pochodzi pierwszy ), a każde polecenie jest wyrażeniem. W językach, które wymuszają Programowanie funkcyjne, słowo kluczowe return jest implikowane, a instrukcja if zachowuje się jak operator ?: W C++.

Ponadto wszystko jest niezmienne, więc localMap.put musi utworzyć nową kopię localMap i zwrócić ją, zamiast modyfikowanie oryginalnego localMap , tak jak zrobiłby to zwykły program C++ lub Java. W zależności od struktury localMap, Kopia może ponownie użyć wskaźników do oryginału, zmniejszając ilość danych, które mają być skopiowane.

Niektóre z zalet programowania funkcyjnego obejmują fakt, że programy funkcjonalne są krótsze i łatwiej jest zmodyfikować program funkcjonalny (ponieważ nie ma ukrytych globalnych efektów do wzięcia pod uwagę), i łatwiej jest uzyskać program od samego początku.

Jednak programy funkcjonalne zwykle działają powoli (z powodu całego kopiowania, które muszą wykonać) i nie mają tendencji do interakcji z innymi programami, procesami systemu operacyjnego lub systemami operacyjnymi, które zajmują się adresami pamięci, little-endian blokami bajtów i innymi specyficznymi dla maszyny, niefunkcjonalnymi bitami. Stopień nieinteraktywności jest zwykle odwrotnie skorelowany ze stopniem czystości funkcjonalnej i ścisłością systemu typu.

Bardziej popularne języki funkcyjne mają bardzo, bardzo ścisłe systemy typów. W OCAML nie można nawet mieszać liczb całkowitych i zmiennoprzecinkowych ani używać tych samych operatorów (+służy do dodawania liczb całkowitych, +. jest do dodawania pływaków). Może to być zaletą lub wadą, w zależności od tego, jak wysoko cenisz zdolność sprawdzania typów do łapania pewnych rodzajów błędów.

Języki funkcyjne mają również bardzo duże środowiska uruchomieniowe. Haskell jest wyjątkiem (GHC pliki wykonywalne są prawie tak małe jak programy C, zarówno w czasie kompilacji, jak i w czasie wykonywania), ale SML, Common Lisp i programy Scheme zawsze wymagają mnóstwa pamięci.

 4
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-18 00:27:26

Tak masz rację myśląc, że C jest językiem niefunkcjonalnym. C jest językiem proceduralnym.

 3
Author: robintw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-23 15:10:44

Wolę używać programowania funkcyjnego, aby zaoszczędzić sobie powtarzających się prac, tworząc bardziej abstrakcyjną wersję, a następnie używając jej zamiast. Podam przykład. W Javie często zdarza mi się tworzyć mapy do rejestrowania struktur, a tym samym pisać struktury getOrCreate.

SomeKindOfRecord<T> getOrCreate(T thing) { 
    if(localMap.contains(t)) { return localMap.get(t); }
    SomeKindOfRecord<T> record = new SomeKindOfRecord<T>(t);
    localMap = localMap.put(t,record);
    return record; 
}
To się zdarza bardzo często. Teraz, w języku funkcjonalnym mógłbym napisać
RT<T> getOrCreate(T thing, 
                  Function<RT<T>> thingConstructor, 
                  Map<T,RT<T>> localMap) {
    if(localMap.contains(t)) { return localMap.get(t); }
    RT<T> record = thingConstructor(t);
    localMap = localMap.put(t,record);
    return record; 
}

I już nigdy nie będę musiał pisać nowego, mógłbym je odziedziczyć. Ale mógłbym zrobić coś lepszego niż dziedziczenie, Mogę powiedzieć w konstruktorze tego czegoś

getOrCreate = myLib.getOrCreate(*,
                                SomeKindOfRecord<T>.constructor(<T>), 
                                localMap);

(Gdzie * jest rodzajem notacji "pozostaw ten parametr otwarty", która jest rodzajem curryingu)

I wtedy lokalny getOrCreate jest dokładnie taki sam, jak by to było, gdybym napisał całość, w jednej linijce, bez zależności dziedziczenia.

 3
Author: John with waffle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-24 12:53:55

Jeśli szukasz dobrego tekstu na F#

Expert F # jest współautorem Don Syme. Twórca F#. Pracował nad generics w. NET specjalnie, aby mógł stworzyć F#.

F # jest wzorowany na OCaml, więc każdy tekst OCaml pomoże Ci również nauczyć się F#.

 2
Author: Brian Leahy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-08-23 17:54:14

Znajduję Czym jest Programowanie funkcyjne? to be useful

Programowanie funkcyjne polega na pisaniu czystych funkcji, na usuwaniu ukrytych wejść i wyjść w miarę możliwości, tak aby jak najwięcej naszych Kod jak to tylko możliwe opisuje zależność między wejściami i wyjścia.

Preferuj explicit when param

public Program getProgramAt(TVGuide guide, int channel, Date when) {
  Schedule schedule = guide.getSchedule(channel);

  Program program = schedule.programAt(when);

  return program;
}

Over

public Program getCurrentProgram(TVGuide guide, int channel) {
  Schedule schedule = guide.getSchedule(channel);

  Program current = schedule.programAt(new Date());

  return current;
}

Język funkcjonalny jest aktywnie wrogo nastawiony do efektów ubocznych. Skutki uboczne to złożoność i złożoność to błędy, a błędy to diabeł. Język funkcjonalny pomoże Ci być wrogo nastawionym do efektów ubocznych.

 1
Author: onmyway133,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-07 08:24:20

W informatyce Programowanie funkcyjne jest paradygmatem programowania-stylem budowania struktury i elementów programów komputerowych-który traktuje obliczenia jako ocenę funkcji matematycznych i unika C wiszących i zmiennych danych. Jest to paradygmat programowania deklaratywnego, co oznacza, że programowanie odbywa się za pomocą wyrażeń. W kodzie funkcyjnym, wartość wyjściowa funkcji zależy tylko od argumentów, które są wprowadzane do funkcji, więc wywołanie funkcja f dwa razy o tej samej wartości dla argumentu x da taki sam wynik f(x) za każdym razem. Wyeliminowanie skutków ubocznych, czyli zmian stanu, które nie zależą od wejść funkcji, może znacznie ułatwić zrozumienie i przewidzenie zachowania programu, co jest jedną z kluczowych motywacji do rozwoju programowania funkcyjnego. Zobacz więcej szczegółów w wiki . niektóre przykłady funkcjonalnych języków programowania są jak scala, javascript...etc

 1
Author: madhu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-16 11:02:50