Continuation Marks A john clements talk
What are Continuation Marks?
What are Continuation Marks? What are Continuations?
What are Continuation Marks? What are Continuations? Continuations Paren-hackers Contexts Stacks Compiler-writers Semanticists
Contexts Stacks Compiler-writers Semanticists (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null))))
Contexts Stacks Compiler-writers Semanticists mark mark mark (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null)))) mark mark mark
Closing the Loop Programming Language Marks
Closing the Loop Programming Language with marks
Closing the Loop oops! Programming Language with marks
Closing the Loop Programming Language with marks
Contexts Stacks Compiler-writers Semanticists mark mark mark (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null)))) mark mark mark
Contexts Stacks Compiler-writers Semanticists (let*-2vals ([kept-vars (cond [(eq? tail-bound 'all) free-vars] [else (filter (lambda (varref) (ormap (lambda (binding) (bound-identifier=? binding varref)) tail-bound)) free-vars)])] [var-clauses (map (lambda (x) (list x (d->so `(quote-syntax ,x)))) kept-vars)] [let-bindings (filter (lambda (var) (case (syntax-property var 'stepper-binding-type) ((let-bound) #t) ((lambda-bound stepper-temp top-level) #f) (else (error 'make-debug-info "varref ~a's binding-type info \ was not recognized: ~a" (syntax-e var) (syntax-property var 'stepper-binding-type))))) [lifter-syms (map get-lifted-var let-bindings)] [quoted-lifter-syms (map (lambda (b) (d->so `(quote-syntax ,b))) lifter-syms)] [let-clauses (map list lifter-syms quoted-lifter-syms)]) (make-full-mark source label (append var-clauses (if lifting? let-clauses null))))
New Language Forms
New Language Forms Introducing marks: Observing marks: (with-continuation-mark M M) mark value body (current-continuation-marks)
New Language Forms Synopsis of Reduction Semantics: New Contexts: E = [] | (E M) | (V E) | … | (w-c-m V E) * *With restrictions on successive w-c-m’s New Reductions: E[(w-c-m V V)] -> E[V] E[(w-c-m V (w-c-m M M))] -> E[(w-c-m M M)] E[(c-c-m)] -> E[X(E)]
New Language Forms (define (loop x) (w-c-m x (loop (+ x 1)))) (w-c-m 0 (loop (+ 0 1))) -> (w-c-m 0 (loop 1)) -> (w-c-m 0 (w-c-m 1 (loop (+ 1 1)))) -> (w-c-m 1 (loop (+ 1 1))) -> (w-c-m 1 (loop 2)) -> (w-c-m 1 (w-c-m 2 (loop (+ 2 1)))) -> ...
New Language Forms (define (f x) (w-c-m x (+ (f x) 1))) (loop 0) -> (w-c-m 0 (+ (f 0) 1)) -> (w-c-m 0 (+ (w-c-m 0 (+ (f 0) 1)) 1)) -> (w-c-m 0 (+ (w-c-m 0 (+ (w-c-m 0 (+ (f 0) 1)) 1)) 1)) -> (w-c-m 0 (+ (w-c-m 0 (+ (w-c-m 0 (+ (w-c-m 0 (+ (f 0) 1)) 1)) 1)) 1)) -> ...
Expressiveness Conjecture: cannot be expressed in a “tail-call preserving way” by state, continuations, etc. Difficult to state claim clearly
Using Continuation Marks (to build a stepper)
(using continuation marks) Building a Stepper (using continuation marks)
Building a Stepper Why a Stepper? How to build a stepper? A stepper is a sound debugger A stepper is a complete debugger … with a suitable proof How to build a stepper? Annotation with continuation marks Non-invasive (well-defined) implementation
Building a Stepper Annotation: Marks must contain: Breakpoints Source position Values of free variables Breakpoints Where? Everywhere. No, even more than that.
Building a Stepper Pragmatics
Pragmatics Orthogonality of annotations Add a ‘key’ to each mark: Marks with different keys are orthogonal (with-continuation-mark M M M) key mark body (current-continuation-marks M)
Macro Reversal (cond [a b] [c d]) ?? R? R (if c d (error)) (if a b
“Needed” variables Variables stored in each mark Avoid duplication Store all variables which are not guaranteed to occur in an enclosing mark.
“Needed” variables Variable “a” is not needed in these contexts (letrec ([a 13] [b (+ a 14)] [c (lambda () a)]) (g a) Variable “a” is needed in these contexts
Opaque Values Closures: procedures, classes Structures, Units Put them in a table
Before & After Steps (+ 1 (if true 3 4)) -> (+ 1 3) Requires additional breakpoints for: • tail-position expressions • results of primitive applications
Unannotated Code Libraries Partial Annotation Complete Reconstruction not possible Detection necessary
Lifting & Renaming Newly created closures go to top level Names must be assigned at runtime Extra binding created
Lightweight Inspection (what else can we do with continuation marks?)
Stack Inspection Widely used security measure Associate privileges with ‘principals’ Inspect the stack to make guarantees about execution Implemented in a variety of ways: Stack Inspection “Security-passing style” ...
Stack Inspection … or using continuation marks Preserves tail-call optimization Place marks on the “bad” code T T G G OLD NEW
Aspect-Oriented Programming Allows textual separation of program aspects. May be implemented by a static annotation … with certain run-time decisions “cflow” rules in AspectJ But what about tail-call optimization? May be recovered with continuation marks
Lightweight Inspection Other uses waiting to be found…
Lightweight Inspection Other uses waiting to be found… Tell me yours!