#lang racket ; define syntax for weak delay of expr. Returns a ; closure that when evaluated evaluates expr in the ; original context. (define-syntax-rule (w-delay expr) (lambda () expr)) ; define syntax for weak force of a delayed expr ; simply evaluates the lambda (define-syntax-rule (w-force thunk) (thunk) ) ; a double function that assumes its argument is w-delayed. (define (double-w w-x) (+ (w-force w-x) (w-force w-x))) ; (w-double 42) ; (w-double (w-delay 42)) ; a double function that w-delays its result (define (w-double-w w-x) (w-delay (+ (w-force w-x) (w-force w-x)) ) ) ; (define r (w-double-w (w-delay 42))) ; (w-force r) ; weak delay and force give you a kind of call by name behaviour, ; as if you substituted the parameter into the code, while avoiding ; any new lexical bindings. ; note how this breaks referential transparency ; a global state changing operation (define state 0) (define (next-state) (set! state (+ 1 state)) state) (define v1 (w-delay (next-state))) ; every force gives a different value ; (w-force v1)) ; (w-force v1)) ; and so does double ; (double-w v1) ; and things are really bad if you w-delay even further (define v2 (w-double-w v1)) ; state ; v2 ; (w-force v2) ; (next-state) ; (w-force v2)