Common Lisp Native Coroutines (sort of. . . ahem. . . actually, no) - - PowerPoint PPT Presentation

common lisp native coroutines
SMART_READER_LITE
LIVE PREVIEW

Common Lisp Native Coroutines (sort of. . . ahem. . . actually, no) - - PowerPoint PPT Presentation

Common Lisp Native Coroutines (sort of. . . ahem. . . actually, no) Didier Verna April 4 2017 Coroutines Very old idea yield values without losing its state resume its computation later (yielding more values) transfer control


slide-1
SLIDE 1

Common Lisp Native Coroutines

(sort of. . . ahem. . . actually, no) Didier Verna April 4 2017

slide-2
SLIDE 2

Coroutines

◮ Very old idea ◮ yield values without losing its state ◮ resume its computation later (yielding more values) ◮ transfer control elsewhere ◮ . . .

slide-3
SLIDE 3

Examples

(defun squares () (loop :for i :from 0 :do (yield (* i i)))) (defun preorder (tree) (if (atom tree) (yield tree) (progn (preorder (car tree)) (preorder (cdr tree)))))

slide-4
SLIDE 4

The Condition System

3D Separation of Concerns, no mandatory stack unwinding

slide-5
SLIDE 5

Tricking the Condition System into Coroutin’ing

A handler declining, but still side-effecting!

slide-6
SLIDE 6

Back to the Examples

(define-condition yield () ((value :accessor value :initarg :value))) (defun yield (value) (signal 'yield :value value)) (defun squares () (loop :for i :from 0 :do (yield (* i i)))) (defun preorder (tree) (if (atom tree) (yield tree) (progn (preorder (car tree)) (preorder (cdr tree)))))

slide-7
SLIDE 7

Handling yielded values

? ? ? ? ? ,coroutine) ?

slide-8
SLIDE 8

Handling yielded values

? ? (handler-bind ((yield (lambda (condition) (let ((,value (value condition))) ,@body)))) ,coroutine) ?

slide-9
SLIDE 9

Handling yielded values

? `(restart-case (handler-bind ((yield (lambda (condition) (let ((,value (value condition))) ,@body)))) ,coroutine) (abort ())))

slide-10
SLIDE 10

Handling yielded values

(defmacro with-coroutine (coroutine value &body body) `(restart-case (handler-bind ((yield (lambda (condition) (let ((,value (value condition))) ,@body)))) ,coroutine) (abort ())))

slide-11
SLIDE 11

Handling yielded values

(defmacro with-coroutine (coroutine value &body body) `(restart-case (handler-bind ((yield (lambda (condition) (let ((,value (value condition))) ,@body)))) ,coroutine) (abort ())))

(defun ssq (n) (let ((step 0) (sum 0)) (with-coroutine (squares) sq (incf sum sq) (incf step) (when (> step n) (abort))) sum)) (defun leaves (tree) (let (leaves) (with-coroutine (preorder tree) leaf (push leaf leaves)) (nreverse leaves)))