<div dir="ltr">Interestingly what Haravikk describes is mentioned here.<div><br></div><div><a href="http://ericasadun.com/2015/08/27/capturing-context-swiftlang/">http://ericasadun.com/2015/08/27/capturing-context-swiftlang/</a><br></div><div><br></div><div>This approach is very similar to Rubys</div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr">
<p><b><font color="#cc0000">___________________________________</font></b></p><p><b>James⎥Head of Trolls</b></p><p><b><font color="#cc0000"><a href="mailto:james@supmenow.com" target="_blank">james@supmenow.com</a>⎥<a href="http://supmenow.com" target="_blank">supmenow.com</a></font></b></p><p><b><font size="2">Sup</font></b></p><p><b><font size="2">Runway East
</font></b></p><p><b><font size="2">10 Finsbury Square</font></b></p><p><b><font size="2">London</font></b></p><p><b><font size="2">
EC2A 1AF </font></b></p></div></div></div></div></div></div></div></div></div></div></div>
<br><div class="gmail_quote">On Tue, Mar 8, 2016 at 10:07 AM, Haravikk via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> On 8 Mar 2016, at 01:21, Brent Royal-Gordon <<a href="mailto:brent@architechies.com">brent@architechies.com</a>> wrote:<br>
><br>
>> A duplicate shouldn’t be necessary; functions/initialisers that can throw just need to be called with a flag indicating whether they should capture or ignore errors as appropriate for try vs try? and try!. Any statement that is identified as being specific to a throw is then wrapped in a conditional based on this flag so it can be skipped if errors are ignored.<br>
><br>
> Okay, so you're passing in what amounts to a new parameter (which is going to take up a register or some stack space that could be used for something else) and adding a new conditional branch at each throw site. In cases where a `try` is nested directly inside a `throws` function, you might need a conditional branch at the return site, too. (Remember, CPUs hate conditional branches.)<br>
<br>
</span>It’s a conditional that should only have an impact when an error is being (or about to be) thrown, also I don’t think that a conditional at the call site would be necessary; if you know that try? or try! was used then you know that the flag was passed and that you’ll get no error instance back, just whatever usually passes the error status.<br>
<span class=""><br>
> I think that your use of the word "laziness" is telling. You are assuming that, if someone doesn't throw detailed errors, they are being lazy.<br>
<br>
</span>You’re assuming that every error has to be as detailed as possible ;)<br>
<br>
I’m working from the assumption that part of updating the standard library to remove failable initialisers would include creating a set of common errors that developers can use too if they like. For example, yes, InvalidParameterError wouldn’t be super informative (though it at least informs you that the issue was with the parameter itself, and not something else that failed internally), however if there were errors for non-numeric input and such that this could provide extra information. You can certainly argue that it could still provide more information, but if we’re considering all failable initialisers to be “simple” then there will be a point at which you’re providing more information than anyone is actually going to use; a developer can certainly choose to do-so, but ultimately there may still be cases where just knowing that there was an error, or an error of a particular type, is enough.<br>
<span class=""><br>
> To illustrate, I spent ten or fifteen minutes examining IntegerParsing.swift.gyb so I could understand the failure cases of `Int.init(_:radix)`. To fully model all of the errors which can cause it to return `nil`, and without including any redundant information you could get from the string itself, you would probably need this enum:<br>
><br>
> enum IntFromStringError: ErrorType {<br>
> case EmptyString<br>
> case NoDigits<br>
> case NegativeUnsigned<br>
> case TooLarge (at: String.UTF16View.Index)<br>
> case NonDigit (at: String.UTF16View.Index)<br>
> case DigitBeyondRadix (at: String.UTF16View.Index)<br>
> }<br>
><br>
</span><span class="">> if your answer is "Don't do all that, just lump everything together into one vague error", then why are we using the throwing mechanism in the first place? Failable initializers convey one vague error just as well and with much less fuss.<br>
<br>
</span>My answer would be more along the lines of “just lump everything together into reasonably specific errors”. For example, EmptyString and NoDigits could easily be handled by a general purpose non-numeric error, while the rest could be handled by an integer out of range error of some kind; that should be plenty to communicate the problem, while detail messages could provide further information to the developer if the error is coming up unexpectedly (e.g- from input you thought was safe).<br>
<br>
Instead of “something was wrong” you would then have two possibilities for what was wrong, and the potential to get more information if you need it during testing.<br>
<span class=""><br>
> If an error should only occur during debugging, it should be a precondition, not a failable *or* throwing initializer.<br>
><br>
> By definition, any throwable error should be something you expect to happen in the normal course of running the code out in the wild. That means there needs to be enough detail to either automatically fix the problem or usefully present it to a user, either textually or with some kind of graphical representation (like pointing to the invalid character).<br>
<br>
</span>Not quite what I meant; I would absolutely expect the error to occur in the wild, and be caught or ignored as appropriate, the message is just for cases where you’re not sure why it’s occurred in the first place, i.e- the error (and its type) is often enough all you need in simpler error cases, but if you’re getting them unexpectedly rather than due to anticipated mistakes in input etc. then you may want the extra detail. You certainly could model it for programmatic inspection and that’s an option too, but it may not be necessary.<br>
<br>
Just because someone opts to use error handling over a failable initialiser doesn’t mean they have to go overboard on the detail of their errors; it’s entirely possible to pick a reasonable middle-ground. In other words, the work you put in should absolutely reflect some kind of value, but you seem to be assuming that the maximum possible amount of work has to be put into every error type thrown, where I think that most simple errors can be adequately modelled from a decent set of default error types; anything more complex absolutely should go into more detail as appropriate, but again they don’t necessarily have to expose the most minute of details.<br>
<div class="HOEnZb"><div class="h5">_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</div></div></blockquote></div><br></div>