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 letwrapping the
forloop 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().orEmptydoesn'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 with
while. Optional chaining doing nothing for
foris the odd one out here.
- There is also a mismatch between
for x in a!but
for x in a.orEmpty. Elsewhere,
!means trap on nil and
?means no-op on
nil, 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.