#lang racket (define-namespace-anchor a) (define ns (namespace-anchor->namespace a)) ;; clasic (define prod1 (λ (x y) (displayln "prod") (if x (* y (+ y 1)) 0))) (define test1 (λ (xarg) (let ((yarg 5)) (prod1 xarg (and (display "y ") yarg))))) ; lui prod1 i se transmite valoarea 5 (test1 #f) (test1 #t) ; îmi doresc să obțin ; prod ; y prod (display '---------------------------)(newline) (define prod2 (λ (x y) ; în y primesc textul unei expresii (displayln "prod") (if x (* (eval y) (+ (eval y) 1)) 0))) (define test2 (λ (xarg) (let ((yarg 5)) (prod2 xarg (quote (and (display "y ") yarg)))))) ; lui prod2 i se transmite "(and (display "y ") yarg)" ;(test2 #f) (test2 #t) (display '---------------------------)(newline) (define prod3 (λ (x y) ; în y primesc o funcție (de fapt, o închidere funcțională) (displayln "prod") (if x (* (y) (+ (y) 1)) 0))) (define test3 (λ (xarg) (let ((yarg 5)) (prod3 xarg (λ () (and (display "y ") yarg)))))) ; lui prod3 i se transmite < (λ () (and (display "y ") yarg)) ; {yarg<-5}> (test3 #f) (test3 #t) (display '---------------------------)(newline) ; promisiuni (promises) (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 (and (display "y ") yarg)))))) ; lui prod4 i se transmite 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) (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 (display "y ") yarg))) ) (prod4b xarg promisiune) (prod4b xarg promisiune) ))) (test4b #f) (test4b #t) ; (displayln "------") ;; ============================================================================ ;; creez un macro pentru a abstractiza mecanismul de întârziere ;; cu închideri ;(define-syntax-rule (pack computation) (λ () computation) ) ;(define (unpack package) (package) ) ;; cu promisiuni (define-syntax-rule (pack computation) (delay computation) ) ; define-syntax-rule funcționează exact prin substituție textuală a ; parametrului actual în corp, ca în calcul λ (define (unpack package) (force package) ) (display '---------------------------)(newline) ; promisiuni (promises) (define prod5 (λ (x y) ; în y primesc un calcul împachetat (displayln "prod") (if x (* (unpack y) (+ (unpack y) 1)) 0))) (define test5 (λ (xarg) (let ((yarg 5)) (prod5 xarg (pack (and (display "y ") yarg)))))) (test5 #f) (test5 #t) ;(define x (delay (+ 1 2)))