I remain partially unconvinced, but you make a good point. In any case this sounds like something orthogonal to the proposal - as a pre-existing concern - and so best handled separately, e.g. in a future SEP.

public func map<U, E>( _ transform: (Wrapped) throws(E) -> U ) throws(E) -> U?
In the body of map, how are you going to throw an instance of type
E
if not by callingtransform
? Its only constraint is that it conforms toError
, and that protocol doesn't have any way to create a new instance. One would need to either add more constraints onE
(which will show up in the signature) or do some kind of dynamic casting to create an instance ofE
.
I apologise, I had forgotten about this, from the detailed discussion of rethrows in the prior pitch review thread. Indeed @xwu covered that specific possibility. Thanks for reiterating that important point.
You're right that it does make the typed throw version closer to equivalent than I was thinking, at least for most [likely] uses. However, you might also recall from that prior thread that there are valid, realistic cases where the intended semantics - of the existing rethrows
- are not enforceable with just typed throws (as opposed to typed rethrows), such as this example by @michelf. Not common use-cases, for sure.
I assume it's not fruitful to duplicate the discussion on this here - I somewhat summarised my thoughts previously, and @anandabits helped refine my point - and I trust that the proposal's reviewers will incorporate that earlier discussion & feedback.

I suspect that
rethrows
will ultimately be removed from the language.rethrows
is in this unfortunate place where there are existing soundness holes in the checking; yet these soundness holes are load-bearing because there are patterns you cannot write withrethrows
(the proposal shows this), and code in the wild is using these holes to provide good APIs. Sorethrows
either needs to be extended and made sound (e.g., the pitch I linked that proposesrethrows(unsafe)
), or it needs to be removed.This proposal isn't removing
rethrows
outright for several reasons:
- It's a source-breaking change in a proposal that tries very hard not to be source-breaking.
- It's possible that there uses of
rethrows
not well-covered by typed throws (although I have yet to see one).- The bar for removal of an existing feature is significantly higher than for the introduction of a new feature, and I don't want this proposal to be delayed by that higher bar.
It might be reasonable to immediately follow up this proposal with another one that lays out the argument for eliminating
rethrows
. Personally, I think we can let it sit for a year or more to see whether typed throws has subsumed all uses ofrethrows
.
I certainly acknowledge that rethrows
has some enforcement issues (although I'm also not stressed by them, because unlike e.g. memory or concurrency safeguards, the holes in rethrows
are much less likely to lead to severe effects like memory corruption or invalid program states).
I want to agree (on the procedure and timing - I still think rethrows
has merit and is worth preserving).
My hesitance to defer the rethrows
question is because until rethrows
is properly resolved (one way or another), we'll have an unfortunate time period in which users are forced to choose between rethrows
and typed errors. It would, arguably, be the more conservative option to support typed rethrows as part of this SEP as it'll mean users have to make fewer tough decisions and fewer [undesirable] semantic changes to their code, in adopting typed throws. And that still doesn't preclude then reviewing rethrows
and potentially removing it (which is the source-breaking aspect that, as you note, is a much bigger deal).
I also fear that people will predominately choose typed throws over rethrows
if forced to, and this will be misconstrued as a "popular vote" against the unique benefits of rethrows
.
But - lest we forget or I appear under-appreciative - I do want to thank you once more for the incredibly thorough thinking and work done on this proposal, especially as you say with an eye towards avoiding source- and binary-incompatible changes. I'm really impressed by some of the subtleties you identified and found elegant workarounds for (for Swift 5 mode). As much as I've heartily debated some aspects of the proposal, such as rethrows
, I find very little overall that I can even nit-pick about.
Exhaustivity checking in catch
I appreciate the extra details & discussion on why exhaustivity checking for catch
is implementationally difficult. It certainly convinces me that it's reasonable to defer any further improvements there to a future SEP, as much as I'll miss the functionality in the meantime.
I suggest, though, including a little of that "why not" detail in the SEP itself, for future readers (who are more likely to find the SEP than this forum thread). Both to better explain the rationale and also for the interesting, educational glimpse into how the type checker and exhaustivity checking do [and don't] interact today. Plus it will help clarify that there's no dispute about the desire for the checking, but rather that we just don't know how to implement it efficiently enough [yet].
(and I use "we" in the most self-aggrandising sense here, because I haven't the faintest clue how to solve that thorny performance issue )