source: project/wiki/eggref/5/srfi-189 @ 39245

Last change on this file since 39245 was 39245, checked in by Zipheir, 2 months ago

Create page.

File size: 24.9 KB
Line 
1== SRFI-189: Maybe and Either
2
3This SRFI defines two disjoint immutable container types known as Maybe and
4Either, both of which can contain objects collectively known as their payload.
5A Maybe object is either a Just object or the unique object Nothing (which has
6no payload); an Either object is either a Right object or a Left object. Maybe
7represents the concept of optional values; Either represents the concept of
8values which are either correct (Right) or errors (Left).
9
10Note that the terms Maybe, Just, Nothing, Either, Right, and Left are
11capitalized in this SRFI so as not to be confused with their ordinary use as
12English words. Thus "returns Nothing" means "returns the unique Nothing
13object"; "returns nothing" could be interpreted as "returns no values" or
14"returns an unspecified value".
15
16[[toc:]]
17
18== SRFI Description
19
20This page includes excerpts from the SRFI document, but is primarily
21intended to document the forms exported by this egg. For a full
22description of the SRFI, see the full
23[[https://srfi.schemers.org/srfi-189/srfi-189.html|SRFI document]].
24
25== Authors
26
27John Cowan (text) and Wolfgang Corcoran-Mathe (sample implementation)
28
29== Specification
30
31The four types Just, Nothing, Left, and Right are disjoint from each other and
32from all other Scheme types.
33
34We speak of unwrapping a container when we extract its payload, and wrapping
35values in a container when we create the container with the values as its
36payload.
37
38The following names are used for the arguments:
39<table>
40<tr><td>''obj'', ''default''</td><td>Any Scheme object.</td></tr>
41</td></tr>
42<tr><td>''maybe''</td><td>A Maybe object.</td></tr>
43</td></tr>
44<tr><td>''either''</td><td>An Either object.</td></tr>
45</td></tr>
46<tr><td>''failure''</td><td>A procedure that accepts zero arguments (unless specified otherwise).</td></tr>
47</td></tr>
48<tr><td>''success''</td><td>A procedure that accepts one or more arguments.</td></tr>
49</td></tr>
50<tr><td>''pred''</td><td>A predicate that accepts zero or more arguments.</td></tr>
51</td></tr>
52<tr><td>''equal''</td><td>A predicate that accepts two arguments and returns a boolean value. It is not necessarily an equivalence relation.</td></tr>
53</td></tr>
54<tr><td>''proc''</td><td>A procedure that accepts zero or more arguments and returns zero or more values.</td></tr>
55</td></tr>
56<tr><td>''mproc''</td><td>A procedure that accepts zero or more arguments and returns zero or more values wrapped in a single Maybe or Either container.</td></tr>
57</td></tr>
58<tr><td>''list''</td><td>A Scheme list.</td></tr>
59</td></tr>
60<tr><td>''producer''</td><td>A procedure that accepts no arguments and returns some number of values.</td></tr>
61</table>
62It is an error (unless otherwise noted) if the procedures are passed arguments
63that do not have the type implied by the argument names.
64
65== Maybe and Either
66
67=== Constructors
68
69<procedure>(just obj ...)</procedure>
70
71Monadic pure. Returns the {{objs}} wrapped in a Just.
72
73<procedure>(nothing)</procedure>
74
75Returns the unique Nothing object.
76
77<procedure>(right obj ...)</procedure>
78
79Monadic pure. Returns the {{objs}} wrapped in a Right.
80
81<procedure>(left obj ...)</procedure>
82
83Returns the {{objs}} wrapped in a Left.
84
85<procedure>(list->just list)</procedure>
86<procedure>(list->left list)</procedure>
87<procedure>(list->right list)</procedure>
88
89Returns a Just / Left / Right whose values are the elements of {{list}}. Note
90that these procedures are not monadic; they are equivalent to
91just/left/right but accept a list rather than multiple arguments. There is
92no need for {{list->nothing}} distinct from {{nothing}}.
93
94<procedure>(maybe->either maybe obj ...)</procedure>
95
96If {{maybe}} is a Just, returns a Right with the same payload objects in the
97sense of {{eqv?}}; otherwise returns a Left of _objs_.
98
99<procedure>(either->maybe either)</procedure>
100
101If {{either}} is a Right, returns a Just with the same payload objects in the
102sense of {{eqv?}}; otherwise returns Nothing.
103
104<procedure>(either-swap either)</procedure>
105
106If {{either}} is a Left, return a Right with the same payload objects (in the
107sense of {{eqv?}}), and vice versa.
108
109=== Predicates
110
111<procedure>(just? obj)</procedure>
112<procedure>(nothing? obj)</procedure>
113<procedure>(right? obj)</procedure>
114<procedure>(left? obj)</procedure>
115
116Returns {{#t}} if {{obj}} is a Just, Nothing, Left, or Right respectively, and
117{{#f}} otherwise.
118
119<procedure>(maybe? obj)</procedure>
120
121Returns {{#t}} if {{obj}} is a Maybe (that is, either a Just or Nothing) and {{#f}}
122otherwise.
123
124<procedure>(either? obj)</procedure>
125
126Returns {{#t}} if {{obj}} is an Either (that is, either a Right or a Left) and
127{{#f}} otherwise.
128
129<procedure>(maybe= equal maybe1 maybe2 ...)</procedure>
130
131Returns {{#t}} if all {{maybes}} are Nothing, or if they all are Justs and their
132respective payload objects are the same in the sense of {{equal}}, and {{#f}}
133otherwise.
134
135<procedure>(either= equal either1 either2 ...)</procedure>
136
137Returns {{#t}} if all {{eithers}} are all Lefts or all Rights and their respective
138payload objects are the same in the sense of {{equal}}, and {{#f}} otherwise.
139
140=== Accessors
141
142<procedure>(maybe-ref maybe failure [success])</procedure>
143
144If {{maybe}} is a Just, tail-calls the procedure {{success}} on the values of its
145payload and returns the result. Otherwise, it tail-calls the procedure
146{{failure}} on no arguments and returns the result. The default value of
147{{success}} is {{values}}.
148
149<procedure>(either-ref either failure [success])</procedure>
150
151If {{either}} is a Right, tail-calls the procedure {{success}} on the values of
152its payload and returns the result. Otherwise, it tail-calls the procedure
153{{failure}} on the values of its payload and returns the result. The default
154value of {{success}} is {{values}}.
155
156<procedure>(maybe-ref/default maybe default ...)</procedure>
157<procedure>(either-ref/default maybe default ...)</procedure>
158
159If {{maybe/either}} is a Just/Right, returns the values of its payload;
160otherwise returns the {{defaults}} as multiple values.
161
162=== Join and bind
163
164<procedure>(maybe-join maybe)</procedure>
165<procedure>(either-join either)</procedure>
166
167Monadic join. If {{maybe/either}} is a Just/Right whose single payload object is
168a Maybe/Either, returns that payload; if it is a Nothing/Left, returns
169{{maybe}}/{{either}}. In all other cases (including a Just/Right with multiple
170values) it is an error. Thus {{(maybe-join (just (just x))}} returns Just
171{{x}} and {{(maybe-join (just (nothing))}} returns Nothing, and similarly for
172{{either-join}}.
173
174<procedure>(maybe-compose mproc1 mproc2 ...)</procedure>
175<procedure>(either-compose mproc1 mproc2 ...)</procedure>
176
177Returns an mproc that accepts zero or more arguments and applies the following
178iterative algorithm to each {{mproc}}:
179
180The {{mproc}} is applied to the arguments and returns a Maybe/Either interim
181result. If the result is Nothing / a Left, it is returned as the final result.
182If it is a Just/Right, the next {{mproc}} is applied to the values of its
183payload, returning the next interim result. When no more {{mprocs}} are
184available, the interim result is returned as the final result.
185
186It is an error if one of the {{mprocs}} does not accept as arguments the number
187of values wrapped in the Just/Right produced by its predecessor.
188
189<procedure>(maybe-bind maybe mproc1 mproc2 ...)</procedure>
190<procedure>(either-bind either mproc1 mproc2 ...)</procedure>
191
192Monadic bind. If {{maybe/either}} is a Just/Right, it behaves as if
193{{maybe-compose}}/{{either-compose}} were applied to {{mprocs}}, and the
194resulting mproc applied to the payload of {{maybe}}/{{either}}. But if
195{{maybe}}/{{either}} is a Nothing/Left, it is immediately returned.
196
197=== Sequence operations
198
199These procedures treat Maybes (and in some cases Eithers) as sequences of
200length 0 or 1. This length depends only on the type of the container and not
201on the number of objects it contains.
202
203<procedure>(maybe-length maybe)</procedure>
204<procedure>(either-length either)</procedure>
205
206Return 1 if {{maybe}}/{{either}} is a Just/Right, and 0 otherwise.
207
208<procedure>(maybe-filter pred maybe)</procedure>
209<procedure>(maybe-remove pred maybe)</procedure>
210<procedure>(either-filter pred either obj ...)</procedure>
211<procedure>(either-remove pred either obj ...)</procedure>
212
213If {{maybe}}/{{either}} is a Just/Right and the values of its payload satisfy / do
214not satisfy {{pred}}, then return {{maybe}}; otherwise, returns Nothing / a Left
215of {{objs}}.
216
217<procedure>(maybe-sequence mappable map [aggregator])</procedure>
218<procedure>(either-sequence mappable map [aggregator])</procedure>
219
220The purpose of these procedures is to transform a collection of Maybes/Eithers
221of some particular type into a Maybe/Either of a collection, often of the same
222type.
223
224The {{mappable}} argument is the collection to be transformed, and the {{map}}
225argument is the appropriate procedure that can transform it, one element at a
226time. The signature of {{map}} is {{(map proc mappable)}}, where {{proc}} is
227supplied by the implementation. Typical mappables are lists and vectors, and
228{{map}} and {{vector-map}} are useful map functions, though not the only possible
229ones.
230
231Each element is processed as follows: If it is a Just/Right, its values are
232unwrapped and the {{aggregator}} function (which defaults to {{list}}) is applied
233to them. But if it is a Left/Nothing, that object is immediately returned as
234the value of {{maybe-sequence}}/{{either-sequence}}.
235
236Assuming there are no Lefts/Nothings, the {{map}} function is then responsible
237for constructing the new mappable out of the results of the calls on
238{{aggregator}}.
239
240For example, a list of Justs becomes a Just list of lists if the map procedure
241is {{map}} and the aggregator is {{list}}. In the same way, a vector of Rights
242containing one value each becomes a Right vector if the map procedure is
243{{vector-map}} and the aggregator is {{(lambda (x) x)}}.
244
245=== Protocol Conversion
246
247The purpose of Maybe and Either is to provide first-class objects
248representing the distinction between success and failure in such a way that
249any number of success values (and, in the case of Either, any number of
250failure values) can be packaged up in a single object without reserving any
251values to indicate success or failure. A variety of ''protocols'' are already in
252use in Scheme and other Lisps to more or less perfectly represent the
253distinction. Some reserve a value to represent failure which cannot be
254returned as a success value; some handle only one success value; some are not
255first-class.
256
257In order to facilitate communication between code using Maybe/Either and code
258using another protocol, the following procedures convert between Maybe/Either
259objects and some of the most usual protocols. Conversion in either direction is
260frequently lossy.
261
262☞ The following procedures interface between the Maybe protocol and the ''list''
263protocol, which uses an empty list to represent failure and a non-empty list
264to represent success.
265
266<procedure>(maybe->list maybe)</procedure>
267<procedure>(either->list either)</procedure>
268
269Returns a list whose elements are the payload of {{maybe}}/{{either}}; if
270{{maybe}}/{{either}} is Nothing/Left, returns the empty list. It is an error to
271mutate the result of this procedure.
272
273<procedure>(list->maybe list)</procedure>
274<procedure>(list->either list obj ...)</procedure>
275
276If {{list}} is empty, returns Nothing / wraps {{objs}} in a Left and returns it;
277otherwise, wraps the list elements in a Just/Right and returns that.
278
279☞ The following procedures interface between the Maybe and Either protocols
280and the ''truth'' protocol, which uses {{#f}} to represent failure and a single
281true value to represent success.
282
283<procedure>(maybe->truth maybe)</procedure>
284<procedure>(either->truth either)</procedure>
285
286If {{maybe}}/{{either}} is a Just/Right, returns its payload; otherwise returns
287{{#f}}. It is an error if the Just/Right does not have exactly one value.
288
289<procedure>(truth->maybe obj)</procedure>
290<procedure>(truth->either obj fail-obj ...)</procedure>
291
292If {{obj}} is {{#f}}, return Nothing / a Left of {{fail-objs}}; otherwise, return a
293Just/Right whose payload is {{obj}}.
294
295☞ The following procedures interface between the Maybe protocol and the
296''list-truth'' protocol, which uses {{#f}} to represent failure and a list to
297represent success.
298
299<procedure>(maybe->list-truth maybe)</procedure>
300<procedure>(either->list-truth either)</procedure>
301
302If {{maybe}}/{{either}} is a Just/Right, returns a list whose elements are the
303payload; otherwise, returns {{#f}}. It is an error to mutate the result of this
304procedure.
305
306<procedure>(list-truth->maybe list-or-false)</procedure>
307<procedure>(list-truth->either list-or-false obj ...)</procedure>
308
309If {{list-or-false}} is {{#f}}, returns Nothing / a Left of {{objs}}; otherwise,
310wraps the list elements in a Just/Right and returns it.
311
312☞ The following procedures interface between the Maybe and Either protocols
313and the ''generation'' protocol, which uses an end-of-file object to represent
314failure and any other value to represent success.
315
316<procedure>(maybe->generation maybe)</procedure>
317<procedure>(either->generation either)</procedure>
318
319If {{maybe}}/{{either}} is a Just/Right, then its payload is returned. It is an
320error if the Just/Right does not have exactly one value. If {{maybe}}/{{either}}
321is Nothing / a Left, then an end-of-file object is returned.
322
323<procedure>(generation->maybe obj)</procedure>
324<procedure>(generation->either obj fail-objs ...)</procedure>
325
326If {{obj}} is an end-of-file object, return Nothing / a Left of {{fail-objs}}.
327Otherwise, return {{obj}} wrapped in a Just/Right.
328
329☞ The following procedures interface between the Maybe and Either protocols
330and the ''values'' protocol, which returns one or more values to represent
331success and zero values to represent failure.
332
333<procedure>(maybe->values maybe)</procedure>
334<procedure>(either->values either)</procedure>
335
336If {{maybe}}/{{either}} is a Just/Right, returns the values of its payload;
337otherwise returns no values.
338
339<procedure>(values->maybe producer)</procedure>
340<procedure>(values->either producer fail-obj ...)</procedure>
341
342These procedures invoke {{producer}} with no arguments. If no values are
343returned, Nothing / Left of {{fail-objs}} is returned. Otherwise the values are
344wrapped in a Just/Right and returned.
345
346☞ The following procedures interface between the Maybe protocol and the
347''two-values'' protocol, which returns {{#f}} and {{#f}} to represent failure and a
348single value and {{#t}} to represent success. (This protocol is more often used
349in Common Lisp, where additional values are automatically discarded if the
350continuation expects only one.)
351
352<procedure>(maybe->two-values maybe)</procedure>
353
354If {{maybe}} is a Just, returns the value of its payload and the additional
355value {{#t}}; otherwise returns two values, both {{#f}}. It is an error if {{maybe}}
356does not have exactly one value.
357
358<procedure>(two-values->maybe producer)</procedure>
359
360This procedure is the inverse of {{maybe->two-values}}. It invokes {{producer}}
361with no arguments. If the second value is true, the first value is wrapped in
362a Just and returned; otherwise, Nothing is returned.
363
364<procedure>(exception->either pred thunk)</procedure>
365
366This procedure is in a sense the inverse of {{maybe-ref}}. A call to {{thunk}} is
367made, wrapped in an exception handler that examines any exception signaled
368during {{thunk}}'s execution. If the condition object satisfies {{pred}}, it is
369wrapped in a Left which is then returned; if it does not, the exception is
370reraised. But if no exception is raised, the values returned by {{thunk}} are
371wrapped in a Right and the Right is returned.
372
373=== Map, fold and unfold
374
375<procedure>(maybe-map proc maybe)</procedure>
376<procedure>(either-map proc either)</procedure>
377
378Monadic map. If {{maybe}}/{{either}} is a Just/Right, applies {{proc}} to the payload
379values and wraps the returned values as a Just/Right; otherwise returns
380{{maybe}}/{{either}}.
381
382<procedure>(maybe-for-each proc maybe)</procedure>
383<procedure>(either-for-each proc either)</procedure>
384
385If {{maybe}}/{{either}} is a Just/Right, applies {{proc}} to the payload values and
386discards the result; otherwise does nothing. Returns an unspecified result.
387
388<procedure>(maybe-fold kons nil maybe)</procedure>
389<procedure>(either-fold kons nil either)</procedure>
390
391If {{maybe}}/{{either}} is a Just/Right, {{kons}} is invoked on the values of its
392payload and the additional value {{nil}} and the result is returned; otherwise,
393{{nil}} is returned.
394
395<procedure>(maybe-unfold stop? mapper successor seed ...)</procedure>
396<procedure>(either-unfold stop? mapper successor seed ...)</procedure>
397
398If {{stop?}} returns true on {{seeds}}, a Nothing / a Left of {{seeds}} is returned.
399Otherwise, {{successor}} is applied to {{seeds}}. If {{stop?}} returns false on the
400results of {{successor}}, it is an error. But if the second call to {{stop?}}
401returns true, {{mapper}} is applied to {{seeds}} and the results are wrapped in a
402Just/Right and returned.
403
404=== Syntax
405
406<syntax>(maybe-if maybe-expr just-expr nothing-expr)</syntax>
407
408Equivalent to {{(if (just? maybe-expr) just-expr nothing-expr)}}, except
409that an error satisfying {{error-object?}} is signaled if {{maybe-expr}} does not
410evaluate to a Maybe.
411
412<syntax>(maybe-and expr ...)</syntax>
413<syntax>(either-and expr ...)</syntax>
414
415The {{expr}}s are evaluated in order. If an {{expr}} evaluates to a Nothing /
416Left, it is returned without evaluating any more expressions. Otherwise, the
417last Just / Right is returned. If there are no {{exprs}}, then a Just/Right of
418an unspecified value is returned. If an {{expr}} does not evaluate to a
419Maybe/Either, an error satisfying {{error-object}} is signaled.
420
421<syntax>(maybe-or expr ...)</syntax>
422<syntax>(either-or expr ...)</syntax>
423
424The {{exprs}} are evaluated in order. If an {{expr}} evaluates to a Just/Right, it
425is returned without evaluating any more expressions. Otherwise, the last
426Nothing/Left is returned. If there are no {{exprs}}, then Nothing / a Left of an
427unspecified value is returned. If an {{expr}} does not evaluate to a
428Maybe/Either, an error satisfying {{error-object}} is signaled.
429
430<syntax>(maybe-let* (claw ...) . body)</syntax>
431<syntax>(either-let* (claw ...) . body)</syntax>
432
433The Maybe/Either equivalent of {{and-let*}} from [[http://srfi.schemers.org/srfi-2/srfi-2.html|SRFI 2]].
434However, instead of testing
435whether a {{claw}} is true or false, it tests whether it is Just/Right or
436Nothing/Left. If a {{claw}} does not evaluate to a Maybe/Either, an error
437satisfying {{error-object}} is signaled. The same is true if a {{claw}} evaluates
438to a Just or Right that wraps zero values or more than one value.
439
440A {{claw}} is either a bound identifier, or a list of length 1, in which case it
441is an expression, or a list of length 2, in which case it is a variable and an
442expression. In either case, the value of the {{claw}} is the value of the bound
443variable or expression. If the value of a {{claw}} is Nothing / a Left, the
444expression immediately returns that value. But if the value of a {{claw}} is a
445Just/Right, then the variable (if any) is bound to its unwrapped value; the
446scope of this binding is any remaining {{claws}} and the {{body}}.
447
448If the values of all the {{claws}} are Just/Right, then the {{body}} is evaluated
449as if it were in a {{(let () ...)}}, and its values are wrapped in a Just/Right
450and returned.
451
452<syntax>(maybe-let*-values (claw ...) . body)</syntax>
453<syntax>(either-let*-values (claw ...) . body)</syntax>
454
455The same as {{maybe/either-let*}}, except that the first element of a two-element
456claw is a <formals> from {{lambda}}, and the variables mentioned in it
457(if any) are bound to the values that result from unpacking a Just/Right. Note
458that a claw with a single variable in {{maybe}}/{{either-let*}} is bound to the sole
459value contained in the Just/Right, whereas in {{maybe}}/{{either-let*-values}}, it
460is bound to a list of all the values, just as in a {{lambda}} expression, a
461<formals> consisting of a single variable is bound to a list of all the
462procedure arguments.
463
464<syntax>(either-guard pred-expr . body)</syntax>
465
466The syntactic analogue of {{exception->either}}. The {{body}} is evaluated, and
467the values it produces are wrapped in a Right and returned, unless an
468exception occurs. If the condition object that is raised satisfies the
469predicate that is the value of {{pred-expr}}, the condition object is wrapped in
470a Left and returned; otherwise the condition is reraised as if by {{raise-continuable}}.
471
472=== Trivalent logic
473
474These procedures provide trivalent logic in the style of SQL on Maybe objects
475containing a single value. For the purposes of this section, an object counts
476as false if it is Just {{#f}}, true if it is Just anything else. It is an error
477if any argument is not a Maybe.
478
479Unlike {{and}} and {{or}}, {{tri-and}} and {{tri-or}} are procedures and not syntax,
480because determining their value requires that all the arguments be evaluated
481in order to provide correct SQL-style semantics. For example, {{(and #f (nothing))}}
482will return {{#f}} immediately without evaluating its second
483argument, but {{(tri-and (just #f) (nothing))}} will return Nothing.
484
485<procedure>(tri-not maybe)</procedure>
486
487Returns Just {{#t}} if {{maybe}} is false, Just {{#f}} if {{maybe}} is true, and
488Nothing if {{maybe}} is Nothing.
489
490<procedure>(tri=? maybe1 maybe2 ...)</procedure>
491
492Similar to {{boolean=?}}, returning Just {{#t}} if all the {{maybes}} are true or if
493all are false. Otherwise, if any {{maybe}} is Nothing or any two {{maybes}} have
494different (trivalent) truth values, returns Just {{#f}}.
495
496Note: this function is not transitive and therefore is not an equivalence
497relation.
498
499<procedure>(tri-and maybe ...)</procedure>
500
501If all {{maybes}} are true, Just {{#t}} is returned. If any {{maybe}} is false or
502Nothing, then the first such {{maybe}} is returned. If there are no arguments,
503Just {{#t}} is returned.
504
505<procedure>(tri-or maybe ...)</procedure>
506
507If all {{maybes}} are false, Just {{#f}} is returned. If any {{maybe}} is true or
508Nothing, then the first such {{maybe}} is returned. If there are no arguments,
509Just {{#f}} is returned.
510
511<procedure>(tri-merge maybe ...)</procedure>
512
513If any {{maybes}} are true or false, then the first such {{maybe}} is returned. If
514all {{maybes}} are Nothing, then Nothing is returned. If there are no arguments,
515Nothing is returned.
516
517== Examples
518
519Here is a variant of [[https://srfi.schemers.org/srfi-1/srfi-1.html#Searching|SRFI 1]]
520{{find}} that returns a Maybe, and so can be safely
521used to search for {{#f}} in a list, just like any other value:
522
523<enscript highlight="scheme">
524(define (maybe-find pred list)
525  (cond
526    ((null? list) (nothing))
527    ((pred (car list)) (just (car list)))
528    (else (maybe-find pred (cdr list)))))
529</enscript>
530
531The following examples show how {{find}} and {{maybe-find}} differ in their
532results:
533
534<enscript highlight="scheme">
535(define (atom? obj) (not (pair? obj)))
536(define with-t '((1) #t (3) 4 5))
537(define with-f '((1) #f (3) 4 5))
538(define without '((1) (2) (3) (4) (5)))
539
540(find atom? with-t) => #t
541(find atom? with-f) => #f
542(find atom? without) => #f
543
544(maybe-find atom? with-t) => Just #t
545(maybe-find atom? with-f) => Just #f
546(maybe-find atom? without) => Nothing
547</enscript>
548
549And here is {{head}}, which is more general than {{car}} because it lets the
550caller figure out what happens if its argument is not a pair and can handle an
551argument that is either an actual pair or Just a pair.
552
553<enscript highlight="scheme">
554(define (head x)
555  (cond
556    ((pair? x) (just (car x)))
557    ((and (just? x) (pair? (maybe-ref x))) (just (car (maybe-ref x))))
558    (else (nothing))))
559</enscript>
560
561In other words, if the argument to {{head}} is a pair, whether wrapped in a Just
562or not, the result is the car of that pair wrapped in a Just; in all other
563cases, the result is Nothing. (There are simpler ways to do this using more
564advanced procedures.)
565
566== About This Egg
567
568=== Dependencies
569
570The [[https://wiki.call-cc.org/eggref/5/srfi-145|srfi-145]],
571[[https://wiki.call-cc.org/eggref/5/r7rs|r7rs]], and
572[[https://wiki.call-cc.org/eggref/5/srfi-1|srfi-1]] eggs are required.
573
574=== Maintainer
575
576Wolfgang Corcoran-Mathe <wcm at sigwinch dot xyzzy without the zy>
577
578=== Repository
579
580[[https://github.com/Zipheir/srfi-189-chicken|GitHub]]
581
582=== Version History
583
584; 0.1 (2020-11) : Initial release.
585
586== License
587
588Copyright (C) John Cowan, Wolfgang Corcoran-Mathe (2020).
589
590Permission is hereby granted, free of charge, to any person obtaining a copy
591of this software and associated documentation files (the "Software"), to deal
592in the Software without restriction, including without limitation the rights
593to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
594copies of the Software, and to permit persons to whom the Software is
595furnished to do so, subject to the following conditions:
596
597The above copyright notice and this permission notice (including the next
598paragraph) shall be included in all copies or substantial portions of the
599Software.
600
601THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
602IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
603FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
604AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
605LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
606OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
607SOFTWARE.
Note: See TracBrowser for help on using the repository browser.