summary refs log tree commit diff
path: root/err.svnwiki
blob: 932518455cfeb7a6089a5cbdeee7f41ec36c3c54 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
= Err, a scheme library for reasoning with results

{{err}} provides a disjoint error data type, and helper functions to
conveniently work with them.


== Design

{{err}} distinguishes two types of values:
{{err}} objects, for which {{err?}} returns true,
and all others (so called {{ok}} objects).

This means that existing code can be incorporated very easily as ok
values do not need to be wrapped.
Likewise, passing errors to existing code will trigger type errors quickly.
(Note that the empty list, the false value, and the unspecified
values are all considered {{ok}}.)

For integrating with code which uses exceptions for error handling,
{{err}} provides the {{guard-err}} macro and the {{ok}} procedure to convert
between the two mechanisms.

If you prefer explicit container types, you may like
SRFI 189 ("Maybe and Either").

If you need to deal with {{err}} values in a transparent way,
you can use SRFI 111 ("Boxes") to contain them as {{ok}} values.


== Core functions

<procedure>(err <obj>)</procedure>

Returns an err object that contains {{<obj>}}.
If {{<obj>}} already is an err object, just returns {{<obj>}}.

<procedure>(unerr <obj>)</procedure>

Returns the object wrapped in the {{err}} object {{<obj>}}.
Returns an unspecified value if {{<obj>}} is not an {{err}} object.

<procedure>(err? <obj>)</procedure>

Returns true if {{<obj>}} is an {{err}} object, false otherwise.

<procedure>(ok? <obj>)</procedure>

Returns true if {{<obj>}} is not an {{err}} object, false otherwise.


== Helpers

<procedure>(ok/if <obj> <case-ok> [<case-err>])</procedure>

If {{<obj>}} is not an {{err}} object, calls {{<case-ok>}} with {{<obj>}}
as argument.  If {{<obj>}} is an {{err}} object, and {{<case-err>}}
is given, calls {{<case-err>}} with the value that was wrapped in {{<obj>}};
if {{<case-err>}} is not given, returns {{<obj>}} as is.

<procedure>(ok=> <obj> <fun>...)</procedure>

Successively applies functions {{<fun>}} to the value {{<obj>}}
(and then its return value etc.) as long as {{<obj>}} is {{ok?}}.

<procedure>(err=> <obj> <fun>...)</procedure>

If {{<obj>}} is an {{err}} object, unwrap it and successively
apply the functions {{<fun>}}, else just return {{<obj>}}.
(NB: this is not the dual to {{ok=>}}, as immediate values
can be {{ok}} objects but function application continues.)

<syntax>(ok/or <expr>...)</syntax>

Evaluate the expressions {{<expr>...}} from left to right,
stop and return as soon one is {{ok}}.

<syntax>(ok/and <expr>...)</syntax>

Evaluate the expressions {{<expr>...}} from left to right,
stop and return as soon one is not {{ok}}.

<syntax>(guard-err [(<exn>...)] <expr>)</syntax>

Evaluate {{<expr>}} and when an exception is raised which is listed in
{{<exn>...}} (or, by default, any exception), return the condition
object wrapped as an {{err}} object.

<syntax>(ok <obj>)</syntax>

If {{<obj>>}} is an {{err}} object, raise it as an error (or re-raise
if it wrapped a condition).  Else, return {{<obj>}}.