[swift-evolution] use standard syntax instead of "do" and "repeat"
Goffredo Marocchi
panajev at gmail.com
Sun Jan 3 13:06:03 CST 2016
> On 3 Jan 2016, at 18:21, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
>
>
>> On Jan 3, 2016, at 12:12 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>>
>>
>>> On Jan 2, 2016, at 2:23 PM, Tyler Cloutier <cloutiertyler at aol.com> wrote:
>>>
>>> Please see comments inline.
>>>
>>>> On Dec 31, 2015, at 12:07 PM, Dave Abrahams via swift-evolution <swift-evolution at swift.org> wrote:
>>>>
>>>>
>>>>>> On Dec 27, 2015, at 10:25 PM, Brent Royal-Gordon via swift-evolution <swift-evolution at swift.org> wrote:
>>>>>>
>>>>>> So “try” instead of “do”. If there is no catch, then just use braces without a keyword for a block.
>>>>>>
>>>>>> And use do-while instead of repeat-while.
>>>>
>>>> +1
>>>>
>>>>>
>>>>> Do you also propose no longer marking calls to throwing functions with `try`?
>>>>
>>>> If try had both a single-statement/expression form as it does today, and a block form that makes it unnecessary to mark all the individual statements in the block, that would be an improvement.
>>>>
>>>>> Have you read the "Error-Handling Rationale" document in the Swift repository? If not, please do: <https://github.com/apple/swift/blob/master/docs/ErrorHandlingRationale.rst> If so, please explain why you disagree with it.
>>>>
>>>> There are large classes of programs where you can know you don’t care exactly where a failure happens, e.g. (most init functions, all pure functions, any function that doesn’t break invariants). In these cases marking every statement or expression that can throw is just noise. Try writing some serialization/deserialization code where the underlying stream can fail to see what I mean; you’ll have “try” everwhere, and it adds nothing to comprehensibility or maintainability. Personally I would like to be able to label the function itself and not have to introuce a scope, but IMO being able to create “try blocks” would be a welcome addition and would even match the common case in blocks with catch clauses, where being aware of the exact line where the error was generated is typically not useful.
>>>
>>> I had proposed something very similar to this around six months ago on the swift-users list, but I think John McCall, had some (quite valid) concerns with this.
>>>
>>> Unfortunately I can't access those emails, but I think his concern was that the purpose of try was to mark explicitly which statements throw and this would defeat the purpose of that. People might just wrap large blocks in try.
>>
>> As much as I am loath to disagree with John on this, there’s an incorrect implicit assumption in that rationale, that forcing people to mark all throw points trains them to get error-handling correct. What it does instead is to train them to think of all code uniformly instead of recognizing the places where a throw needs special attention (places where there are broken invariants). Eventually, as with warnings that have a high false-positive rate, when you see “try” in many places where it doesn’t help, you learn to ignore it altogether.
>
> I agree that requiring this is not likely to result in improved error handling and thus is not a strong argument in favor of it.
>
> IMO the purpose of requiring “try” to be stated explicitly is that it arguably makes code more readable. It is immediately clear which functions can throw and which cannot. You don’t need to look up the signature of every function called to determine this. My experience thus far has been that I have really appreciated the requirement that throwing expressions be explicitly marked.
>
In a way the current 'do' (which I would rename to attempt ;)... regardless of requiring try for every throwing statement is used or not I am not a fan of taking a commonly used keyword and changing its meaning unless there is a clear strong benefit to it) already identifies blocks of throwing code and having try marking each expression does not do much about trying to catch errors thrown by too many statements together. My litmus test for this is that we could remove the try keyword from those error handling blocks and it would not by itself worsen our code much, but I may very well be utterly wrong here.
> I think positions on both sides of this are reasonable.
>
>>
>>>
>>> Another idea is to treat the block as an unnamed, no argument, no return value, function that could throw. This solves the problem in a very general way, and would retain the marking of all throwing functions with try,
>>
>> That marking, in itself, is the root problem. Our syntax is the way it is primarily because "marking everywhere" was adopted as an explicit goal.
>>
>>> but has the perhaps unfortunate syntax of allowing things like:
>>>
>>> try {
>>> try myFunction()
>>> } catch {
>>>
>>> }
>>>
>>> Something like this could be shortened to a consistent theoretical inline try catch syntax like:
>>>
>>> try myFunction() catch {
>>>
>>> }
>>>
>>> Though, as John, pointed out at the time, this could still be added on with the current syntax. Obviously treating a try like an unnamed function would have different return semantics, so perhaps that's not the right abstraction. (Although I recall a thread going on that is considering allowing functions to retain return semantics of the outer scope)
>>>
>>> Tyler
>>>
>>>
>>>>
>>>> -Dave
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>> -Dave
>>
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
More information about the swift-evolution
mailing list