In particular, in Common Lisp, restarts are only valid in the dynamic environment where they were created by restart-bind. In contrast, call/cc captures this dynamic environment and makes it available later. You can't store restarts and invoke them later the way you can with call/cc.
You simply cannot create a stack trace from within a C++ exception handler because that state is gone. Hence my argument that exceptions are not a continuation, there is nothing to continue.
try{
foo()
}catch(Exception e){
bar(e)
}
void foo() {
throw new exception();
}
with (bar (call/cc foo))
(defun foo (cont)
(cont (make-exception))
However, this ignores most details of the problem. In fact, (re-entrant) continuations and exceptions can't be mixed in the same language: Common Lisp has not adopted `call/cc` for one because it's impossible or at least much harder to implement `unwind-protect` (`finally`) in the presence of `call/cc` [0].The major difference is that continuations allow you to do this:
(defparam *global*)
(defparam *shadow-list* (list))
(defun foo (cont)
(setf *global* cont))
(with-open-file (f "~/file.log")
(loop
for line = (read-line stream nil 'eof)
until (eq line 'eof)
collect (cons line (call/cc foo)))
(*global* *shadow-list*)
(*global* *shadow-list*) ;; what is the state of the file here? what if there was an exception reading from the file?
[0] https://groups.google.com/g/comp.lang.lisp/c/1Ggl_BUi3Yg/m/V...To be fair, it's probably relatively easy to use dynamic-wind to raise some runtime error when trying to resume the continuation after the original context "ended".
Pitman's comments on this are in http://www.nhplace.com/kent/PFAQ/unwind-protect-vs-continuat..., Sitaram's response is at http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.79.3..., and Pitman's final response is at http://www.nhplace.com/kent/PFAQ/unwind-protect-vs-continuat....