<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">I understand that Rust is not doing implicit conversions, but the effect for the user is pretty much the same. &nbsp;The try macro is converting the underlying error to the type that can be propagated. &nbsp;As I stated, Swift is not Rust and deserves a different solution. &nbsp;</div><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">Nevertheless, that does not minimize the need to solve the problem. &nbsp;I maintain that the <b class="">problem </b>solved by the try macro is a significant one that is not addressed by the current proposal. &nbsp;I would really like to see it addressed one way or another.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">You could make it “nicer” by doing something like this:</div><div class=""><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><font face="Menlo" class="">try&nbsp;MyError.convertFrom(try&nbsp;funcThatThrowsAnErrorThatMustBeTranslatedItoMyPublishedError())</font></div></div></blockquote></div></div></blockquote><div class=""><br class=""></div><div class="">Can you elaborate on how you think this would work? &nbsp;If&nbsp;funcThatThrowsAnErrorThatMustBeTranslatedItoMyPublishedError actually throws it will be propagated to the next enclosing catch clause. &nbsp;MyError.convertFrom will not have a chance to do anything with it.</div></div></div></div></blockquote><div><br class=""></div><div>Here’s a full playground example (I’ve annotated in comments where the type of error could be described):</div><div><br class=""></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div><div><font face="Menlo" class="">enum&nbsp;InternalError:&nbsp;ErrorType&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;Internal(value: Int)</font></div></div><div><div><font face="Menlo" class="">}</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class="">enum&nbsp;PublishedError:&nbsp;ErrorType&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;static&nbsp;func&nbsp;from&lt;T&gt;(@autoclosure&nbsp;fn: ()&nbsp;throws&nbsp;-&gt;&nbsp;T)&nbsp;throws&nbsp;-&gt;&nbsp;T&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;do&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;try&nbsp;fn()</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;catch&nbsp;InternalError.Internal(let&nbsp;value) {</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;throw&nbsp;PublishedError.Converted(value: value)</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;catch&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fatalError("unsupported conversion")</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;Converted(value: Int)</font></div></div><div><div><font face="Menlo" class="">}</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class="">func&nbsp;example() {</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;bad(value:&nbsp;Int)&nbsp;throws&nbsp;/* InternalError */&nbsp;-&gt;&nbsp;Int&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;value %&nbsp;2&nbsp;==&nbsp;0&nbsp;{&nbsp;throw&nbsp;InternalError.Internal(value: value) }</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;value</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;verbose(value:&nbsp;Int)&nbsp;throws&nbsp;/* PublishedError */&nbsp;-&gt;&nbsp;Int&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;do&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;try&nbsp;bad(value)</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;catch&nbsp;InternalError.Internal(let&nbsp;value) {</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;throw&nbsp;PublishedError.Converted(value: value)</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;catch&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fatalError("unsupported conversion")</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;func&nbsp;convert(value:&nbsp;Int)&nbsp;throws&nbsp;/* PublishedError */&nbsp;-&gt;&nbsp;Int&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;try&nbsp;PublishedError.from(try&nbsp;bad(value))</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;do&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;r1 =&nbsp;try&nbsp;verbose(11)</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("verbose:&nbsp;\(r1)")</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;let&nbsp;r2 =&nbsp;try&nbsp;convert(9)</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("converted:&nbsp;\(r2)")</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;catch&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;print("error:&nbsp;\(error)")</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class="">}</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div></div><div><div><font face="Menlo" class="">example()</font></div></div></blockquote><div><div><br class=""></div><div><br class=""></div><div>As you can see, the “verbose()” and the “from()” conversion are basically the same implementation. What I’m saying is that I believe you can simply do the explicit conversion yourself without much fanfare (compare the verbose() and convert() implementations).</div><div><br class=""></div><div>In the implementation of PublishedError.from() you can use Swift’s pattern matching to do all of your conversions in a single place. Note that where the implementation of “from” is at doesn’t matter, it could be on another type or a free function, whatever.</div><div><br class=""></div><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Are you willing to explore adding *explicit* syntax to convert thrown errors to your proposal? &nbsp;That seems like it might be a reasonable compromise between implicit conversions and manual boilerplate. &nbsp;</div></div></blockquote><div><br class=""></div><div>The only boiler plate I’m seeing is the explicit conversion call: PublishedError.from(try&nbsp;bad(value))</div><div><br class=""></div><div>Am I misunderstanding something?&nbsp;</div><div><br class=""></div><div>To me, this would be much more confusing:</div><div><br class=""></div><div><div><div><font face="Menlo" class="">&nbsp; &nbsp; func&nbsp;convert(value:&nbsp;Int)&nbsp;throws&nbsp;/* PublishedError */&nbsp;-&gt;&nbsp;Int&nbsp;{</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return try&nbsp;bad(value) &nbsp; &nbsp; /* implicit conversion from InternalError -&gt; PublishedError */</font></div></div><div><div><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div><div></div></div><div><br class=""></div><div>If there were implicit type conversions, this would have to be something that Swift supported all up. I’d be very hesitant to make this work for only errors. For example, how does implicit conversion work if we can later extend this to async behaviors? Do we have special conversions that can take an async error make it a synchronous error? How about vice-versa?</div><div><br class=""></div><div>I guess I wouldn’t want to go further than having explicit conversions until we better understood all of those answers and how implicit type conversion would work in Swift generally. If I recall, Swift had implicit type conversion in the early versions, and it has been removed in most places.&nbsp;</div><br class=""></div><div>-David</div><br class=""></body></html>