I’d like to re-iterate my support for the authors continuing to investigate this pitch in the face of the prevailing wind. It’s true my experience with Alamofire and Ben’s experience with and NetNewsWire contrasting options ImplicitSome
and ExistentialAny
that a blanket re-intrepretation of a bare protocol from meaning any
to some
without qualification may make the problem worse rather than better. I’ve tried to put forward a tempered, hybrid approach but I underestimated the number and vigour of the “the migration pain is the gain” constituency.
I’m not a luddite. I’d be prepared to acquiesce to a certain amount of disruption if I felt we were moving to a better Swift. I don’t find a Swift where a novice programmer is required to make a choice between two genuinely difficult to understand and teach concepts in order to use a protocol a step forward though. This isn’t a dilemma one encounters in Java for example. I feel in that situation the compiler would be able to make as informed a choice. It’s a strange situation, in the course of two years we’ve moved from many of us being blissfully unaware of essentials to finding the possibility the compiler would make the decision to to use one for us beyond the pale. This just goes to show the power of giving something a label. I'm not saying there aren't other more subtle, perfectly valid concerns.
Much of the “bad rap” existentials suffer from is based on considerations that don't bare close scrutiny or are no longer true. While it is true using them to pass a value to a function is not as efficient as the generic approach I doubt this ever made anyone’s program meaningfully slower as function call overhead in Swift is barely quantifiable. It’s also the case that while it was possible to paint yourself into a design corner putting a value into an existential, we can now “open” them and get the value back - another great innovation from the heady time at the end of 2021 when so many aspects of the usability of Swift generics were revisited and improved.
Let’s not bridle at the prospect someone is trying to introduce a elision. Swift has been eliding for years and the real debate should be the extent to which we can move the dial from eliding any
to some
with Swift 6. We are already at a Goldilocks point where if you feel the compiler has made the wrong choice or it's a critical distinction that must be visible you an add a annotation since Xcode 13.3.
I’ve been experimenting with the compiler in a naive way and I am almost able to get Alamofire to compile unmodified with a very conservative and comprehensible rule that not storage and only procedure arguments of a simple bare protocol type (no containers or closures) are elided to some. This feels like a sweet spot where disruption is minimised and the migration away from the less efficient passing of existentials to functions can move forward and we can save a coupe of registers.
This leaves a couple of thorny problems which it may not be possible to resolve if you try a broader corpus of software. Code breaks if an argument is elided to some
where it was intended to satisfy a legacy protocol or is the override of a function of a class that was compiled as any
. Given how difficult it would be to avoid these problems, perhaps this would be a acceptable level of source breaking being more the exception than the rule. What gives me pause though are the silent changes in binding priority changing a function’s signature can give rise to described above. Perhaps it might be possible to produce a diagnostic if the compiler is making a different decision than it would have done in the past.