Programare functionala = programare folosind functii Nu sunt functii si in C? Ce nu pot face cu o functie in C, dar pot face in Haskell: int f(int x) { return x; } - nu pot trimite ca argument unei functii o alta functie (pot trimite un numar intreg, o structura, ...) !!! int f(functie g) { return g(3); } !!! - o functie nu poate intoarce ca rezultat o alta functie functie f(int x) { return ... } --> Limbajele care permit lucrurile de mai sus se numesc limbaje functionale. LISP, Haskell, OCaml, Python -> functionale C, C++, Java -> nu sunt limbaje functionale De ce as vrea sa invat programare functionala? - incurajeaza scrierea de cod "clean"; - trasaturi de limbaje functionale sunt preluate din ce in ce mai mult de limbajele mainstream (C#, C++); - $$$; - schimba mentalitatea; - o forma de programare declarativa; - limbajele functionale permit scrierea de programe scurte -- sunt foarte concise; - ce in Java e un program de sute de linii sa fie cateva linii in Haskell; - petrec mai mult timp gandind decat scriu propriu-zis. GHC -> Glasgow Haskell Compiler Miranda - limbaj pur functional ($) Haskell - limbaj pur functional Windows: Haskell Platform Linux: apt-get install ghc Mac: brew install ghc Doua moduri de lucru cu Haskell: - modul interactiv; ---> cel mai mult timp - modul "obisnuit". Folosim comanda "ghci" la linia de comanda (cmd pe Windows, bash/zsh pe Linux/Mac). Mod interactiv / REPL (read-evaluate-print loop) REPL = 1. citeste o expresie Haskell 2. evalueaza expresia 3. listeaza rezultatul loop = repeta de la inceput GHCI, in plus fata de expresii Haskell, poate primi si comenzi (incep cu ":"). tipul fiecarei expresii este cunoscut de la momentul compilarii (inainte de executia propriu-zisa) vvvvvv Haskell este un limbaj puternic (si static) tipizat. ^^^^^^^^ fiecare expresie are un tip bine definit slab tipizat puternic tipizat dialecte vechi de BASIC C Java Haskell LISP ^ | | '1' + 7 tipul unei expresii nu tipul unei expresii este cunoscut decat in este cunoscut inca momentul evaluarii de la momentul compilarii | | v v tipizat dinamic tipizate static LISP Haskell Python Ocaml F# C Java C# Comenzi GHCI: ":type" ":t" Dandu-se o expresie Haskell, imi afiseaza tipul ei (fara sa evalueze expresia). :type (3 + 4) variabila de tip vvv (3 + 4) :: Num a => a Expresia "(3 + 4)" are tip "a", cu conditia ca "a" sa fie instanta a clasei "Num". :info Clasa de tipuri = multime de tipuri (cu niste lucruri in comun) Haskell suporta inferenta de tipuri. ^^^^^^^^^ 1. nu este necesar, in general, sa declar tipul unei expresii 2. Haskell calculeaza tipul fiecarei expresii 3. Alege cel mai general tip posibil Sintaxa de apel a unei functii in Haskell: - scriu numele functiei - scriu spatiu - scriu primul argument - scriu spatiu - ... - scriu spatiu - scriu ultimul argument Sintaxa de apel a unei functii in C: - scriu numele functiei - scriu "(" - scriu primul argument - scriu "," - scriu al doilea argument - scriu "," - ... - scriu "," - scriu ultimul argument - scriu ")" Scrierea "not(not(True))" este sintactic corecta, dar descurajata, fiindca seama cu sintaxa din C si poata sa conduca la confuzie suplimentara: de exemplu, ajunge sa scrie "mod(10 3)". Este incurajata scrierea: "not (not True)". Limbaj pur functional. 1. Efect secundar. - schimbarea valorii unei variabile globale In C, expresia "x = 7" se evalueaza la valoarea "7" si, ca efect secundar, schimba valoarea variabilei "x". - afisarea unui mesaj pe ecran - trimiterea unui pachet in retea - crearea unui fisier pe disc 2. Limbaj pur functional = nicio expresie nu are efecte secundare Nu pot face o bucla: efect secundar vvvvv for (i = 0; i < 10; i++) ^^^^ efect secundar { // ... } 3. Limbajele pur functionale se bucura de o proprietate care se numeste transparenta referentiala (referential transparency). transparenta referentiala = valoarea unei expresii este data doar de expresia in sine, nu si de contextul in care apare expresia