Fie urmatoarea expresie, scrisă într-o varianta relaxata a Calculului Lambda (in care valori numerice si operatii pe acestea sunt permise, iar functiile sunt in forma uncurry):
(λx.λy.(x + y) 1 2)
Evident, in urma aplicării funcției de mai sus, expresia se va evalua la 3. Sa observam, insa, cazul in care parametrii functiei reprezinta aplicatii de functii:
(λx.λy.(x + y) 1 (λz.(z + 2) 3))
Desigur, evaluarea expresiei (λz.(z + 2) 3)
va genera valoarea 5
, de unde deducem ca rezultatul final al expresiei va fi 6
( adunarea lui 1 cu rezultatul anterior ). În cadrul acestui raționament, am presupus că parametrii sunt evaluați înaintea aplicării funcției asupra acestora. Vom vedea, în cele ce urmează, că evaluarea se poate realiza și in alt mod.
Evaluarea aplicativă (eager evaluation) este cea în care fiecare expresie este evaluată imediat. În exemplul de mai sus, evaluarea aplicativă va decurge astfel:
(λx.λy.(x + y) 1 (λz.(z + 2) 3)) (λx.λy.(x + y) 1 5) 6
Spre deosebire de evaluarea aplicativă, evaluarea normală va întarzia evaluarea unei expresii, până când aceasta este folosită efectiv. Exemplu:
(λx.λy.(x + y) 1 (λz.(z + 2) 3)) (1 + (λz.(z + 2) 3)) (1 + 5) 6
Evaluarea in Racket este by default aplicativă.
Codul (+ 1 (+ 2 3))
pentru a se evalua si a intoarce 6, urmează etapele:
(+ 2 3)
se evaluează intai, al doilea parmetru al funcției +
si produce 5(+ 1 5)
se evaluează si produce 6Totuși, putem intarzia evaluarea expresiilor prin inchideri nulare
(define suma (lambda (a b) (+ a b))) (define suma_intarziata (lambda (a b) (lambda () (+ a b) )))
(suma_intarziata 2 3)
intoarce un #procedure
(functie) care isi salveaza contextul ( inchidere functionala )(
(suma_intarziata 2 3)
)
intoarce rezultatul(take 5 ones_stream)
⇒ (1 1 1 1 1)
(0 . #procedure)
, unde dacă vom apela procedure vom obtine(1 . #procedure)
, unde dacă iar apelam procedure-ul nou obtinut, obtinem(2 . #procedure)
etc.(take 5 naturals_stream)
⇒ (0 1 2 3 4)
(take 5 (sum_stream naturals_stream ones_stream))
⇒ (1 2 3 4 5)
zipWith
care sa opereze pe stream-uri(take 5 even_stream)
⇒ (0 2 4 6 8)
map
care sa opereze pe stream-uri(take 5 fibo_stream)
⇒ (0 1 1 2 3)
Fibo = t0 t1 t2 t3 ... t(k-2) ... + (tail Fibo) = t1 t2 t3 t4 ... t(k-1) ... ___________________________________________ Fibo = t0 t1 t2 t3 t4 t5 ... tk ...
build :: (a → a) → a → [a]
care primeste o functie 'generator' (pe care o numim g
in continuare), o valoare initiala (a0
), si generaza lista: [a0, g a0, g (g a0), g (g (g a0)), …
select
care primeste o toleranta e
, o lista, si intoarce valoarea an
care satisface proprietatea: |an - a{n+1}| < e
sqrt(k)
:sqrt(k)
cu toleranta 0.01
, exploatand faptul ca sirul: an = 1/2(a{n-1} + k/a{n-1})
converge catre sqrt(k)
cand n
tine de la infinit.f
intr-un punct a
[h0, h0/2, h0/4, h0/8, …]
f'(a)
, calculate astfel: f'(a)=f(a+h)-f(a)/h
a
a unei functii f
, cu toleranta 0.01
[a,b]
f
intre a
si b
, cu toleranta 0.01
. Strategia de imbunatatire a unei aproximari consta in spargerea intervalului [a,b]
in doua sub-intervale de dimensiune egala [a,m]
si [m,b]
, calculul integralei pe fiecare, si adunarea rezultatului.