Remix.run Logo
koito17 a day ago

More importantly, Rust has the notion of a result type and it is designed to be both generic and composable.

A problem I often face in Go and TypeScript code is code that ignores errors, often unintentionally. For instance, many uses of JSON.parse in TypeScript do not check for the SyntaxError that may be thrown. In Go, it is common to see patterns like

  _ := foo.Bar()
  // assume Bar() returns error
This pattern exists to tell the reader "I don't care if this method returns an error". It allows one to avoid returning an error, but it also stops the caller from ever being handle to the error.

Also, the position of the error matters. While the convention in the stdlib is to return errors as the final value, this isn't necessarily followed by third party code.

Similarly, errors are just an interface and there is no requirement to actually handle returned errors. Even if one wants to handle errors, it's quite awkward having to use errors.As or errors.Is to look into a (possibly wrapped) chain of errors.

The benefit of Rust's Result<T, E> is that

- position doesn't matter

- there is strong, static type checking

- the language provides operators like ? to effortlessly pass errors up the call stack, and

- the language provides pattern matching, so it's easy to exhaustively handle errors in a Result

The last two points are extremely important. It's what prevents boilerplate like

  if err != nil {
    return nil, err
  }
and it's what allows one to write type-safe code rather than guess whether errors.As() or errors.Is() should be used to handle a returned error.
DanielHB a day ago | parent | next [-]

I am pretty sure if it were for the Typescript creators they would not allow exceptions in the language, but they had to work within the confines of Javascript. Heck they even refused to make exceptions part of the type-system.

It is unfortunate that many of Typescript developers still rely on throwing exceptions around (even in their own typescript code). Result types are totally doable in Typescript and you can always wrap native calls to return result types.

quotemstr a day ago | parent | prev [-]

Why would you "check" for TypeError being thrown? Just let exceptions in general propagate until they reach one of the few places in the program that can log, display, crash, or otherwise handle an exception. No need to "check" anything at call sites.

90% of the criticism of exceptions I see comes from the bizarre and mistaken idea that every call needs to be wrapped in a try block and every possible error mentioned.