#lang racket (define-namespace-anchor a) (define ns (namespace-anchor->namespace a)) ; Omega -- expresie nereductibilă ;(define omega ((λ (x) (x x)) (λ (x) (x x)))) ; omega (define y 5) (define (f x) y) ; o funcție obișnuită (strictă) ;(f ((λ (x) (x x)) (λ (x) (x x)))) ; ciclează - f este funcție strictă (if #t 'true ((λ (x) (x x)) (λ (x) (x x)))) ; if este funcție nestrictă (implementată ca macro, nu ca funcție) (or 'ceva ((λ (x) (x x)) (λ (x) (x x)))) ; or este funcție nestrictă (implementată ca macro, nu ca funcție) (f (λ (x) ((λ (x) (x x)) (λ (x) (x x))))) ; omega nu se evaluează, pentru că este în corpul unei funcții neaplicate niciodată ; paranteză: and și or (and 1 2 #f 3) (and 1 2 3) (or #f #f) (or #f #f 0 2 #f) ;; clasic (define prod1 (λ (x y) ; în y primesc o valoare (displayln "prod") (if x (* y (+ y 1)) 0))) (define test1 (λ (xarg) (let ((yarg 5)) (prod1 xarg (and (display "y ") yarg)))) ; în al doilea argument, prod primește valoarea 5 ) (test1 #f) (test1 #t) (displayln "------ ^ direct") ; îmi doresc să obțin ; prod ; y prod ;; quote + eval (define prod2 (λ (x y) ; în y primesc o expresie quoted (displayln "prod") (if x (* (eval y ns) (+ (eval y ns) 1)) 0))) ; eval necesită un spațiu de nume în care să evalueze expresia ; aici, am dat spațiul de nume global; o soluție ar fi să transmitem și spațiul de nume ca argument (define test2 (λ (xarg) (let ((yarg 5)) (prod2 xarg (quote (and (display "y ") yarg))))) ; în al doilea argument, prod primește expresia "(and (display "y ") yarg)", fără context ) ;(test2 #f) (test2 #t) (displayln "------ ^ quote & eval") ;; inchidere λ (define prod3 (λ (x y); în y primesc o închidere (displayln "prod") (if x (* (y) (+ (y) 1)) 0))) (define test3 (λ (xarg) (let ((yarg 5)) (prod3 xarg (λ () (and (display "y ") yarg))))) ; în al doilea argument, prod primește o închidere funcțională ; < (λ () (and (display "y ") yarg)) ; { yarg <- 5 } > ) (test3 #f) (test3 #t) (displayln "------ ^ închideri λ") ;; promisiuni (define prod4 (λ (x y) ; în y primesc o promisiune (displayln "prod") (if x (* (force y) (+ (force y) 1)) 0))) (define test4 (λ (xarg) (let ((yarg 5)) (prod4 xarg (delay (begin (display "y ") yarg))))) ; în al doilea argument, prod primește o promisiune ; < (and (display "y ") yarg) ; { yarg <- 5 } ; fără valoare calculată > ; după primul force, promisiunea devine ; < (and (display "y ") yarg) ; { yarg <- 5 } ; valoare calculată: 5> ; la force-uri ulterioare pe această promisiune, se întoarce direct valoarea calculată ) (test4 #f) (test4 #t) (displayln "------ ^ promisiuni") (display '---------------------------)(newline) ; promisiuni (promises) (define prod4b (λ (x y) ; în y primesc o promisiune (displayln "prod") (if x (* (force y) (+ (force y) 1)) 0))) (define test4b (λ (xarg) (let* ((yarg 5) (promisiune (delay (and (displayln "y ") yarg))) ) (prod4b xarg promisiune) (prod4b xarg promisiune) ))) (test4b #f) (test4b #t) (displayln "------ ^ apelare prod de 2 ori") (define ya 2) (delay (and (display "y ") ya)) ; -> prim rang ;(delay (+ 1 2 3)) ;# ;> (force (delay (+ 1 2 3)))