[swift-evolution] ternary operator ?: suggestion
Lukas Stabe
ahti333 at gmail.com
Sat Dec 5 22:54:52 CST 2015
I agree.
I’m sure there are use-cases where the different branches return different types, both conforming to some protocol. Since we’d need to support these cases, this approach is also pretty clean, because Any is just another protocol.
The warning emitted should be silenceable by explicitly declaring the variable being assigned to as Any.
Lukas
> On 06 Dec 2015, at 05:46, Jacob Bandes-Storch via swift-evolution <swift-evolution at swift.org> wrote:
>
> That approach seems fine to me; I don't think it seems like magic.
>
> "if x { returnsAnInt() } else { returnsAString() }" would have type Any, but would only emit a warning if you actually tried to use the value. Much like the current warning, "X inferred to have type Any, which may be unexpected".
>
> Jacob Bandes-Storch
>
> On Sat, Dec 5, 2015 at 7:53 PM, Kevin Ballard via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
> On Sat, Dec 5, 2015, at 04:32 PM, Lukas Stabe via swift-evolution wrote:
>>
>>> I don't think you can just get rid of the if statement in favor of an expression. You still want to be able to do this:
>>>
>>> if (condition) {
>>> funcWithSideEffectsThatReturnsInt()
>>> } else {
>>> funcWithSideEffectsThatReturnsString()
>>> }
>>>
>>> but that's not a valid expression (what is its type?).
>>
>> An if statement with two different types could just have the closes common ancestor or Any as type.
>
> That's a great way to cause confusion.
>
> Rust has this feature (all statements are expressions), and it requires if statements to have an else branch with the same type unless the type is `()`. It's solution to the issue of the branches returning unwanted values is that Rust uses semicolons, and the semicolon acts sort of like an operator that consumes any value and returns `()`, so if you terminate the last statement of the branch with a semicolon, the whole branch returns `()`, and if you leave it off, the branch returns a value. It's actually very elegant and straightforward.
>
> That said, proposing that Swift introduce this same rule for semicolons is probably not a good idea. We certainly could declare that an explicit semicolon has this behavior, so you'd see people writing code like
>
> if condition {
> funcWithSideEffectsThatReturnsInt();
> }
>
> but it would be confusing because semicolons are almost never used in Swift.
>
> An alternative that would work today is just relying on assignment returning Void, so you can write
>
> if condition {
> _ = funcWithSideEffectsThatReturnsInt()
> }
>
> but that looks kind of weird and would probably also be confusing. Better than the semicolon rule I think, but still not great.
>
> Another option is to check if the return value is actually used anywhere, and if it's not, then silently coerce it to Void. This way you can write
>
> if condition {
> funcWithSideEffectsThatReturnsInt()
> } else {
> funcWithSideEffectsThatReturnsString()
> }
>
> and it would be fine but writing
>
> let foo = if condition {
> funcWithSideEffectsThatReturnsInt()
> } else {
> funcWithSideEffectsThatReturnsString()
> }
>
> would fail with a type error.
>
> I suspect that this is the right approach, but it does involve a bit of magic.
>
> -Kevin
>
>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution <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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151206/f838508a/attachment.html>
More information about the swift-evolution
mailing list