[swift-evolution] ternary operator ?: suggestion

Kevin Ballard kevin at sb.org
Sat Dec 5 22:55:52 CST 2015


If it's defined as type Any, then we'd also need a guaranteed compiler
optimization (preferably one that happens in debug builds too) that
omits the creation of the `Any` value if it's unused.

-Kevin

On Sat, Dec 5, 2015, at 08:46 PM, Jacob Bandes-Storch 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> 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
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20151205/2a41055a/attachment.html>


More information about the swift-evolution mailing list