]> gitweb.factorcode.org Git - factor.git/blob - core/continuations/continuations-docs.factor
Initial import
[factor.git] / core / continuations / continuations-docs.factor
1 USING: help.markup help.syntax kernel kernel.private
2 continuations.private parser vectors arrays namespaces
3 threads assocs words quotations ;
4 IN: continuations
5
6 ARTICLE: "errors-restartable" "Restartable error handling"
7 "Support for restartable errors is built on top of the basic error handling facility. The following words signals recoverable errors:"
8 { $subsection throw-restarts }
9 { $subsection rethrow-restarts }
10 "The list of restarts from the most recently-thrown error is stored in a global variable:"
11 { $subsection restarts }
12 "To invoke restarts, see " { $link "debugger" } "." ;
13
14 ARTICLE: "errors-post-mortem" "Post-mortem error inspection"
15 "The most recently thrown error, together with the continuation at that point, are stored in a pair of global variables:"
16 { $subsection error }
17 { $subsection error-continuation }
18 "Developer tools for inspecting these values are found in " { $link "debugger" } "." ;
19
20 ARTICLE: "errors" "Error handling"
21 "Support for handling exceptional situations such as bad user input, implementation bugs, and input/output errors is provided by a set of words built using continuations."
22 $nl
23 "Two words raise an error in the innermost error handler for the current dynamic extent:"
24 { $subsection throw }
25 { $subsection rethrow }
26 "A set of words establish an error handler:"
27 { $subsection cleanup }
28 { $subsection recover }
29 { $subsection catch }
30 "Unhandled errors are reported in the listener and can be debugged using various tools. See " { $link "debugger" } "."
31 { $subsection "errors-restartable" }
32 { $subsection "errors-post-mortem" } ;
33
34 ARTICLE: "continuations.private" "Continuation implementation details"
35 "A continuation is simply a tuple holding the contents of the five stacks:"
36 { $subsection continuation }
37 { $subsection >continuation< }
38 "The five stacks can be read and written:"
39 { $subsection datastack }
40 { $subsection set-datastack }
41 { $subsection retainstack }
42 { $subsection set-retainstack }
43 { $subsection callstack }
44 { $subsection set-callstack }
45 { $subsection namestack }
46 { $subsection set-namestack }
47 { $subsection catchstack }
48 { $subsection set-catchstack }
49 "The continuations implementation has hooks for single-steppers:"
50 { $subsection walker-hook }
51 { $subsection set-walker-hook }
52 { $subsection (continue) }
53 { $subsection (continue-with) } ;
54
55 ARTICLE: "continuations" "Continuations"
56 "At any point in the execution of a program, the " { $emphasis "current continuation" } " represents the future of the computation."
57 $nl
58 "Words for working with continuations are found in the " { $vocab-link "continuations" } " vocabulary; implementation details are in " { $vocab-link "continuations.private" } "."
59 $nl
60 "Continuations can be reified with the following two words:"
61 { $subsection callcc0 }
62 { $subsection callcc1 }
63 "Another two words resume continuations:"
64 { $subsection continue }
65 { $subsection continue-with }
66 "Continuations serve as the building block for a number of higher-level abstractions."
67 { $subsection "errors" }
68 { $subsection "continuations.private" } ;
69
70 ABOUT: "continuations"
71
72 HELP: catchstack*
73 { $values { "catchstack" "a vector of continuations" } }
74 { $description "Outputs the current catchstack." } ;
75
76 HELP: catchstack
77 { $values { "catchstack" "a vector of continuations" } }
78 { $description "Outputs a copy of the current catchstack." } ;
79
80 HELP: set-catchstack
81 { $values { "catchstack" "a vector of continuations" } }
82 { $description "Replaces the catchstack with a copy of the given vector." } ;
83
84 HELP: continuation
85 { $values { "continuation" continuation } }
86 { $description "Reifies the current continuation from the point immediately after which the caller returns." } ;
87
88 HELP: >continuation<
89 { $values { "continuation" continuation } { "data" vector } { "retain" vector } { "call" vector } { "name" vector } { "catch" vector } { "c" array } }
90 { $description "Takes a continuation apart into its constituents." } ;
91
92 HELP: ifcc0
93 { $values { "capture" "a quotation with stack effect " { $snippet "( continuation -- )" } } { "restore" quotation } }
94 { $description "Reifies a continuation from the point immediately after which this word returns, and passes it to " { $snippet "capture" } ". When the continuation is restored, execution resumes and "{ $snippet "restore" } " is called." } ;
95
96 HELP: ifcc1
97 { $values { "capture" "a quotation with stack effect " { $snippet "( continuation -- )" } } { "restore" quotation } }
98 { $description "Reifies a continuation from the point immediately after which this word returns, and passes it to " { $snippet "capture" } ". When the continuation is restored, execution resumes and "{ $snippet "restore" } " is called." } ;
99
100 { callcc0 continue callcc1 continue-with ifcc0 ifcc1 } related-words
101
102 HELP: callcc0
103 { $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } } }
104 { $description "Applies the quotation to the current continuation, which is reified from the point immediately after which the caller returns. The " { $link continue } " word resumes the continuation." } ;
105
106 HELP: callcc1
107 { $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } } { "obj" "an object provided when resuming the continuation" } }
108 { $description "Applies the quotation to the current continuation, which is reified from the point immediately after which the caller returns. The " { $link continue-with } " word resumes the continuation, passing a value back to the original execution context." } ;
109
110 HELP: set-walker-hook
111 { $values { "quot" "a quotation with stack effect " { $snippet "( continuation -- )" } ", or " { $link f } } }
112 { $description "Sets a quotation to be called when a continuation is resumed." }
113 { $notes "The single-stepper uses this hook to support single-stepping through code which makes use of continuations." } ;
114
115 HELP: walker-hook
116 { $values { "quot" "a quotation with stack effect " { $snippet "( obj -- )" } ", or " { $link f } } }
117 { $description "Outputs a quotation to be called when a continuation is resumed, or " { $link f } " if no hook is set. If a hook was set prior to this word being called, it will be reset to " { $link f } "."
118 $nl
119 "The following words do not perform their usual action and instead just call the walker hook if one is set:"
120     { $list
121         { { $link callcc0 } " will call the hook, passing it the continuation to resume." }
122         { { $link callcc1 } " will call the hook, passing it a " { $snippet "{ obj continuation }" } " pair." }
123         { { $link stop } " will call the hook, passing it " { $link f } "." }
124     }
125 "The walker hook must take appropriate action so that the callers of these words see the behavior that they expect." }
126 { $notes "The single-stepper uses this hook to support single-stepping through code which makes use of continuations." } ;
127
128 HELP: (continue)
129 { $values { "continuation" continuation } }
130 { $description "Resumes a continuation reified by " { $link callcc0 } " without invoking " { $link walker-hook } "." } ;
131
132 HELP: (continue-with)
133 { $values { "obj" "an object to pass to the continuation's execution context" } { "continuation" continuation } }
134 { $description "Resumes a continuation reified by " { $link callcc1 } " without invoking " { $link walker-hook } ". The object will be placed on the data stack when the continuation resumes." } ;
135
136 HELP: continue
137 { $values { "continuation" continuation } }
138 { $description "Resumes a continuation reified by " { $link callcc0 } "." } ;
139
140 HELP: continue-with
141 { $values { "obj" "an object to pass to the continuation's execution context" } { "continuation" continuation } }
142 { $description "Resumes a continuation reified by " { $link callcc1 } ". The object will be placed on the data stack when the continuation resumes." } ;
143
144 HELP: error
145 { $description "Global variable holding most recently thrown error." }
146 { $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
147
148 HELP: error-continuation
149 { $description "Global variable holding current continuation of most recently thrown error." }
150 { $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
151
152 HELP: restarts
153 { $var-description "Global variable holding the set of possible restarts for the most recently thrown error." }
154 { $notes "Only updated by " { $link throw } ", not " { $link rethrow } "." } ;
155
156 HELP: >c
157 { $values { "continuation" continuation } }
158 { $description "Pushes an exception handler continuation on the catch stack. The continuation must have been reified by " { $link callcc1 } "." } ;
159
160 HELP: c>
161 { $values { "continuation" continuation } }
162 { $description "Pops an exception handler continuation from the catch stack." } ;
163
164 HELP: throw
165 { $values { "error" object } }
166 { $description "Saves the current continuation in the " { $link error-continuation } " global variable and throws an error. Execution does not continue at the point after the " { $link throw } " call. Rather, the innermost catch block is invoked, and execution continues at that point." } ;
167
168 HELP: catch
169 { $values { "try" quotation } { "error/f" object } }
170 { $description "Calls the " { $snippet "try" } " quotation. If an error is thrown in the dynamic extent of the quotation, restores the data stack and pushes the error. If the quotation returns successfully, outputs " { $link f } " without restoring the data stack." }
171 { $notes "This word cannot differentiate between the case of " { $link f } " being thrown, and no error being thrown. You should never throw " { $link f } ", and you should also use other error handling combinators where possible." } ;
172
173 { catch cleanup recover } related-words
174
175 HELP: cleanup
176 { $values { "try" quotation } { "cleanup-always" quotation } { "cleanup-error" quotation } }
177 { $description "Calls the " { $snippet "try" } " quotation. If no error is thrown, calls " { $snippet "cleanup-always" } " without restoring the data stack. If an error is thrown, restores the data stack, calls " { $snippet "cleanup-always" } " followed by " { $snippet "cleanup-error" } ", and rethrows the error." } ;
178
179 HELP: recover
180 { $values { "try" quotation } { "recovery" "a quotation with stack effect " { $snippet "( error -- )" } } }
181 { $description "Calls the " { $snippet "try" } " quotation. If an exception is thrown in the dynamic extent of the " { $snippet "try" } " quotation, restores the data stack and calls the " { $snippet "recovery" } " quotation to handle the error." } ;
182
183 HELP: rethrow
184 { $values { "error" object } }
185 { $description "Throws an error without saving the current continuation in the " { $link error-continuation } " global variable. This is done so that inspecting the error stacks sheds light on the original cause of the exception, rather than the point where it was rethrown." }
186 { $notes
187     "This word is intended to be used in conjunction with " { $link recover } " or " { $link catch } " to implement error handlers which perform an action and pass the error to the next outermost error handler."
188 }
189 { $examples
190     "The " { $link with-parser } " catches errors, annotates them with file name and line number information, and rethrows them:"
191     { $see with-parser }
192 } ;
193
194 HELP: throw-restarts
195 { $values { "error" object } { "restarts" "a sequence of " { $snippet "{ string object }" } " pairs" } { "restart" object } }
196 { $description "Throws a restartable error using " { $link throw } ". The " { $snippet "restarts" } " parameter is a sequence of pairs where the first element in each pair is a human-readable description and the second is an arbitrary object. If the error reaches the top-level error handler, the user will be presented with the list of possible restarts, and upon invoking one, execution will continue after the call to " { $link condition } " with the object associated to the chosen restart on the stack." }
197 { $examples
198     "Try invoking one of the two restarts which are offered after the below code throws an error:"
199     { $code
200         ": restart-test"
201         "    \"Oops!\" { { \"One\" 1 } { \"Two\" 2 } } condition"
202         "    \"You restarted: \" write . ;"
203         "restart-test"
204     }
205 } ;
206
207 HELP: rethrow-restarts
208 { $values { "error" object } { "restarts" "a sequence of " { $snippet "{ string object }" } " pairs" } { "restart" object } }
209 { $description "Throws a restartable error using " { $link rethrow } ". Otherwise, this word is identical to " { $link throw-restarts } "." } ;
210
211 { throw rethrow throw-restarts rethrow-restarts } related-words
212
213 HELP: compute-restarts
214 { $values { "error" object } { "seq" "a sequence" } }
215 { $description "Outputs a sequence of triples, where each triple consists of a human-readable string, an object, and a continuation. Resuming a continuation with the corresponding object restarts execution immediately after the corresponding call to " { $link condition } "."
216 $nl
217 "This word recursively travels up the delegation chain to collate restarts from nested and wrapped conditions." } ;
218
219 HELP: save-error
220 { $values { "error" "an error" } }
221 { $description "Called by the error handler to set the " { $link error } " and " { $link restarts } " global variables after an error was thrown." }
222 $low-level-note ;
223
224 HELP: init-error-handler
225 { $description "Called on startup to initialize the catch stack and set a pair of hooks which allow the Factor VM to signal errors to library code." } ;