Exception
Exceptions are just a special kind of variant, "thrown" in exceptional cases (don't abuse them!).
Usage
RElet getItem = (theList) =>
if (callSomeFunctionThatThrows()) {
/* return the found item here */
} else {
raise(Not_found)
};
let result =
try (getItem([1, 2, 3])) {
| Not_found => 0 /* Default value if getItem throws */
};
Note that the above is just for demonstration purposes; in reality, you'd return an option(int)
directly from getItem
and avoid the try
altogether.
You can directly match on exceptions while getting another return value from a function:
REswitch (List.find((i) => i === theItem, myItems)) {
| item => print_endline(item)
| exception Not_found => print_endline("No such item found!")
};
You can also make your own exceptions like you'd make a variant (exceptions need to be capitalized too).
exception InputClosed(string); ... raise(InputClosed("the stream has closed!"));
Tips & Tricks
When you have ordinary variants, you often don't need exceptions. For example, instead of throwing when item
can't be found in a collection, try to return an option(item)
(None
in this case) instead.
Design Decisions
The above tip seems to contradict what's happening in the OCaml standard library; prominent functions in modules such as List and String seems to throw exceptions overly often. This is partially a historical sediment, and partially out of extreme care for performance. Native OCaml/Reason is incredibly performant; exception throwing was designed to be very cheap, cheaper than allocating and returning e.g. an option
. This is unfortunately not the case for JavaScript.
Newer standard library alternatives usually come with option
-returning functions rather than exception-throwing ones. For example, List.find
has the option
-returning counterpart List.find_opt
, which doesn't throw.
Exceptions are actually just variants too. In fact, they all belong to a single variant type, called exn
. It's an extensible variant, meaning you can add new constructors to it, such as InputClosed
above. exception Foo
is just a sugar for adding a constructor to exn
.