[swift-evolution] ternary operator ?: suggestion

Jacob Bandes-Storch jtbandes at gmail.com
Sat Dec 5 22:46:18 CST 2015


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/57e17cdd/attachment.html>


More information about the swift-evolution mailing list