Unexpected coalescing

Is it me, or it shouldn't behave like that?

I mean, it should have returned in both cases 100

This is just a product of the fact that ?? has higher precedence than == (and both have higher precedence than the ternary operator), so the first line is really equivalent to:

((paths.sorted().last.flatMap { ... } ?? paths.sorted().first?.row) == 0) ? 0 : nil

Perhaps a bit confusing, but when you're stringing long chains of operators together without parentheses to differentiate, you're necessarily going to have to reason about precedence. If the chain parsed the way you expected, there would probably be someone else that is just as confused about why their code is returning 100 instead of nil. :slightly_smiling_face:

ETA: The listing of operator precedences can be found here.

@Jumhyn Thank you for replying

A little bit more formatted

paths.sorted().last.flatMap { last -> Int? in
    (self?.isLastElement(atIndexPath: last) ?? false) ? last.row : nil
} ?? (paths.sorted().first?.row == 0 ? 0 : nil)

Aside from the operators precedence, I expect that the coalescing takes place if and only if the flatMap result applied to the optional returns nil, otherwise the flatMap result should be considered

Something is confusing me perhaps, I'll check the operator precedence nonetheless as suggested

The nil-coalescing operator will only use the right-hand side if the left-hand side evaluates to nil, yes.

This is where the operator precedence is important. In the example where you've added parentheses, "considered" means that the result of the flatMap is actually returned from the expression when non-nil. If we look at my version where I've re-parenthesized the expression according to the precedence rules, the result of the flatMap, instead of being returned when non-nil, is used as the left-hand side of the == operator.

Another way of looking at it is that in the unparenthesized version, the 'top-level' expression is the ternary expression, so the only possible output of that expression is 0 or nil—you'll never get the result of the flatMap at all, unless the flatMap happens to be 0 (or nil)!

Terms of Service

Privacy Policy

Cookie Policy