Should ReScript move more towards explicit control flow?

TypeScript doesn’t solve JavaScript’s problem with implicit control flow. For example, any library function (or really any function) might throw an error or do something unexpected. Unless you wrap it in a try/catch, your application can crash unexpectedly.

ReScript has the result type, which is great for explicit, recoverable error handling. However, I notice that throwing exceptions is still very common and feels like a first-class concept in the language. Functions like Option.getOrThrow, List.headOrThrow, JSON.parseOrThrow, and similar helpers are provided in the standard library. They make it easy (and tempting) to throw in many situations.

One of ReScript’s biggest strengths could be creating safer libraries by porting TypeScript or JavaScript ones and replacing implicit throws with explicit option or result returns. Speaking from experience, ReScripters will likely reach for these methods that throw to reach parity in their codebase, and may even stop there. However, deprecating or eliminating these functions would force consumers to handle errors properly instead of letting crashes happen silently or loudly.

I’m wondering whether the ReScript type system and standard library should lean even more toward explicit control flow. Perhaps we could do this by deprecating, renaming, or marking as “unsafe” the methods that throw exceptions in favor of their safe counterparts.

What are your thoughts? Is this already the direction the community wants, or are exceptions (and throwing helpers) intentionally kept for pragmatic reasons, especially around JS interop?