<p>I'm working on a Scheme interpreter written in C. Currently it uses the C runtime stack as its own stack, which is presenting a minor problem with implementing continuations. My current solution is manual copying of the C stack to the heap then copying it back when needed. Aside from not being standard C, this solution is hardly ideal.</p>

<p>What is the simplest way to implement continuations for Scheme in C?</p>

[{'answer_id': 6515, 'author': 'Patrick', 'author_id': 429, 'author_profile': 'https://Stackoverflow.com/users/429', 'pm_score': 1, 'selected': False, 'text': '<p>Use an explicit stack instead.</p>\n'}, {'answer_id': 6566, 'author': 'C. K. Young', 'author_id': 13, 'author_profile': 'https://Stackoverflow.com/users/13', 'pm_score': 5, 'selected': True, 'text': '<p>I remember reading an article that may be of help to you: <em><a href="http://home.pipeline.com/~hbaker1/CheneyMTA.html" rel="noreferrer">Cheney on the M.T.A.</a></em> :-)</p>\n\n<p>Some implementations of Scheme I know of, such as <a href="http://sisc.sourceforge.net/" rel="noreferrer">SISC</a>, allocate their call frames on the heap.</p>\n\n<p>@ollie: You don\'t need to do the hoisting if all your call frames are on the heap. There\'s a tradeoff in performance, of course: the time to hoist, versus the overhead required to allocate all frames on the heap. Maybe it should be a tunable runtime parameter in the interpreter. :-P</p>\n'}, {'answer_id': 6572, 'author': 'olliej', 'author_id': 784, 'author_profile': 'https://Stackoverflow.com/users/784', 'pm_score': 1, 'selected': False, 'text': '<p>Patrick is correct, the only way you can really do this is to use an explicit stack in your interpreter, and hoist the appropriate segment of stack into the heap when you need to convert to a continuation.</p>\n\n<p>This is basically the same as what is needed to support closures in languages that support them (closures and continuations being somewhat related).</p>\n'}, {'answer_id': 31951, 'author': 'Thomas Vander Stichele', 'author_id': 2900, 'author_profile': 'https://Stackoverflow.com/users/2900', 'pm_score': 3, 'selected': False, 'text': '<p>The traditional way is to use <code>setjmp</code> and <code>longjmp</code>, though there are caveats.</p>\n\n<p>Here\'s a <a href="https://web.archive.org/web/20090206042150/http://homepage.mac.com/sigfpe/Computing/continuations.html" rel="nofollow noreferrer">reasonably good explanation</a></p>\n'}, {'answer_id': 36644, 'author': 'Josh Segall', 'author_id': 2659, 'author_profile': 'https://Stackoverflow.com/users/2659', 'pm_score': 5, 'selected': False, 'text': '<p>A good summary is available in <a href="http://link.springer.com/article/10.1023/A:1010016816429" rel="noreferrer">Implementation Strategies for First-Class Continuations</a>, an article by Clinger, Hartheimer, and Ost.  I recommend looking at Chez Scheme\'s implementation in particular.</p>\n\n<p>Stack copying isn\'t that complex and there are a number of well-understood techniques available to improve performance.  Using heap-allocated frames is also fairly simple, but you make a tradeoff of creating overhead for "normal" situation where you aren\'t using explicit continuations.</p>\n\n<p>If you convert input code to continuation passing style (CPS) then you can get away with eliminating the stack altogether.  However, while CPS is elegant it adds another processing step in the front end and requires additional optimization to overcome certain performance implications.</p>\n'}, {'answer_id': 134886, 'author': 'Kyle Burton', 'author_id': 19784, 'author_profile': 'https://Stackoverflow.com/users/19784', 'pm_score': 3, 'selected': False, 'text': '<p>Examples that you can look at are: <a href="http://www.call-with-current-continuation.org/" rel="noreferrer">Chicken</a> (a Scheme implementation, written in C that support continuations); Paul Graham\'s <a href="http://www.paulgraham.com/onlisp.html" rel="noreferrer">On Lisp</a> - where he creates a CPS transformer to implement a subset of continuations in Common Lisp; and <a href="http://common-lisp.net/project/cl-weblocks/" rel="noreferrer">Weblocks</a> - a continuation based web framework, which also implements a limited form of continuations in Common Lisp.</p>\n'}, {'answer_id': 343160, 'author': 'Joel Borggrén-Franck', 'author_id': 38222, 'author_profile': 'https://Stackoverflow.com/users/38222', 'pm_score': 4, 'selected': False, 'text': '<p>If you are starting from scratch, you really should look in to Continuation Passing Style (CPS) transformation.</p>\n\n<p>Good sources include "LISP in small pieces" and <a href="https://web.archive.org/web/20090702055316/http://www.iro.umontreal.ca/~boucherd/mslug/meetings/20041020/minutes-en.html" rel="noreferrer">Marc Feeley\'s Scheme in 90 minutes presentation</a>.</p>\n'}, {'answer_id': 1839737, 'author': 'Charles Stewart', 'author_id': 222815, 'author_profile': 'https://Stackoverflow.com/users/222815', 'pm_score': 3, 'selected': False, 'text': '<p>Continuations aren\'t the problem: you can implement those with regular higher-order functions using CPS.  The issue with naive stack allocation is that tail calls are never optimised, which means you can\'t be scheme.</p>\n\n<p>The best current approach to mapping scheme\'s spaghetti stack onto the stack is using trampolines: essentially extra infrastructure to handle non-C-like calls and exits from procedures.  See <a href="http://www.cs.indiana.edu/~dfried/ts.ps" rel="noreferrer">Trampolined Style (ps)</a>.</p>\n\n<p>There\'s <a href="http://cpscm.googlecode.com/svn/trunk/scm/cpscm.scm" rel="noreferrer">some code</a> illustrating both of these ideas.</p>\n'}, {'answer_id': 1998702, 'author': 'Stefan Dragnev', 'author_id': 243103, 'author_profile': 'https://Stackoverflow.com/users/243103', 'pm_score': 3, 'selected': False, 'text': '<p>Continuations basically consist of the saved state of the stack and CPU registers at the point of context switches. At the very least you don\'t have to copy the entire stack to the heap when switching, you could only redirect the stack pointer.</p>\n\n<p>Continuations are trivially implemented using fibers. <a href="http://en.wikipedia.org/wiki/Fiber_%28computer_science%29" rel="nofollow noreferrer">http://en.wikipedia.org/wiki/Fiber_%28computer_science%29</a>\n. The only things that need careful encapsulation are parameter passing and return values.</p>\n\n<p>In Windows fibers are done using the CreateFiber/SwitchToFiber family of calls.\nin Posix-compliant systems it can be done with makecontext/swapcontext.</p>\n\n<p>boost::coroutine has a working implementation of coroutines for C++ that can serve as a reference point for implementation.</p>\n'}, {'answer_id': 2994071, 'author': 'Jay', 'author_id': 114979, 'author_profile': 'https://Stackoverflow.com/users/114979', 'pm_score': 3, 'selected': False, 'text': '<p>Besides the nice answers you\'ve got so far, I recommend Andrew Appel\'s  <a href="https://rads.stackoverflow.com/amzn/click/com/052103311X" rel="nofollow noreferrer" rel="nofollow noreferrer">Compiling with Continuations</a>. It\'s very well written and while not dealing directly with C, it is a source of really nice ideas for compiler writers.</p>\n\n<p>The Chicken Wiki also has pages that you\'ll find very interesting, such as  <a href="http://wiki.call-cc.org/chicken-internal-structure" rel="nofollow noreferrer">internal structure</a> and <a href="http://wiki.call-cc.org/chicken-compilation-process" rel="nofollow noreferrer">compilation process</a> (where CPS is explained with an actual example of compilation).</p>\n'}, {'answer_id': 7945834, 'author': 'soegaard', 'author_id': 23567, 'author_profile': 'https://Stackoverflow.com/users/23567', 'pm_score': 3, 'selected': False, 'text': '<p>It seems Dybvig\'s thesis is unmentioned so far.\nIt is a delight to read. The heap based model\nis the easiest to implement, but the stack based\nis more efficient. Ignore the string based model.</p>\n\n<p>R. Kent Dybvig. "Three Implementation Models for Scheme". \n<a href="http://www.cs.indiana.edu/~dyb/papers/3imp.pdf" rel="nofollow noreferrer">http://www.cs.indiana.edu/~dyb/papers/3imp.pdf</a></p>\n\n<p>Also check out the implementation papers on ReadScheme.org.\n<a href="https://web.archive.org/http://library.readscheme.org/page8.html" rel="nofollow noreferrer">https://web.archive.org/http://library.readscheme.org/page8.html</a></p>\n\n<p>The abstract is as follows:</p>\n\n<blockquote>\n  <p>This dissertation presents three implementation models for the Scheme\n  Programming Language. The first is a heap-based model used in some\n  form in most Scheme implementations to date; the second is a new\n  stack-based model that is considerably more efficient than the\n  heap-based model at executing most programs; and the third is a new\n  string-based model intended for use in a multiple-processor\n  implementation of Scheme. </p>\n  \n  <p>The heap-based model allocates several important data structures in a\n  heap, including actual parameter lists, binding environments, and call\n  frames. </p>\n  \n  <p>The stack-based model allocates these same structures on a stack\n  whenever possible. This results in less heap allocation, fewer memory\n  references, shorter instruction sequences, less garbage collection,\n  and more efficient use of memory. </p>\n  \n  <p>The string-based model allocates versions of these structures right in\n  the program text, which is represented as a string of symbols. In the\n  string-based model, Scheme programs are translated into an FFP\n  language designed specifically to support Scheme. Programs in this\n  language are directly executed by the FFP machine, a\n  multiple-processor string-reduction computer. </p>\n  \n  <p>The stack-based model is of immediate practical benefit; it is the\n  model used by the author\'s Chez Scheme system, a high-performance\n  implementation of Scheme. The string-based model will be useful for\n  providing Scheme as a high-level alternative to FFP on the FFP machine\n  once the machine is realized.</p>\n</blockquote>\n'}, {'answer_id': 46927339, 'author': 'alinsoar', 'author_id': 1419272, 'author_profile': 'https://Stackoverflow.com/users/1419272', 'pm_score': 2, 'selected': False, 'text': '<p>As <code>soegaard</code> pointed out, the main reference remains  <code>R. Kent Dybvig. "Three Implementation Models for Scheme"</code>.</p>\n\n<p>The idea is, a continuation is a closure that keeps its evaluation control stack.  The control stack is required in order to continue the evalution from the moment the continuation was created using <code>call/cc</code>.</p>\n\n<p>Oftenly invoking the continuation makes long time of execution and fills the memory with duplicated stacks.  I wrote this stupid code to prove that, in mit-scheme it makes the scheme crash,</p>\n\n<p>The code sums the first 1000 numbers <code>1+2+3+...+1000</code>.</p>\n\n<pre><code>(call-with-current-continuation \n (lambda (break)\n   ((lambda (s) (s s 1000 break))\n    (lambda (s n cc)\n      (if (= 0 n)\n          (cc 0)\n          (+ n\n             ;; non-tail-recursive,\n             ;; the stack grows at each recursive call\n             (call-with-current-continuation\n              (lambda (__)\n                (s s (- n 1) __)))))))))\n</code></pre>\n\n<p>If you switch from 1000 to 100 000 the code will spend 2 seconds, and if you grow the input number it will crash.</p>\n'}]
['https://Stackoverflow.com/questions/6512', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/658/']