Typed throws

Found the post in the old thread why I had the impression that there was some issue with rethrowswhere it must remain untyped:

Honestly, I personally don‘t see any. It would be cool if we could replace the keyword as in a typed throws world it can be misleading, but that‘s not a priority to me.


Bikeshedding alarm, not necessarily something to include into the proposal unless it gains some traction:

// assuming E: Error and F: Error 

() -> Void === () throws<Never> -> Void
() throws -> Void === () throws<Error> -> Void
() throws<E> -> Void

// replacing `rethrows` with `throws?`

// requires `try` if closure throws anything other than `Never` 
// and just like above it would be a shorthand that throws `Error`
( () throws<E> -> Void ) throws? -> Void === ( () throws<E> -> Void ) throws?<Error> -> Void

// requires `try` if closure throws anything other than `Never` 
// but it would throw a custom type `F`
( () throws<E> -> Void ) throws?<F> -> Void

// requires `try` if closure throws anything other than `Never` 
// and the user has the impression that it just rethrows `E`
( () throws<E> -> Void ) throws?<E> -> Void

This makes the model simpler, at least from my point of view:

  • throw always requires try
  • throw? (renamed rethrows) only requires try if one closure parameter throws anything else than Never
  • error type rules and all shorthands would be consistent between both variants, hence throws? == throws?<Error>

One more note. There is no way to control the conditional rethorwing mechanism to explicitly specify which closure parameter it should track if there are many.

More bike shedding:

Instead of throws?<...> we'd add a configurable parameter throws<...>(...).

(() throws -> Void, () throws -> Void) throws<ErrorType>(.always)-> Void
// same as 
(() throws -> Void, () throws -> Void) throws<ErrorType> -> Void

// tracks only first parameter
(() throws -> Void, () throws -> Void) throws<ErrorType>(.parameter(1)) -> Void

// tracks all, which means if one of them is throwable, the compiler will require `try`
(() throws -> Void, () throws -> Void) throws<ErrorType>(.all) -> Void
  • Do we need this much control around rethrows?
  • Has anyone ever wanted something like this already?
  • Can we solve some existing problems with this?
1 Like