#lang racket (require racket/trace) ; definire factorial locală (numele va fi disponibil doar în letrec) ; recursiv pe stivă (define fact-1 (λ (n) (if (= n 1) 1 (* n (fact-1 (- n 1))) ) )) (trace fact-1) (fact-1 5) ; folosiți Debug pentru a observa cum stiva nu se încarcă cu apeluri fact-aux ; după evaluarea lui (= n 1) cu n=1, întoarcerea se face direct la ieșirea din fact-2 ; factorial recursiv pe coadă (define fact-2 (λ (n) (fact-aux n 1))) (define fact-aux (λ (n rezultat) (if (= n 1) rezultat (fact-aux (- n 1) (* n rezultat)) )) ) (trace fact-2) (trace fact-aux) (fact-2 5) ; este recursiv pe stivă, dar nu am ; nevoie de argument suplimentar / funcție auxiliară (define mem-tail (lambda (e L) (if (null? L) #f (if (equal? e (car L)) #t (mem-tail e (cdr L)) )))) (mem-tail 3 '(1 2 3 4 5)) ; recursivitate pe stivă (define evens-s (λ (L) (if (null? L) '() ; null ; (list) (append (if (even? (car L)) (list (car L)) null) (evens-s (cdr L))) ))) ; evens recursiv pe coadă (define (evens-aux L R) (cond ((null? L) R) ; la terminarea recursivității în R avem deja rezultatul final ((even? (car L)) (evens-aux (cdr L) (cons (car L) R))) ; (append R (list (car L))))) ; ineficient (#t (evens-aux (cdr L) R)) )) (define (evens-tail L) (reverse (evens-aux L '()))) ; la final rezultatul întors va fi în ordine inversă ; pentru că primul element par din listă este adăugat cel mai devreme în RP, deci ultimul, ; pentru că celelalte elemente vor fi adăugat mereu la începutul listei ; la recursivitatea pe stivă, primul element par din listă este adăugat cel mai târziu ; (deci primul) în rezultat, după revenirea din recursivitate ; ========= funcții nestricte ; if este funcție nestrictă (macro) (if #f (/ 1 0) 'ceva) ; funcțiile definite cu define și lambda sunt stricte (define myif (λ (cond true false) (if cond true false))) ; apelul de myif evaluează întâi toți parametrii ;(myif #f (/ 1 0) 'ceva) ; and este funcție nestrictă (and #f (/ 1 0)) ; and întoarce ultima valoare (dacă toate sunt diferite de false) (and 0 '() #t 'a) ; 0 este luat ca ne-fals ; or întoarce prima valoare diferită de false (or 0 '() #t 'a) (or #f false 0 '() #t 'a) ; ========== secvențiere expresii (define f (λ (a b) ; expresia 1 (+ 1 2) ; expresia 2 ; (/ 1 0) ; expresiile 3 și 4 - efect lateral de afișare la consolă (display (+ a b))(newline) ; expresia 5 (+ a b) )) ; lambda va întoarce la aplicare ; valoarea întoarsă de ultima expresie ; din corp (f 10 11) ; parametrii funcției (define x 2) (and (display x) (newline) 5) ; pot folosi and ca să includ mesaje de debugging în ceva care este o expresie (append '(a b c) ; pot face debugging cu and și mai multe expresii pentru afișare; and întoarce ultima valoare (and (display '(1 2 3)) (newline) '(1 2 3)) )