emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Delimited continuations


From: John Wiegley
Subject: Delimited continuations
Date: Sat, 09 Dec 2017 01:06:23 -0800
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.90 (darwin)

It just occurred to me this evening that lexical-binding makes delimited
continuations (https://en.wikipedia.org/wiki/Delimited_continuation) trivial
to implement in Emacs Lisp:

  ;; -*- lexical-binding: t -*-
  
  (defun shift (k entry)
    (if (eq (nth 0 k) 'outer)
        (throw (nth 1 k)
               (funcall entry #'(lambda (val)
                                  (funcall (nth 2 k)
                                           (list 'inner val)))))
      (nth 1 k)))
  
  (defun reset (thunk)
    (let ((bound (make-symbol "reset--bound")))
      (catch bound
        (funcall thunk (list 'outer bound thunk)))))
  
  (reset
   #'(lambda (_)
       (+ 4 (reset
             #'(lambda (p)
                 (* 2 (shift p #'(lambda (k)
                                   (funcall k (funcall k 4))))))))))
  ;; (+ 4 (* 2 (* 2 4)))
  ;; => 20
  
  (reset
   #'(lambda (q)
       (+ 4 (reset
             #'(lambda (_)
                 (* 2 (shift q #'(lambda (k)
                                   (funcall k (funcall k 4))))))))))
  ;; (+ 4 (* 2 (+ 4 (* 2 4))))
  ;; => 28

This can handy when coding something that naturally lends itself to "inversion
of control", when it's easier to code the inner structure of something up
front, and then refer to that structure -- possibly repeating it and
transforming it -- to build up the resulting data:

  (let ((data '(1 2 3)))
    (reset
     #'(lambda (p)
         (list 'a 'b (shift p #'(lambda (k)
                                  (append (funcall k 0)
                                          (mapcar (apply-partially k)
                                                  data))))))))
  ;; => (a b 0
  ;;     (a b 1)
  ;;     (a b 2)
  ;;     (a b 3))

-- 
John Wiegley                  GPG fingerprint = 4710 CF98 AF9B 327B B80F
http://newartisans.com                          60E1 46C4 BD1A 7AC1 4BA2



reply via email to

[Prev in Thread] Current Thread [Next in Thread]