I write a fair number of rethrows
functions. These are often generic over a protocol, and the caller passes in a closure such as a predicate or transform. (Sometimes more than one.)
In every case, the implementation of the rethrowing function either calls the closures, or passes them along to another rethrowing function, or perhaps wraps them in a larger closure before doing one of those things.
Regardless, every place where the predicate is used, that line must be marked with try
. Sometimes two tries are needed on the same line, as in:
try foo{ try !predicate($0) }
These try
markings are all just noise.
Inside a rethrows
function, any error thrown by the predicate is expected and intended to be rethrown. Nothing is gained by writing try
there.
The only exception is if the rethrowing function for some reason actually wants to catch an error from one of its arguments. I consider this to be extremely rare, and even then it is only within a do-try-catch
block that writing try
makes sense.
When there is no catch
block, the fact that we are in a rethrows
function makes the use of try
superfluous. It is simply unnecessary boilerplate.
I would like to see the rules around try
improved in this regard, so that in the body of a rethrowing function, uses of its closure parameters do not require try
(unless they are inside a do-catch
block).
• • •
As a side tangent, I also think that from a readability standpoint, closure parameters that can be rethrown should be marked something like rethrown
instead of throws
.
Marking the parameter throws
when the function itself is rethrows
seems incongruous. The whole point of rethrows
is that the parameter may or may not be throwing, but the word “throws” communicates to the reader that the parameter is necessarily throwing, which is incorrect.