; Function of multiple moderately-complex arguments: (define (g x y z) ...) (lambda (x f y h z) (g x (f y) (h z))) ; Same thing in functional continuation-passing form: (define (g x y z) ...) (lambda (k x f y h z) (let [(g1 (lambda (_ fy) (let [(g2 (lambda (_ hz) (g k x fy hz)))] (h g2 z))] (f g1 y))) ; Internal form: #S(lambda ; globals #( #S(template ; g1 ; globals #( #S(template ; g1 #(#S(lambda ...)) ; globals (g1=g) #B(i0 i1 f0) ; instance vars (i0-i2) 1 ; frame vars (f0) #B( ; code (set! f0 (car argv)) (set! f0 (cons f0 nil)) (set! f0 (cons i2 f0)) (set! f0 (cons i1 f0)) ; (list x fy hz) ) g1 ; tail-call f0 ; arguments ctx ; dynamic context i0 ; continuation ) ) #(k f0 f3 f4) ; instance vars (i0-i3) 3 ; frame vars (f0-f2) #B( ; code (set! f0 (car argv)) (set! f1 (cons i3 nil)) ; (list z) (set! f2 (lambda g1)) ) i2 ; tail-call f1 ; arguments ctx ; dynamic context f2 ; continuation ) ) #() ; instance vars 7 ; frame vars (f0-f6) #B( ; code (set! f0 (car argv)) ; x (set! f5 (cdr argv)) (set! f1 (car f5)) ; f (set! f5 (cdr f5)) (set! f2 (car f5)) ; y (set! f5 (cdr f5)) (set! f3 (car f5)) ; h (set! f5 (cdr f5)) (set! f4 (car f5)) ; z (set! f5 (cons f2 nil)) ; (list y) (set! f6 (lambda g1)) ) f1 ; tail-call f5 ; arguments ctx ; dynamic context f6 ; continuation ) ================================================= ; Function w/ conditional behavior (let [(add1 (lambda (x) (+ 1 x)))] (lambda (x y) (if x (add1 x) y)) ; CPS (let [(add1 (lambda (k x) (k (+ 1 x))))] (lambda (k x y) (let [(f0 (if' x (lambda (k') (add1 k' x)) (lambda (k') (k' y))))] (f0 k)))) ; Internal form #S(lambda #( #S(template ; g1 #( #S(lambda ; g1 = add1 #(1) #() 1 #B( (set! f0 (car argv)) (set! f0 (fix+ f0 g1)) (set! f0 (cons f0 nil)) ) k f0 ctx nil ) ) #B(f0) 1 ; f0 #B( (set! f0 (cons i0 nil)) ) g1 f0 ctx k ) #S(template ; g2 #(#f) #B(f0) 1 ; f0 #B( (set! f0 (cons i0 nil)) ) k f0 g1 g1 ) ) #() 3 ; f0-f2 #B( (set! f0 (car argv)) (set! f1 (cdr argv)) (set! f1 (car f1)) (set! f2 (if f0 g1 g2)) (set! f2 (lambda f2)) ) f2 nil ctx k ) ================================================= ; Recursive function (define fact (lambda (n) (if (< n 1) 1 (* n (fact (- n 1)))))) ; CPS (letrec [(fact (lambda (k n) ((if' (< n 1) (lambda (k') (k' 1)) (lambda (k') (let (k'' (lambda (_ m) (k' (* n m)))) (fact k'' (- n 1))))) k)))]) ; Internal #0=#S(lambda #( #S(lambda ; g1 = (lambda (k) (k 1)) #(1 #f) ; g1 = 1; g2 = #f #() ; instance 1 ; frame (f0) #B( (set! f0 (cons g1 nil)) ) k ; tail-call f0 ; arguments g2 ; dynamic context g2 ; continuation ) #S(template ; g2 = (lambda (k) ...) #( #=0 ; g1 = fact #S(template ; g2 = (lambda (_ m) (k (* n m))) #(#f) ; globals #B(i0 k) ; instance (i0=n, i1=k) 1 ; frame (f0) #B( (set! f0 (car argv)) (set! f0 (fix* i0 f0)) (set! f0 (cons f0 nil)) ) i1 f0 g1 g1 ) 1 ; g3 = 1 ) #B(f0) ; instance (i0 = parent->f0 = n) 1 ; frame (f0) #B( (set! f0 (fix- i0 g3)) (set! f0 (cons f0 nil)) ) g1 f0 ctx g2 ) 1 ; g3 = 1 ) #() ; instance 2 ; frame (f0-f1) #B( (set! f0 (car argv)) (set! f1 (fix< f0 g3)) (set! f1 (if f1 g1 g2)) (set! f1 (lambda f1)) ) f1 nil ctx k ) # vim:set sw=2 expandtab: