What is an idiomatic way to handle failure in Racket?
Asked Answered
C

1

5

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?

Cupidity answered 8/6, 2017 at 15:23 Comment(0)
A
7

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
Aureus answered 8/6, 2017 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.