[swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority
Xiaodi Wu
xiaodi.wu at gmail.com
Sat Sep 3 11:09:56 CDT 2016
I agree with Thorsten. I would expand on that by arguing that (1) the
original motivation identified is inapplicable to Swift; (2) the solution
doesn't solve the problem, and creates more problems; (3) the revised
solutions are not compatible with the direction of Swift.
Argument (1):
The only real-world example provided is one in C, not Swift. The key
difference is that C will implicitly cast from many types to bool, but
Swift does not. Therefore, that example is not a demonstration of a
weakness in Swift.
The same issue could only arise in Swift when you have an expression `a
[operator] b ? c : d` where a, b, c, and d are all Bool--and the operator
is a Boolean operator. I see no evidence that confusion is encountered in
everyday practice because the user would have to (a) not know the relative
precedence of Boolean/ternary operators; (b) incorrectly believe that they
do know the relative precedence of Boolean/ternary operators; and (c)
choose not to use parentheses.
I don't think it's likely you'll encounter a real-life example of this, nor
do I think that we should make source-breaking changes to the language to
prevent that possibility, because the category of errors that are possible
if a user doesn't understand something *and* affirmatively believes
something that's not true *and* chooses not to use a sane coding style is
infinite and impossible to defend against.
Argument (2):
The original proposal is, in essence, to change `?:` to `()?:`, but that
does not solve the issue outlined above *and* silently breaks existing code
that uses the current operator correctly. For instance, `a && (b || c) ? d
: e` would have a different meaning. Unless I'm mistaken, the only way to
remove all ambiguity is to change the syntax from `?:` to `(()?:)`, which I
think you'll agree is absurd.
Argument (3):
Changing the syntax to use words is a commonly rejected proposal, and I
don't see any new information on how it would solve this particular issue.
Although custom operators can't use words, built-in ones do (e.g., `as`)
and still have relative precedence that is higher than some other
operators. Therefore, spelling out "then" absolutely does not "carry the
meaning of low priority." In fact, by moving away from C, you are now going
to raise questions for the large proportion of uses who *do* know the
precedence of ?: as to what the corresponding precedence might be in Swift.
Finally, the argument to remove precedence here has the same defect as
previous proposals on changing or removing operator precedence. This
operator, like others, does have a known precedence. It is clearly written
out in a table, and in the case of `?:` it is essentially unchanged from
other languages in the C family. If you use the operator assuming it has
precedence that it does not have, then you are in for a bad time. However,
*every* operator with a precedence relationship has this "caveat". That is,
after all, what it means to have precedence above some operator and below
some other operator. If you believe that the issues described above are
sufficient to remove precedence for `?:`, you must also believe that it is
sufficient to remove relative precedence between any two operators except
the basic arithmetic operators `+`, `-`, `*`, `/`. But this is clearly not
the direction of Swift, since we have recently changed custom operator
syntax specifically to enable a better way to define new operators *with
custom precedence*.
In short, any change in Swift should be justified by a real-world use case.
A source-breaking change, such as modifying the syntax or precedence of an
existing operator, should be justified by an overwhelming compelling
real-world use case. I see only theoretical ones presented here, and I see
no solution that actually addresses the alleged issue in a way that fits
with the direction of Swift.
On Sat, Sep 3, 2016 at 7:29 AM Anton Zhilin via swift-evolution <
swift-evolution at swift.org> wrote:
> With the replacement, I would prefer just "then-else", which would still
> clearly carry the meaning of low priority. But yes, this option was
> explicitly rejected. Unfortunately.
>
> I also agree that changing the priority is not a solution. But how about
> removing priority?
>
> The following expression:
> `s << (x == 10) ? "10" : "not 10"`
> Is currently parsed as
> `(s << (x == 10)) ? "10" : "not 10"`
>
> With such a change, the compiler would make you add outer parentheses and
> find a bug, by the way:
> `s << ((x == 10) ? "10" : "not 10")`
>
> Should this apply to assignment operators?
> `s += (x == 10) ? "10" : "not 10" // error?`
>
> I think such caveats of `?:` are worth creating a proposal, at least.
>
> 2016-09-03 14:21 GMT+03:00 Thorsten Seitz via swift-evolution <
> swift-evolution at swift.org>:
>
>> The problem you describe is not the priority of the ternary operator but
>> that developers just assume a priority without checking (or learning)
>> whether their assumption is correct. Changing the priority won't solve that
>> problem, it would only shift the problem over to those developers assuming
>> the other priority. Worse, it would create this problem for those
>> developers knowing the correct priority, because they now have to relearn
>> the new priority with the added difficulty of the priority being different
>> from C.
>>
>> I'm not sure whether the problem really is one (other operators have
>> priorities too, which have to be learned), but assuming for the moment that
>> it is, a solution would be to replace the ternary operator with an
>> if-expression: *if* condition *then* expr1 *else* expr2
>> This would enclose the condition between two keywords and thereby be free
>> of misunderstandings.
>> Replacing the ternary operator is on the commonly asked changes list,
>> though, and therefore requires new arguments/insights why a replacement
>> would make sense. I think the possibly confusing priority has been
>> discussed already in the past and therefore wouldn't count as new insight,
>> though I'm not quite sure.
>>
>> -Thorsten
>>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160903/26608f83/attachment-0001.html>
More information about the swift-evolution
mailing list