? versus ifSome

Continuing the discussion from SE-0231 — Optional iteration:

Your ifSome is essentially a re-implementation of ??, phrased as a method on self instead of a binary free function.

Your example similarly shows a different way to use ??, one that avoids the specific bug in hand:

// edit: the fortold doom is not happening in this example ;)
for i in (maybeHugeRange ?? 0..<0).reversed()  { // doom occurs here
  print(i) // your app will jetsam without ever reaching here
  break
}

only you're expressing it with your method instead of the nil-coalescing operator. But it amounts to the same thing.

This is also not limited to optionals. There are similar unfortunate lazy-defeating examples in my radar queue that don't involve them, sadly.

2 Likes

I appreciate that and I confirmed as much in the thread (just after the two method examples I posted).

Surely the real issue at hand is the deviation that has been created as a result of the optional ? chaining syntactic affordance that precedes the optional unwrap ?? something which is not so easy to reproduce with the method alternative.

A number of inconsistencies have been highlighted in respect of the syntactic approach to this. I'd certainly be far more positive about this overall if we could somehow deal that. I'm certainly in no way pushing to remove either ? or ??

Picking up from @Ling_Wang's above question the ifSome method defaults to Range<Int> and in turn to ReverseCollection<Range<Int>>, where as ? optional chaining in your code failure example defaults to ReverseCollection<[Int]> -- implying optional chaining picks the wrong reverse method.

Is this bug logged?

This is not related to optional chaining. This is a fundamental aspect of overload resolution.

Here's an example without optional chaining:

maybeHugeRange.map { $0.reversed() } ?? []

and here's an example without any optionals:

stride(from: 0, to: Int.max, by: 1).lazy.filter { _ in true }.last

ta missed that, plus difficulty to preserve types without HKTs