What’s in a Continuation (2016)
Continuation based list flattening in TXR Lisp:<p><pre><code>  This is the TXR Lisp interactive listener of TXR 181.
  Quit with :quit or Ctrl-D on empty line. Ctrl-X ? for cheatsheet.
  1&gt; (defun yflatten (obj)
       (labels ((flatten-rec (obj)
                  (cond
                    ((null obj))
                    ((atom obj) (yield-from yflatten obj))
                    (t (flatten-rec (car obj))
                       (flatten-rec (cdr obj))))))
         (flatten-rec obj)
         nil))
  yflatten
  2&gt; (yflatten &#x27;(1 (2 3 (4) . 5) 6))
  #S(sys:yld-item val 1 cont #&lt;intrinsic fun: 1 param&gt;)
</code></pre>
Oops, we need the obtain macro work with a function which yields:<p><pre><code>  3&gt; (obtain (yflatten &#x27;(1 (2 3 (4) . 5) 6)))
  #&lt;interpreted fun: lambda (: resume-val)&gt;
  4&gt; [*3]
  1
  5&gt; [*3]
  2
  6&gt; [*3]
  3
  7&gt; [*3]
  4
  8&gt; [*3]
  5
  9&gt; [*3]
  6
  10&gt; [*3]
  nil
  11&gt; [*3]
  nil
</code></pre>
No continuation passing here: real stack where we can have unwind-protect.<p>Let&#x27;s do it again --- but this time let&#x27;s trace the function. For this we beak out flatten-rec into a top-level function we can trace.<p><pre><code>  (defun flatten-rec (obj)
    (cond
      ((null obj))
      ((atom obj) (yield-from yflatten obj))
      (t (flatten-rec (car obj))
         (flatten-rec (cdr obj)))))
  
  (defun yflatten (obj)
    (flatten-rec obj)
    nil)
</code></pre>
Now:<p><pre><code>  1&gt; (trace yflatten flatten-rec)
  nil
  2&gt; (obtain (yflatten &#x27;(1 (2 3 (4) . 5) 6)))
  #&lt;interpreted fun: lambda (: resume-val)&gt;
  3&gt; [*2]
  (yflatten ((1 (2 3 (4) . 5) 6))
    (flatten-rec ((1 (2 3 (4) . 5) 6))
      (flatten-rec (1)
    #S(sys:yld-item val 1 cont #&lt;intrinsic fun: 1 param&gt;))
  1
  4&gt; [*2]
        nil)
      (flatten-rec (((2 3 (4) . 5) 6))
        (flatten-rec ((2 3 (4) . 5))
          (flatten-rec (2)
  2
  5&gt; [*2]
            nil)
          (flatten-rec ((3 (4) . 5))
            (flatten-rec (3)
  3
  6&gt; [*2]
              nil)
            (flatten-rec (((4) . 5))
              (flatten-rec ((4))
                (flatten-rec (4)
  4
  7&gt; [*2]
                  nil)
                (flatten-rec (nil)
                  t)
                t)
              (flatten-rec (5)
  5
  8&gt; [*2]
                nil)
              nil)
            nil)
          nil)
        (flatten-rec ((6))
          (flatten-rec (6)
  6
  9&gt; [*2]
            nil)
          (flatten-rec (nil)
            t)
          t)
        t)
      t)
  nil
</code></pre>
At this point, the flattening is done. What if we keep calling it?<p><pre><code>  10&gt; [*2]
            nil)
          (flatten-rec (nil)
            t)
          t)
        t)
      t)
  nil
  11&gt; [*2]
            nil)
          (flatten-rec (nil)
            t)
          t)
        t)
      t)
  nil
</code></pre>
It&#x27;s just sputtering now, repeating the slice of execution spanning from several nestings deep into flatten-rec, up to the delimiting prompt, because no new continuation is captured.