There are a few idioms:
exceptions
Exceptions are used mainly for errors, but occasionally for other kinds of "exceptional" situations.
(vector-ref "hello" 0)
raises an exception, because a string is not a vector
(string-ref "hello" 72)
raises an exception, because the index is out of bounds
(open-output-file "/does/not/exist")
raises an exception if the path doesn't exist, or can't be opened because of permissions
result values
Some functions return a union where the type acts like a datatype variant. A result of X or false
is especially common.
(assoc 'a '((a . 1) (b . 2)))
returns the pair (a . 1)
, but
(assoc 'c '((a . 1) (b . 2)))
returns false
(read-string 10)
returns either a string or the special eof
object if there are no characters available before the end of the port
The cond =>
syntax can be useful for dealing with X or false
results:
(cond [(assoc key alist) => cdr] [else default-value])
failure continuations
Some functions take an extra (usually optional) argument that determines what happens on certain kinds of failures.
(hash-ref ht key)
raises an error if ht
doesn't contain an entry for key
, but
(hash-ref ht key failure)
either calls failure
(if it is a procedure) or just returns it (otherwise) if ht
doesn't contain key
- but
(hash-ref not-a-hash-table key failure)
raises a contract violation exception; it doesn't call failure