Ternary Conditional Operator: Why do I need to use parentheses?

I wrote the following code in Swift Playgrounds:

var teen: String
myAge > 12 && myAge < 19 ? teen = "You're a Teen" : teen = "You're not a teen"

Upon running my code, I got an error message stating "result of conditional operator '?:' is never mutable.

I tried searching online for a solution and found someone with a similar issue who said he resolved this by placing each result in parentheses, so I did the same and it worked.

var teen: String
myAge > 12 && myAge < 19 ? (teen = "You're a Teen") : (teen = "You're not a teen")

Now when I clicked "run code" it worked just fine. However, I'd like to know WHY this worked. Why do I have to place each result of the condition in parentheses? Please help. Thank you.

It's because of the way the operator precendese rules work out with what you've written. I'll simplify this by replacing myAge > 12 && myAge < 19 with just b. Your code is parsed like so:

(b ? teen = "You're a Teen" : teen) = "You're not a teen"

Which clearly doesn't make sense.

By adding parenthesis, you've forced a particular parsing that actually makes the code valid.

However, there's an even simply, clear way to do this:

  1. There's no need for teen to be mutable
  2. There's no need for teen to be declared and assigned separately
  3. When you're using a conditional operator, it's often nice to group up a complex predicate in parenthesis, but that's a matter of personal style.

Here's how you might improve this:

let teen = (myAge > 12 && myAge < 19) ? "You're a Teen" : "You're not a teen"

I would go further and improve the naming:

let isTeen = (13...19).contains(myAge)
let teenStatusMessage = isTeen ? "You're a Teen" : "You're not a teen"
4 Likes

Oh and by the way, you have a bug in your original snippet :smiley:

myAge < 19 should read myAge <= 19, because nineteen year-olds are teens, too.

1 Like

Thank you, I understand this now (though I don't know why it would be parsed so strangely). :frowning: And you're right, 19-year olds ARE teens too! :slight_smile:

I can most easily explain it by analogy. Imagine you're writing a math expression like:

1 + 2 * 3

and was wondering why the result was 7 instead of 9. Of course, that's because it evaluates as 1 + (2 * 3), whereas you intended (1 + 2) * 3. Then you might ask: "Why does it parse so strangely?". Precedence are man-made, and one could imagine an alternative convention on mathematical notation where that + takes precedence over *. It would work the way you wanted it to. But one can also imagine another post saying: "Why does it evaluate to 9, I wanted 7!"

Operator precedence rules are kind of like which side of the road a country drives on. It doesn't really matter one way or another, but there needs to be a consistent standard or else chaos ensues.

2 Likes

Okay, got it, thank you for your help! :slight_smile: