summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2018-04-19 06:43:06 -0700
committerKaz Kylheku <kaz@kylheku.com>2018-04-19 06:43:06 -0700
commit458d9d74887a837dfd3c22be43fa828b948685bc (patch)
treef70517f22eb8790dedbc40d298322ae5e2ba26de
parentf2d9bb59432f7ed58365ddc7ea4ffd6f5080a354 (diff)
downloadtxr-458d9d74887a837dfd3c22be43fa828b948685bc.tar.gz
txr-458d9d74887a837dfd3c22be43fa828b948685bc.tar.bz2
txr-458d9d74887a837dfd3c22be43fa828b948685bc.zip
doc: continuations: compiled vs interpreted.
* txr.1: Turn the comparison with lexical closures into a named subsection instead of Notes. Add subsection about mutated lexical variables and continuations: how the behavior can differ between interpreted and compiled code. Point user to the hlet and hlet* macros.
-rw-r--r--txr.139
1 files changed, 38 insertions, 1 deletions
diff --git a/txr.1 b/txr.1
index bf05c548..48db6a75 100644
--- a/txr.1
+++ b/txr.1
@@ -37864,7 +37864,7 @@ Unfortunately, the absconding operator is dangerous: its use
breaks the language guarantee that clean-up associated with a form is done no
matter how a form terminates.
-.TP* Notes:
+.NP* Comparison with Lexical Closures
Delimited continuations resemble lexical closures in some ways. Both
constructs provide a way to return to some context whose evaluation
@@ -37888,6 +37888,43 @@ environment. The continuation function returns to its caller when that entire
restarted context terminates, whereas a closure returns to its caller as soon
as the closure body terminates.
+.NP* Differences in Compiled vs. Interpreted Behavior
+
+Delimited continuations in \*(TX expose a behavioral difference between
+compiled and interpreted code.
+
+When a continuation is captured in compiled code, it captures not only the
+bindings of lexical variables, but also potentially their current values
+at the time of capture. Lexical variables captured in a continuation which are
+changed after a continuation is captured may appear to revert to their
+capture-time values inside the restored continuation. This is because in compiled
+code, variables are allocated on the stack, which is copied as part of
+creating a continuation. By contrast, interpreted code only maintains an
+environment pointer on the stack; the lexical environment is a dynamically
+allocated object whose contents aren't included in the continuation.
+Code that doesn't mutate variables will not see a difference.
+An additional complication is that when compiled code captures lexical
+closures, captured variables are moved into dynamic storage.
+
+In continuation-based code which relies on mutation of lexical variables
+created with
+.code let
+or
+.codn let* ,
+the macros
+.code hlet
+and
+.code hlet*
+can be used instead. These macros create variable bindings whose storage is
+outside of the stack.
+
+If the affected variables are other kinds of bindings such as
+function parameters or variables created with specialized binding
+constructs such as
+.codn with-stream ,
+additional coding changes may be required to get interpreted code
+working under compilation.
+
.coNP Function @ sys:capture-cont
.synb
.mets (sys:capture-cont < name < receive-fun <> [ context-form ])