Language steering group guidance
As various ideas related to this topic have percolated since at least 2016, the language steering group discussed if any guidance might help the discussion to coalesce.
Consensus among the steering group is that we wouldn't entertain something like a non-semantic Withable protocol to circumvent the restriction against extending Any. While it's true that arbitrary members can't be added to all types via an extension in the standard library, a restriction we're comfortable maintaining, there is precedent for simulating such a member via built-in "magic": besides self, we've added the keyPath subscript in SE-0161. A with featureâif adoptedâwould likely become a part of idiomatic Swift usage; so, if a convincing case is made that the best design for this feature would have it spelled as a member, it'd be justifiable to take a similar implementation approach. We'd prefer a fair consideration of the merits of a free function versus a member here (whether spelled with or some other name) not to be clouded by this implementation detail.
As a group, we're not yet sure that we'd all reject an operator spelling off the bat, but a very convincing argument would have to be made for why it's clearly superior to alternative designs. Our concerns are several: (1) Existing standard library operators are largely well-known from C-family languages (or, in the case of &-prefixed operators, are deliberately more esoteric "flavors" of well-known operators). From that vantage, it's hard to imagine that any operator for this feature would have the readability of a spelled-out word. Indeed, lately, the direction of the language has favored pronounceable words (repeat each T) over punctuation (...T). (2) Any succinct enough sigil could start to look like line noise with broad adoption. Part of a convincing argument would, in our view, include a robust selection of realistic code examples that demonstrate how well a proposed operator spelling would perform as compared to a free function or method. (3) The addition of a single operator can immediately invite consideration of filling out a whole family of related operators, and we don't think that would be desirable here.
Could this be a language featureâa with statement, in other words? The steering group ultimately considered the implications of using compiler "magic" beyond simulating extension Any to be undesirable. In particular, we think any feature proposed should take a bona fide closure: we'd like to avoid inventing language rules that are unique in Swift to create some DSL-like block here, such as rebinding self as some of Kotlin's scope functions do. We understand that at least a contingent of developers who've used such features in other languages find them to be confusing sharp edges.
Lastly, a variation of this feature that takes its argument inout has also been proposed. We'd avoid this sort of design so as not to expose idiomatic ways to "hide" mutations in a chain of operations. The situation is analogous to assignment operators, which do not return a value in Swift (unlike most C-family languages). Moreover, any inout version of the proposed feature would require the user already to have a mutable binding "on hand" that they could mutate directly, and we expect inout bindings to address use cases where one might want to repeatedly mutate some deeply nested member.
â Xiaodi Wu, on behalf of the language steering group