source: project/wiki/eggref/4/forcible @ 36746

Last change on this file since 36746 was 36746, checked in by svnwiki, 6 months ago

Anonymous wiki edit for IP [176.52.204.58]: Update for new version.

File size: 7.0 KB
Line 
1[[tags: egg]]
2== forcible
3
4Thread- and exception aware, lazy-looking synchronization with timeouts - extending
5srfi-45.
6
7[[toc:]]
8
9== Rationale
10
11{{Force}} and {{delay}} from CHICKEN core as well as SRFI-45 exhibit
12unintuitive behavior in the presence of SRFI-18 threads and when
13exceptions are raised.  The srfi-45 egg extends the srfi-45 reference
14implementation to support multiple values but is still unintuitive
15wrt. threads and exceptions.
16
17This egg builds and extends those, explicit aiming on the following
18objectives:
19
20* Explicit support for multiple value returns from suspended
21  expressions.
22
23* Aware of threads and exception handling.  Multiple threads
24  {{force}}ing the same {{promise}} do NOT cause multiple evaluation
25  of the {{delay}}ed (or {{lazy}}) expression.  The same thread may
26  still recurse into the {{promise}} being forced.
27
28* Bounded space as in srfi-45.
29
30* Extends {{force}} with optional parameters to simplify exception
31  handling.
32
33* {{Future}}s are syntactically similar to {{lazy}} but evaluated in
34  another SRFI-18 thread.
35
36* Cheap timeouts.
37
38* Adds single use "awaitable" values ({{expectable}}).
39
40* Does NOT supplement CHICKEN's force/delay but replaces it.  (To
41  reduce confusion for developers.  Supplementing them as the srfi-45
42  egg does had caused too many confusion for the author of this egg at
43  least.)
44
45== Requirements
46
47Requires [[pigeon-hole]], [[llrb-tree]] for timeout handling.
48
49The implementation of {{expectable}} currently (2016-01-10)
50depends on a CHICKEN having the fix for
51[[http://bugs.call-cc.org/ticket/1231|Ticket 1231]] applied.
52
53== Timeouts
54
55Timeouts come at negligible runtime overhead – the cost of being
56coarse grained.  It is assumed that most timeouts never "fire" hence
57the are deferred for the sake of optimization.  Timeouts fire only if
58they are not canceled before at least a full {{timeout-period}}
59passed.  A {{timeout-period}} defaults to one second.
60
61== API
62
63<procedure>(timeout-condition? x) -> boolean</procedure>
64
65Test x to be a timeout condition object.
66
67<procedure>(eager . vals) -> PROMISE</procedure>
68
69Returns a promise which, when {{force}}d returns the values {{vals}}.
70
71<syntax>(lazy EXPRESSION) -> PROMISE</syntax>
72
73Returns a promise for {{EXPRESSION}}.
74
75<syntax>(delay EXPRESSION) -> PROMISE</syntax>
76
77Returns a promise, a delayed evaluation of {{EXPRESSION}}.
78
79<syntax>(delay/timeout TIMEOUT EXPRESSION) -> PROMISE</syntax>
80
81Same as {{delay EXPRESSION}}.  Promise may fail raising an object
82for which {{timeout-condition?}} returns {{#t}}.
83
84<syntax>(future EXPRESSION) -> PROMISE</syntax>
85<syntax>(&begin BODY ...) -> PROMISE</syntax>
86
87Returns a promise, a delayed evaluation of {{EXPRESSION}}.  The
88evaluation of expression is started immediately in another thread.
89{{PROMISE}} will cache exceptions returned by {{EXPRSSION}}.
90
91{{&begin}} is analogous to {{future}} with {{BODY ...}} wraped in
92{{begin}}.
93
94<syntax>(future/timeout TIMEOUT EXPRESSION) -> PROMISE</syntax>
95<syntax>(&begin/timeout TIMEOUT BODY ...) -> PROMISE</syntax>
96
97Variation of {{future}}.  The evaluation of {{EXPRESSION}} receives an
98exceptions for which {{timeout-condition?}} holds after {{TIMEOUT}}.
99
100{{&begin/timeout}} is the same as {{future/timeout}} with {{BODY ...}}
101waped in {{begin}}.
102
103<syntax>(order EXPRESSION) -> PROMISE</syntax>
104
105Returns a promise, a delayed evaluation of {{EXPRESSION}}.  The
106evaluation of expression is ordered from another thread in a
107threadpool.  {{PROMISE}} will cache exceptions returned by
108{{EXPRSSION}}.
109
110<syntax>(order/timeout TIMEOUT EXPRESSION) -> PROMISE</syntax>
111
112Variation of {{order}}.  The evaluation of {{EXPRESSION}} receives an
113exceptions for which {{timeout-condition?}} holds after {{TIMEOUT}}.
114
115<syntax>(lazy-future EXPRESSION) -> PROMISE</syntax>
116
117Same as {{future}} however the thread is NOT started.  Use {{demand}}
118to start it prior to {{force}}.  Use of {{force}} will also start it
119if not {{demand}}ed before.
120
121<procedure>(demand PROMISE) -> boolean</procedure>
122
123If the {{PROMISE}} was created by {{lazy-future}} and the thread is
124not yet started, start it.  Returns {{#t}} if the thread was started only
125now, otherwise returns {{#f}}.
126
127<procedure>(force OBJECT [FAIL] [SUCCESS]) -> . *</procedure>
128
129Force {{OBJECT}}.  Applies {{SUCCESS}} (which defaults to {{values}})
130to the results of the suspended {{EXPRESSION}} (or {{OBJECT}} if it is
131NOT a promise).
132
133If {{FAIL}} is provided it must be a procedure of one argument.
134Exceptions raised from the {{EXPRESSION}} are passed to {{FAIL}}.
135{{FAIL}} defaults to {{raise}}.
136
137This is equivalent to (but may be more efficiently implemented than)
138 (handle-exceptions ex (FAIL ex) (force OBJECT))
139
140
141<procedure>(expectable [NAME] [THUNK]) -> PROCEDURE PROMISE</procedure>
142
143{{NAME}} is any object and used for debug purposes only (currently
144passed as name of an internal mutex).  Returns two values.
145{{PROCEDURE}} takes a flag indicating whether the {{PROMISE}} shall
146return successful (if {{#t}}) or fail and values to return from
147{{force}}ing the {{PROMISE}}.  If the flag is {{#f}} only the first of
148those values is used and passed to the exception handler as the
149exception raised from the {{PROMISE}}.
150
151When {{THUNK}} is given the resulting promise behaves like a promise
152created by {{lazy}}.
153
154=== Low Level
155
156<procedure>(fulfil! PROMISE TYPE . ARGS) -> boolean</procedure>
157
158Mutate {{PROMISE}} to be fulfilled.  {{TYPE}} must be a boolean.  If
159{{#t}} the {{PROMISE}} is set to return successfully the values
160{{ARGS}}.  If {{TYPE}} is {{#f}} the {{PROMISE}} will raise the first
161value of {{ARGS}} as exception.
162
163Note: This procedure MAY be removed in future versions (if it proves
164to be questionable).
165
166== About this egg
167
168=== Source
169
170Latest version:
171[[http://askemos.org/chicken-eggs/forcible/forcible.tar.gz|forcible from askemos.org]]
172
173=== Version History
174
1750.3.9: Ported to CHICKEN 5.
176
1770.3.8: Bugfix.
178
1790.3.6: Attempted fix implementation wrt. execution in bounded space
180actally creating a leak.
181
1820.3: Added {{/timeout}}.
183
1840.2: Added optional {{THUNK}} to {{expectable}}.
185
1860.1: Initial version.
187
188=== Authors
189
190Jörg F. Wittenberger
191
192=== License
193
194Permission is hereby granted, free of charge, to any person obtaining a
195copy of this software and associated documentation files (the Software),
196to deal in the Software without restriction, including without limitation
197the rights to use, copy, modify, merge, publish, distribute, sublicense,
198and/or sell copies of the Software, and to permit persons to whom the
199Software is furnished to do so, subject to the following conditions:
200
201The above copyright notice and this permission notice shall be included
202in all copies or substantial portions of the Software.
203
204THE SOFTWARE IS PROVIDED ASIS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
205IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
206FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
207THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
208OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
209ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
210OTHER DEALINGS IN THE SOFTWARE.
Note: See TracBrowser for help on using the repository browser.