Sunteți pe pagina 1din 55

Programare Funcional

https://portal.info.uaic.ro/curs/pf/default.aspx

Prof. Gheorghe GRIGORA www.info.uaic.ro/~grigoras grigoras@info.uaic.ro


G. Grigoras - FII Programare Functionala 1

Cursul 1 - Plan
Informaii generale despre curs
Cerine, Logistica, Bibliografia

Limbaje de programare
Functional vs. Imperativ Pur vs. Impur Lazy vs. Eager Typed vs. Untyped

Istoric al limbajelor funcionale Introducere n Haskell


GHC, sesiuni, scripturi

Tipurile de baz n Haskell Tipuri polimorfe, tipuri suprancrcate


G. Grigoras - FII Programare Functionala 2

Cerine
Curs opional, anul II, sem II Numr de credite: 5 Total ore: 5 x 30 = 150
Curs Laborator Activitate individual:
Antrenament programare Haskell: Pregtire teme laborator: Parcurgere bibliografie suplimentar Pregtire examen scris:

28 28
28 28 14 24

Prezena la toate laboratoarele


Evaluare sptmna 8 1 proiect(1 - 2 persoane) spt.9-15 50% din nota final

Examen scris la sfrit 50%


G. Grigoras - FII Programare Functionala 3

Bibliografie
Graham Hutton, Programming in Haskell, Cambridge 2007, (web) Richard Bird, Introduction to Functional Programming using Haskell, Prentice Hall Europe, 1998 Hal Daume III, Yet Another Haskell Tutorial, http://www.cs.utah.edu/~hal/docs/daume02yaht.pdf Mihai Gontineac, Programare funcional - O introducere utiliznd limbajul Haskell, Iasi 2007 (http://www.math.uaic.ro/~gonti/Cursuri/ProgramareFunctionala /ProgrFunct.pdf )
http://www.haskell.org

G. Grigoras - FII

Programare Functionala

Limbaje de programare

Functional vs. Imperativ Pur vs. Impur Lazy vs. Eager Typed vs. Untyped

G. Grigoras - FII

Programare Functionala

Functional vs. Imperativ


Caracteristici ale stilului funcional:
Structuri de date persistente: odat ncrcate nu se mai schimb Metoda primar de calcul: aplicarea funciilor Structura de control de baz: recursia Utilizarea din greu a funciilor de ordin nalt: funcii ce au ca argument alte funcii i/sau ca rezultat funcii

G. Grigoras - FII

Programare Functionala

Functional vs. Imperativ


Caracteristici ale stilului imperativ:
Structuri de date mutabile Metoda primar de calcul: atribuirea Structura de control de baz: iteraia Utilizarea funciilor de ordinul nti

Imperativ (C de exemplu):
suma = 0; for(i=1; i<=10; ++i) suma = suma + i;

Funcional:
sum[1..10]
G. Grigoras - FII Programare Functionala 7

Cod elegant i concis:


quicksort :: (Ord a) => [a] -> [a] quicksort [] = [] quicksort (x:xs) = quicksort lt ++ [x] ++ quicksort ge where lt = [y | y <- xs, y < x] ge = [y | y <- xs, y >= x] Funcioneaz pentru orice tip cu valori peste care exist o relaie de ordine total
G. Grigoras - FII Programare Functionala 8

Limbaje funcionale Haskell ML Scheme Erlang Lisp


G. Grigoras - FII

Limbaje imperative C Cobol C++ Fortran Assembler Visual Basic Java

Visual C++

Programare Functionala

Haskell este bun pentru:


Orice problem ce poate fi caracterizat ca o transformare
Compilatoare DSLs (Domain-Specific Languages) Implementarea conceptelor matematice

Demonstratoare automate
G. Grigoras - FII Programare Functionala 10

Haskell nu este bun pentru:


Orice problem ce necesit vitez extrem de mare pentru rezolvare
Poate fi folosit Haskell pentru a genera cod C

Orice problem care vizeaz simulri


Se pot folosi monade

G. Grigoras - FII

Programare Functionala

11

Aplicaii industriale implementate funcional


http://homepages.inf.ed.ac.uk/wadler/realworld/index.html

Intel (microprocessor verification) Hewlett Packard (telecom event correlation)

Ericsson (telecommunications)
Carlstedt Research & Technology (air-crew scheduling) Legasys (Y2K tool)

Hafnium (Y2K tool)


Shop.com (e-commerce) Motorola (test generation) Thompson (radar tracking) http://www.haskell.org/haskellwiki/Haskell_in_industry
G. Grigoras - FII Programare Functionala 12

Pur vs. Impur


Un limbaj funcional ce are doar caracteristicile stilului funcional (i nimic din stilul imperativ) este limbaj funcional pur. Haskell este limbaj funcional pur. Limbaje ca: Standard ML, Scheme, Lisp combin stilul funcional cu o serie de caracteristici imperative; acestea sunt limbaje impure.
G. Grigoras - FII Programare Functionala 13

Lazy vs. Eager


Limbajele funcionale se mpart n dou categorii:
Cele care evalueaz funciile(expresiile) n mod lazy, adic argumentele unei funcii sunt evaluate numai dac este necesar Cele care evalueaz funciile(expresiile) n mod eager, adic argumentele unei funcii sunt tratate ca i calcule precedente funciei i sunt evaluate nainte ca funcia s poat fi evaluat
G. Grigoras - FII Programare Functionala 14

Haskell este un limbaj lazy:


Prelude> let f x = 10 Prelude> f(1/0) 10 Prelude> 1/0 Infinity Prelude> let poz_ints = [1..] Prelude> let one_to_ten = take 10 poz_ints Prelude> one_to_ten [1,2,3,4,5,6,7,8,9,10]
G. Grigoras - FII Programare Functionala 15

Typed vs. Untyped


Limbajele au, n general, noiunea de tip Sistemul de tipuri difer de la limbaj la limbaj Tipurile sunt utilizate pentru:
Numirea i organizarea conceptelor Asigurarea c secvenele de bii din memorie sunt interpretate consistent Furnizarea ctre compilator a informaiilor privind manipularea datelor de ctre program
G. Grigoras - FII Programare Functionala 16

Typed vs. Untyped


Limbajele pot fi categorisite astfel:
Puternic tipizate (strongly typed): mpiedic programele s acceseze date private, s corup memoria, s blocheze sistemul de calcul etc. Slab tipizate (weakly typed)
Static tipizate (staticaly typed): consistena tipurilor este verificat la compilare Dinamic tipizate (dynamicaly typed): verificarea consistenei se face la execuie
G. Grigoras - FII Programare Functionala 17

Typed vs. Untyped


Limbajul Haskell este puternic tipizat Orice expresie ce apare ntr-un program Haskell are un tip ce este cunoscut la compilare (staticaly typed). Nu exist mecanisme care s distrug sistemul de tipuri. Ori de cte ori se evalueaz o expresie, de tip ntreg de exemplu, rezultatul va fi de acelai tip, ntreg.
G. Grigoras - FII Programare Functionala 18

Haskell este liber de side effects!


Nu are asignri Nu are variabile mutabile Nu are tablouri mutabile Nu are nregistrri mutabile Nu are stri ce pot fi actualizate

G. Grigoras - FII

Programare Functionala

19

Avantajele alegerii limbajului Haskell


Haskell este un limbaj de nivel foarte nalt (multe detalii sunt gestionate automat). Haskell este expresiv i concis (se pot obine o sumedenie de lucruri cu un efort mic). Haskell este adecvat n a manipula date complexe i a combina componente.

Cu Haskell programatorul ctig timp: programmer-time este prioritar lui computer-time


G. Grigoras - FII Programare Functionala 20

Istoric al limbajelor funcionale


1920 1940, Alonzo Church(1903 1995) i Huskell Curry(1900 1982) dezvolt Lambda Calculul, o teorie matematic a funciilor
http://www-groups.dcs.st-and.ac.uk/~history/Mathematicians/Church.html

G. Grigoras - FII

Programare Functionala

21

Istoric al limbajelor funcionale


1950-1960 - Lisp, John McCarthy(n.1927), Professor of Computer Science at Stanford University since 1962
http://www-formal.stanford.edu/jmc/personal.html

G. Grigoras - FII

Programare Functionala

22

Istoric al limbajelor funcionale


1978 - FP, John Backus (n. 1924)
http://www.thocp.net/biographies/backus_john.htm

Funcii de ordin nalt Raionamente asupra programelor

G. Grigoras - FII

Programare Functionala

23

ML, Robin Milner (n. 1924)

Istoric al limbajelor funcionale


A fost profesor timp de 22 ani la Computer Science Department, University of Edinburgh apoi 4 ani la Cambridge. n 1991 laureat al premiului Turing acordat de ACM (considerat echivalentul premiului Nobel pentru Informatic). Au mai primit acest premiu McCarthy i Backus ntre anii 1971 - 1980, a condus echipa ce a proiectat limbajul Standard ML, unul din primele limbaje care are semantica descris formal. Tipurile polimorfe Inferena tipurilor

G. Grigoras - FII

Programare Functionala

24

Istoric al limbajelor funcionale


1970-80, David Turner
Limbaje funcionale lazy Limbajul Miranda (admirable)

1987: ncepe dezvoltarea limbajului Haskell de ctre un comitet internaional (numele vine de la Haskell Curry) limbaj funcional lazy standard 2003: este publicat raportul cu definiia limbajului Haskell 98 (the culmination of fifteen years of revision and extensions)
G. Grigoras - FII Programare Functionala 25

Implementri Haskell
http://www.haskell.org/haskellwiki/Implementations Platforma Haskell: http://hackage.haskell.org/platform/
Current stable release: 2011.4.0.0 (December 2011) , Next release: May 2012 The Haskell Platform is the easiest way to get started with programming Haskell. The Haskell Platform contains only stable and widely-used tools and libraries, drawn from a pool of thousands of Haskell packages, ensuring you get the best from what is on offer. The Haskell Platform ships with advanced features such as multicore parallelism, thread sparks and transactional memory

G. Grigoras - FII

Programare Functionala

26

Introducere n Haskell; GHC


GHC, http://hackage.haskell.org/platform/
GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude>

G. Grigoras - FII

Programare Functionala

27

Sesiuni
La lansarea sistemului se ncarc o bibliotec Prelude.hs n care sunt definite funciile uzuale: Sesiune: secvena de interaciuni utilizator sistem
Prelude> 56-3*(24+4/2)/(4-2) 17.0 Prelude> 3^21 10460353203 Prelude> 22^33 199502557355935975909450298726667414302359552 Prelude> let x = 24 in (x + 14)*(x - 14) 380 Prelude> :{ Prelude| let y = 33 Prelude| in 12 + y*3 Prelude| :} 111
G. Grigoras - FII Programare Functionala 28

Sesiuni
Prelude> [1,2,3] ++ [5,6] [1,2,3,5,6] Prelude> head [1,2,3,4] 1 Prelude> tail [1,2,3,4] [2,3,4] Prelude> take 2 [1,2,3,4] [1,2] Prelude> drop 2 [1,2,3,4] [3,4] Prelude> [1,2,3,4,5] !! 2 3 Prelude> [1,2,3,4,5] !! 9 *** Exception: Prelude.(!!): index too large Prelude> sum [1..10] 55

G. Grigoras - FII

Programare Functionala

29

Scripturi (fiiere surs)


O list de definiii constituie un script:
Se editeaz un fiier cu definiii main = print (fac 20) fac 0 = 1 fac n = n * fac (n-1)

Se salveaz (de exemplu Main.hs) Interpretare:


Se ncarc acest fiier:

:load Main.hs sau :l Main.h


Se invoc oricare din numele definite n fiier

G. Grigoras - FII

Programare Functionala

30

Scripturi
main = print (fac 20) fac 0 = 1 fac n = n * fac (n-1)
Prelude> :cd C:/Users/grisa/Documents/20112012/cursuri/pf/C1 Prelude> :l Main.hs [1 of 1] Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main. *Main> main 2432902008176640000 *Main> fac(5) 120 *Main> fac(20) 2432902008176640000

G. Grigoras - FII

Programare Functionala

31

Scripturi
main = print (fac 20) fac 0 = 1 fac n = n * fac (n-1)

Compilare:
Prelude> :!ghc -o main Main.hs Prelude> :! main 2432902008176640000

G. Grigoras - FII

Programare Functionala

32

Scripturi
main = print (fac 20) fac 0 = 1 fac n = n * fac (n-1)
Prelude> :cd C:/Users/grisa/Documents/20092010/cursuri/pf/C1 Prelude> :l Main.hs [1 of 1] Compiling Main ( Main.hs, interpreted ) Ok, modules loaded: Main. *Main> main 2432902008176640000 *Main> fac(5) 120 *Main> fac(20) 2432902008176640000

G. Grigoras - FII

Programare Functionala

33

Scripturi modificare + rencrcare


Se adaug la fiierul existent (Main.hs) alte definiii: ... smaller x y = if x < y then x else y biger x y = if x > y then x else y
Se salveaz Se rencarc acest fiier:
*Main> :r Ok, modules loaded: Main. *Main> biger 55 66 66 *Main> smaller 5 6 5
G. Grigoras - FII Programare Functionala 34

Reguli sintactice
n Haskell funciile au prioritatea cea mai mare: f 2 + 3 nseamn f(2) + 3 Apelul funciilor se pate face fr a pune argumentele n parantez: f(a) fa f(x, y) fxy f(g(x)) f(gx) f(x, g(y)) f x (g y) f(x)g(y) fx*gy
G. Grigoras - FII Programare Functionala 35

Reguli sintactice
Numele funciilor i a argumentelor trebuie s nceap cu liter mic sau cu _: myF, gMare, x, uu, _x, _y Se recomand ca numele argumentelor de tip list s aib sufixul s: xs, ns, us, ps, a13s ntr-o secven de definiii toate definiiile trebuie s nceap pe aceeai coloan: a = 30 a = 30 a = 30 b = 21 b = 21 b = 21 c = 111 c = 111 c = 111
G. Grigoras - FII Programare Functionala 36

Cuvinte cheie (21)


Erlang - 28, OCaml - 48, Java - 50, C++ - 63, Miranda - 10

case default else in infixr module then


G. Grigoras - FII

class deriving if infix instance newtype type


Programare Functionala

data do import infixl let of where


37

Expresii, Valori
Expresiile denot valori O expresie poate conine:
Numere Valori de adevr Caractere Tuple(n-uple) Funcii Liste

O valoare are mai multe reprezentri reprezentri ale lui 12:


12
G. Grigoras - FII

2+10

3*3+3
38

Programare Functionala

Evaluare (reducere, simplificare)


O expresie este evaluat prin reducerea sa la forme mai simple echivalente Evaluatorul limbajului funcional scrie forma canonic a expresiei care denot o valoare Obinerea formei canonice se face printr-un proces de reducere a expresiilor

Reducerea se poate face n mai multe moduri: rezultatul trebuie s fie acelai
G. Grigoras - FII Programare Functionala 39

Evaluare (reducere, simplificare)


square(2+7) def + square(9) def square 9*9 def * 81 square(2+7) def square (2+7)*(2+7) def + 9*(2+7) def + 9*9 def * 81

G. Grigoras - FII

Programare Functionala

40

Evaluare (reducere, simplificare)


Considerm scriptul:
trei x = 3 infinit = infinit + 1

trei infinit def infinit trei(infinit + 1) def infinit trei((infinit + 1)+1) ...

trei infinit def trei 3

Strategia lazy evaluation asigur terminarea procesului atunci cnd acest lucru este posibil
G. Grigoras - FII Programare Functionala 41

Tipuri
Tip : colecie de valori mpreun cu operaiile ce se pot aplica acestora
Bool conine False i True Bool -> Bool conine toate funciile cu argumente din Bool i valori n Bool

Se utilizeaz notaia v :: T pentru a exprima c v are tipul T Orice expresie are un tip ce se determin, dup reguli precise, nainte de a evalua expresia Procesul de determinare a tipului este numit type inference
G. Grigoras - FII Programare Functionala 42

Tipuri
Tipul unei expresii se poate afla n Haskell:
Prelude> :type 4 4 :: (Num t) => t Prelude> :type 4.54 4.54 :: (Fractional t) => t Prelude> :type False False :: Bool Prelude> :t "alpha" ++ "beta" "alpha" ++ "beta" :: [Char] Prelude> :t [1,2,3] [1,2,3] :: (Num t) => [t] Prelude> :t ['a', 'b', 'c'] ['a', 'b', 'c'] :: [Char]

G. Grigoras - FII

Programare Functionala

43

Tipurile de baz n Haskell


Bool
Valori: False True Operaii: && || not

Char
Valori: caractere Informaii despre tipul char:
Prelude> :i Char

G. Grigoras - FII

Programare Functionala

44

Operaii ale tipului Char


Prelude> False Prelude> True Prelude> True Prelude> False Prelude> 'b' Prelude> '`' Prelude> 'a' Prelude> '9 Prelude> 98 'a' == 'b' 'a' /= 'b' 'a' < 'b' 'a' >= 'b' succ 'a' pred 'a' pred 'b' toEnum 57 :: Char fromEnum 'b'

Tipurile de baz n Haskell

G. Grigoras - FII

Programare Functionala

45

Tipurile de baz n Haskell


String
Valori: liste de caractere Operaii: (vezi liste)
Prelude> "99a" Prelude> 'a' Prelude> "abcd" Prelude> "ef" "99" ++ "a" head "alpha" take 4 "abcdef" drop 4 "abcdef"

G. Grigoras - FII

Programare Functionala

46

Tipurile de baz n Haskell


Int: - 231..231-1 (ntregi precizie fix) Integer (ntregi precizie arbitrar)
Main> 2^31::Int -2147483648 Main> 2^31 2147483648 Main> 2^31::Integer 2147483648 Main> 2^99 633825300114114700748351602688

Operaii: + - *...
G. Grigoras - FII Programare Functionala 47

Tipurile de baz n Haskell


Float, Double
Numere reale n simpl(dubla) precizie: 2.2331, +1.0, 3.141 Numrul de cifre semnificative:
Virgula fixa: 7 Float, 16 Double Virgula mobil: 1+7, 1+16

Prelude> sqrt 4565 67.56478372643548 Prelude> sqrt 4565::Float 67.56478 Prelude> sqrt 456554545454::Float 675688.2 Prelude> sqrt 456554545454 675688.2013576973 Prelude> sqrt 456554545454456667777 2.1367137043938683e10 Prelude> sqrt 456554545454456667777::Float 2.1367138e10

G. Grigoras - FII

Programare Functionala

48

Tipul List n Haskell


Lista: o secven de elemente de acelai tip Sintaxa pentru acest tip: [T], unde T este tipul elementelor
Prelude> :t [1,2,3] [1,2,3] :: (Num t) => [t] Prelude> :t [True, True, False] [True, True, False] :: [Bool] Prelude> :t ["True","True","False"] ["True","True","False"] :: [[Char]] Prelude> :t [[1], [1,2,3],[]] [[1], [1,2,3],[]] :: (Num t) => [[t]] Prelude> :t [[[]]] [[[]]] :: [[[a]]]

[] lista vid, *1+, *unu+, **++ liste singleton


G. Grigoras - FII Programare Functionala 49

Tipul n-upl n Haskell


O secven finit de componente de diferite tipuri; componentele, desprite prin virgul, sunt incluse n paranteze rotunde Reprezentare: (T1, T2,..., Tn) Numrul componentelor = aritatea tuplei
Tupla () tupla vid, (T) = T Perechi, triplete Nu exist restricii asupra tipului componentelor
Prelude> :t () () :: () Prelude> :t (1) (1):: (Num t) => t (2)Prelude> :t ('a', "a", False, 3.4) ('a', "a", False, 3.4) :: (Fractional t) => (Char, [Char], Bool, t)
G. Grigoras - FII Programare Functionala 50

Tipul funcie n Haskell


Funcie n sens matematic, de la tipul T1 la tipul T2 T1 -> T2 noteaz tipul funciilor de la T1 la T2 Convenie Haskell: definiia unei funcii este precedat de tipul su:
pi :: Float pi = 3.14159 square :: Integer -> Integer square x = x*x plus :: (Int, Int) -> Int plus(x, y) = x + y Suma :: Int -> Int -> Int Suma x y = x + y
G. Grigoras - FII Programare Functionala 51

Funcii curry
O funcie cu n > 1 argumente este definit ca funcie cu un argument ce are ca valori o funcie cu n-1 argumente
plusc:: Int -> (Int -> Int) plusc x y = x + y mult :: Int -> (Int -> (Int -> Int)) mult x y z = x*y*z twise :: (Int -> Int) -> (Int -> Int) twise f x = f(fx) twise f = f.f
G. Grigoras - FII Programare Functionala 52

Funcii curry
Convenii pentru funcii curry
Operatorul -> n tipuri are asociativitatea dreapta Int -> Int -> Int -> Int -> Int nseamn Int -> (Int -> (Int -> (Int -> Int))) mult x y z nseamn ((mult x)y)z

G. Grigoras - FII

Programare Functionala

53

Tipuri polimorfe
Funcii ce sunt definite pentru mai multe tipuri: lungimea unei liste se calculeaz indiferent de tipul elementelor listei Variabile tip: a, b, c, ...
Prelude> :t length length :: [a] -> Int Prelude> length "abcdef" 6 Prelude> length [1,2,3,4,5,6,7,8,9] 9 Prelude> :t fst fst :: (a, b) -> a Prelude> :t snd snd :: (a, b) -> b Prelude> :t head head :: [a] -> a

Un tip ce conine una sau mai multe variabile tip se numete tip polimorf
G. Grigoras - FII Programare Functionala 54

Tipuri suprancrcate
Operatori ce se aplic la mai multe tipuri ( +, *, /, <, >, ) Tipul acestora conine variabile tip supuse unor constrngeri Astfel de tipuri se numesc tipuri suprancrcate
Prelude> :t (+) :: (Num Prelude> :t (++) :: [a] Prelude> :t (<) :: (Ord Prelude> :t (/=) :: (Eq
G. Grigoras - FII

(+) a) => a -> a -> a (++) -> [a] -> [a] (<) a) => a -> a -> Bool (/=) a) => a -> a -> Bool
Programare Functionala 55

S-ar putea să vă placă și