On Thu, Jan 12, 2017 at 6:17 PM, Jonathan Hull <[email protected]> wrote:
> > On Jan 12, 2017, at 3:35 PM, Xiaodi Wu <[email protected]> wrote: > > On Thu, Jan 12, 2017 at 4:58 PM, Jonathan Hull via swift-evolution < > [email protected]> wrote: > >> I really like swift’s error handling system overall. It strikes a good >> balance between safety and usability. >> >> There are some cases where it would be nice to throw errors, but errors >> are rarely expected in most use cases, so the overhead of ‘try’, etc… would >> make things unusable. Thus fatalError or optionals are used instead. For >> example, operators like ‘+’ could never throw because adding ’try’ >> everywhere would make arithmetic unbearable. But in a few cases it would >> make my algorithm much cleaner if I just assume it will work and then catch >> overflow/underflow errors if they happen, and resolve each of them with >> special cases. Or perhaps I am dealing with user entered values, and want >> to stop the calculation and display a user visible error (e.g. a symbol in >> a spreadsheet cell) instead of crashing. >> > > Unless I'm mistaken, there is a performance overhead for throwing > functions, and thus a much greater barrier to the use cases outlined above > is that the performance penalty for '+' would be unacceptable in any case, > whatever syntactic sugar you could come up with. > > > I think that is an invalid assumption. I don’t think we should limit our > proposals based on the performance of the naive/brute-force implementation. > I am sure there are lots of tricks the compiler could pull if performance > is an issue. Off the top of my head, although the user model is that it > adds “try!” before the function, it could actually make two different > versions of the function (one with fatalError and the other with error > handling) and insert the right one based on how it is called. > Sure, that's not the meat of why I'm uncomfortable with the idea. I am saying, however, that you've outlined as motivation two use cases here that your proposal does not make possible. > I would like to propose adding ‘throws?’ and ‘throws!’ variants to >> ‘throws’. >> >> These would be used for cases where error handling is not the default >> desired behavior, but having it as an option is desired occasionally. > > > While I admit the idea has an appeal on a practical level, I have an > uncomfortable feeling about this. It's by definition true that error > handling is never the default desired behavior, and if I recall correctly > the performance of Swift error handling is tuned on the assumption that not > throwing is far more common than throwing. If we accept this statement at > face value as the justification for including `throws!`, then essentially > all `throws` should be `throws!`. And indeed I suspect that if the feature > were be implemented, that would rapidly become the case in much written > Swift. In essence, then, I think you're effectively proposing to invert the > assignment of responsibility for determining how errors are handled from > the call site to the declaration site, at least by default. It goes against > an overarching design principle in Swift (discussed earlier in the thread > about DefaultConstructible) not to provide such defaults and to require > explicitness at the call site. > > > I would argue that it allows the framework designer a lot of > expressiveness about what they feel the correct approach is. By using > ‘throws’, ‘throws?’, or ‘throws!’, they are able to require explicitness or > not depending on how they expect the framework to be used. There is still > a lot of value to plain old ‘throws’ (namely where I need the user to > consider the possibility of error), and I would continue to use it for most > cases. It is the cases where I have been forced to use fatalError, where I > would use ‘throws!’. > Have a gander at this document: https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst In particular, have a look at the section titled "Kinds of error." I think what you're describing here is that you've got something that's neither a simple domain error nor a recoverable error, as classically described. And you'll see that there are some kinds of error for which Swift doesn't currently have a good answer. I'd be interested in some real-world use cases, though, and a more holistic approach to these other kinds of error would be called for. It's why I'm saying you've got the beginning of an interesting idea, but it's a lot more involved than you're making it out to be. While mistake prevention is a worthy goal which I support fully, there is a > difference between preventing programming errors and trying to enforce > one’s coding philosophy on everyone. I would argue for things like this, > we should favor expressiveness and then trust framework designers to use > that expressiveness responsibly. I might argue differently in cases where > there was a high probability of foot-gunning, but I don’t feel like this is > one of those cases. It is a choice made by the framework designer (just > like they can make a class ‘open’ or not), and the good designers will use > it well. > > I would also add that all of your arguments apply equally well to ‘as!’ > and forced unwrapping using ‘!’ which are both things that swift includes. > Thus I don’t think it is a overarching design principle of swift as you > claim. Rather we have safety by default, with the ability to override. > My arguments haven't been expressed very clearly, then, if you think that they support such an interpretation. Instead, `as!` and `!` are analogous to `try!`: they are used at the call site to statically assert something. By contrast, your proposal is essentially to have these inferred silently, as a default supplied at the declaration site. There is a distinction between these two, and as pointed out in the other conversation referenced above, Swift is said to choose call site clarity over defaults as a general overarching principle. > Essentially, the user would no longer have to preface the call with ‘try’, >> as the compiler would implicitly add ‘try?’ or ‘try!’ respectively. >> >> Thus, the function would act like a non-throwing function (either >> trapping or returning an optional in the case of error), but the user could >> add ‘try’ to the call to override that behavior and deal with the error >> more explicitly. >> >> Another example would be bounds checking on arrays. If subscripting >> arrays was marked as ‘throws!’ then it would have the same default behavior >> it does now (trapping on bounds error). But a user could add ‘try?’ to >> return nil for a bounds error in cases where they explicitly want that, or >> they could add ‘try’ to deal with it as an error using do-catch. >> > > Subscripts cannot throw at all at the moment, and in another thread some > of the challenges for designing throwing subscripts were just mentioned. I > suspect any sort of throwing subscript will not be possible in the > immediate future, so the argument for `throws!` here is moot. > > > On the contrary, it is on the roadmap, and thus is something we should > plan for. > It is not, as far as I'm aware, the plan of record in any sense; it has not been proposed and is not an identified priority of this phase of Swift 4 for proposal. If we consider each feature only in isolation then we will end up with a > fractured mess like C++. > > > I think this would really increase the availability of error handling in >> areas where it is impractical right now… >> > > I think the practical argument could be made stronger by use cases not > encumbered by other difficulties as outlined above. Is there a currently > throwing function you've encountered that would be greatly improved by such > a feature? Besides that, though, my discomfort is (as mentioned above) that > the practical effect of such a feature is that it will actually altogether > invert the default responsibility for error handling, and I'm not sure that > it's entirely consistent with Swift's design as a consequence. In any case > it'd be a far greater change than you've made it out to be. Interesting > suggestion, definitely. > > Thanks, >> Jon >> _______________________________________________ >> swift-evolution mailing list >> [email protected] >> https://lists.swift.org/mailman/listinfo/swift-evolution >> > > >
_______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
