I am used to OCaml where I rely heavily on the result
type, along with a monadic interface to handle failures in my applications. Exceptions do exist in OCaml but I rarely use them, except for working around the absence of a return
keyword.
Is there such a trend in Racket (especially typed Racket)? What is an idiomatic way to handle and propagate failure in Racket applications?
There are a few idioms:
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 permissionsSome 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 portThe cond =>
syntax can be useful for dealing with X or false
results:
(cond [(assoc key alist) => cdr] [else default-value])
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
(hash-ref not-a-hash-table key failure)
raises a contract violation exception; it doesn't call failure
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With