I referred to orEmpty
in the post. I think it is almost, but not quite, as good as the optional chaining solution, and would be my second choice.
It is clearly inferior though:
- A projection runs the risk of not being optimized away properly. A manual
if let
wrapping thefor
loop never runs this risk. I am guessing the actual code generated for the optional chaining solution is more like the latter than the former. - It composes poorly with optional chaining:
maybeRange?.reversed().orEmpty
doesn't compile for reasons that are hard for users to understand. - It is inconsistent. Optional chaining of methods is just a
flatMap
, why not solve that in the library too? We have optional chaining for function/method/subscript invocation, and for assigning through optionals. Optional chaining composes well withwhile
. Optional chaining doing nothing forfor
is the odd one out here. - There is also a mismatch between
for x in a!
butfor x in a.orEmpty
. Elsewhere,!
means trap on nil and?
means no-op onnil
, and it should here too.
I don't buy that orEmpty
is more discoverable. I don't think developers, faced with a compilation error because they are trying to for
an optional, are going to look at the methods available on Optional
for a solution. They are going to do what they know: unwrap it with an if let
, or coalesce it. The way to drive discovery of this feature, either way we solve it, like you say, is with a fixit.
I also don't feel that orEmpty
is clearer. I don't think anyone familiar with optional chaining and Swift in general won't guess what for x in d[k]?
means when they see it. orEmpty
doesn't even say what it does – we don't use the "or" idiom anywhere else in Swift.