I like your idea, I think you may need a protocol for each class though. It&#39;s possible for NSNumber to be used<span></span> as an NSValue, for example.<div><br><div>On Monday, 8 February 2016, Marco Masser via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>I know I’m late to the party and the review period has ended, but I’d like to add a suggestion towards a possible solution to a point that was discussed in this context.</div><br><div><blockquote type="cite"><div>On 2016-02-05, at 17:54, Michel Fortin via swift-evolution &lt;<a href="javascript:_e(%7B%7D,&#39;cvml&#39;,&#39;swift-evolution@swift.org&#39;);" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><div><div><br></div></div></blockquote><blockquote type="cite">[…]</blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite"><div><div>Eventually, classes such as NSCountedSet and NSIndexSet will have a proper struct wrapper that will claim the non-prefixed name. But there is no urgency in making those wrappers ready for Swift 3 because the class remains available.<br><br>Anyway, that&#39;s what I&#39;d propose. There aren&#39;t that many classes in Foundation; cases like this can be sorted out manually.<br></div></div></blockquote></div><br><div>I wholeheartedly agree with this: I’d take a close look at every <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span> in Foundation that should really be a value type in Swift (all collection types, NSURL, …) and keep the NS prefix for them. Then, at some later point (or with Swift 3 if there’s enough time), add <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span> wrappers without the NS prefix for these <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es.</div><div><br></div><div>I want to outline a possible solution to this that allows all developers to annotate their <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es and have them automatically imported as <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>s in Swift.</div><div>I think that could actually work with just a couple of annotations in the Objective-C headers and the correct interpretation of them in the Clang Importer. I’d propose something like this:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">@interface</span><span> </span><span style="color:#78492a">NS_SWIFT_STRUCT</span><span>(CountedSet) NSCountedSet&lt;ObjectType&gt; : </span><span style="color:#703daa">NSMutableSet</span><span>&lt;ObjectType&gt; {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br><span></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><div style="margin:0px;line-height:normal;color:rgb(187,44,162)"><div style="margin:0px;line-height:normal;color:rgb(0,132,0)"><span style="color:#bb2ca2">@property</span><span style="color:#000000"> </span><span style="color:#bb2ca2">BOOL</span><span style="color:#000000"> foo; </span><span>// Just for demonstration purposes.</span></div></div></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>- (NSUInteger)countForObject:(ObjectType)object;</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>- (</span><span style="color:#bb2ca2">void</span><span>)addObject:(ObjectType)object </span><span style="color:#78492a">NS_SWIFT_MUTATING</span><span>;</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>- (</span><span style="color:#bb2ca2">void</span><span>)removeObject:(ObjectType)object </span><span style="color:#78492a">NS_SWIFT_MUTATING</span><span>;</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><span></span><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px">…</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(187,44,162)"><span>@end</span></div></div><div><br></div><div>In Swift, that would come through as the following (in addition to an NSCountedSet class):</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">struct</span><span> CountedSet&lt;ObjectType&gt; {</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">private let</span><span> _internal: </span><span style="color:#703daa">NSCountedSet</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#703daa">    </span><span style="color:rgb(187,44,162)">var</span><span> foo: </span><span style="color:rgb(112,61,170)">Bool</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">func</span><span> countForObject(object: </span><span style="color:#703daa">ObjectType</span><span>) -&gt; </span><span style="color:#703daa">Int</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">mutating</span><span> </span><span style="color:#bb2ca2">func</span><span> addObject(object: </span><span style="color:#703daa">ObjectType</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>    </span><span style="color:#bb2ca2">mutating</span><span> </span><span style="color:#bb2ca2">func</span><span> removeObject(object: </span><span style="color:#703daa">ObjectType</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">    …</div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span><br></span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>}</span></div></div><div><br></div><div>That is: <span style="color:rgb(120,73,42);font-family:Menlo;font-size:11px">NS_SWIFT_STRUCT(_name)</span> specifies that a <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span> with the given <span style="color:rgb(120,73,42);font-family:Menlo;font-size:11px">_name</span> should be created that has a <span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">private let</span> member of the annotated <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>. All methods of the <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span> and all its superclasses are automatically imported as methods of the <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>. Methods annotated as  <span style="color:rgb(120,73,42);font-family:Menlo;font-size:11px">NS_SWIFT_MUTATING</span> are imported as <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">mutating</span> methods in the Swift <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>. For <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">@property</span> declarations, the importer could automatically infer that the setter is <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">mutating</span> and the getter <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">nonmutating</span>, although an <span style="color:rgb(120,73,42);font-family:Menlo;font-size:11px">NS_SWIFT_NONMUTATING</span> might be useful to annotate that a property setter should be imported as <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">nonmutating</span>, if applicable.</div><div><br></div><div><div>After a quick glance over all of Foundation’s <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es, I think the following could be eligible (probably not a complete list):</div><div><div>NSAttributedString</div><div>NSCharacterSet</div><div>NSCountedSet</div><div>NSData</div><div>NSDate</div><div>NSDecimalNumber</div><div>NSError</div><div>NSHashTable</div><div>NSIndexPath</div><div>NSIndexSet</div><div>NSNotification</div><div>NSNumber/NSValue</div><div>NSOrderedSet</div><div>NSURL</div><div>NSUUID</div></div><div><div><br></div></div><div>Whereas for some classes it would be better to use the mutable variants as the internal storage for the Swift <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>:</div><div><div>NSMutableAttributedString (as AttributedString)</div><div>NSMutableCharacterSet (as CharacterSet)</div><div>NSMutableData (as Data)</div><div>NSMutableIndexSet (as IndexSet)</div><div>NSMutableOrderedSet (as OrderedSet)</div></div></div><div><br></div><div><br></div><div>The Clang Importer could also handle the case where passing a Swift URL to an Objective-C method that expects an NSURL could work automatically. Maybe an Objective-C methods like this:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span>- (</span><span style="color:#bb2ca2">void</span><span>)methodImplementedInObjectiveC:(<span style="color:rgb(112,61,170)">NSURL</span> *)arg;</span></div></div><div><br></div><div>… could be imported into Swift like this:</div><div><br></div><div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">func</span><span> methodImplementedInObjectiveC(arg: </span><span style="color:#703daa">NSURL</span><span>)</span></div><div style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:#bb2ca2">func</span><span> methodImplementedInObjectiveC(</span><span style="color:#bb2ca2">inout</span><span> arg: </span><span style="color:#703daa">URL</span><span>) </span><span style="color:rgb(0,132,0)">// Objective-C code operates on arg._internal</span></div></div><div><br></div><div><br></div><div>If the <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span> wraps a class that has a mutable counterpart (this would have to be annotated somehow), the import could do a better job for the nonmutating variant. This would require a variant of the <span style="color:rgb(120,73,42);font-family:Menlo;font-size:11px">NS_SWIFT_STRUCT(_name) </span>macro that takes another parameter that points to the nonmutating variant. Then, the following methods:</div><div><br></div><div><span style="font-family:Menlo;font-size:11px">- (</span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">void</span><span style="font-family:Menlo;font-size:11px">)nonmutatingMethodImplementedInObjectiveC:(<span style="color:rgb(112,61,170)">NSData</span> *)arg;</span></div><div><span style="font-family:Menlo;font-size:11px"><span>- (</span><span style="color:rgb(187,44,162)">void</span><span>)mutatingMethodImplementedInObjectiveC:(<span style="color:rgb(112,61,170)">NSMutableData</span> *)arg;</span></span></div><div><span style="font-family:Menlo;font-size:11px"><br></span></div><div><div><div>… could be imported into Swift like this:</div></div></div><div><br></div><div><span style="font-family:Menlo;font-size:11px"><div style="margin:0px;line-height:normal"><span style="color:rgb(187,44,162)">func</span><span> nonmutatingMethodImplementedInObjectiveC(arg: </span><span style="color:rgb(112,61,170)">Data</span><span>)</span></div><div style="margin:0px;line-height:normal"><span style="color:rgb(187,44,162)">func</span><span> mutatingMethodImplementedInObjectiveC(</span><span style="color:rgb(187,44,162)">inout</span><span> arg: </span><span style="color:rgb(112,61,170)">Data</span><span>) </span><span style="color:rgb(0,132,0)">// Objective-C code operates on arg._internal</span></div></span></div><div><span style="font-family:Menlo;font-size:11px"><br></span></div><div><br></div><div>Annotations like this would be very useful because it would also allow developers to annotate their own <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es like this. It’s not uncommon to have model objects that could sensibly be <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>s in Swift, but can’t because existing Objective-C code requires them to be <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es.</div><div><br></div><div><div>When Objective-C <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es become Swift <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>s, they obviously lose their inheritance chain and therefore polymorphic properties. I haven’t done a survey, but my gut feeling tells me that the <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es for which all this is relevant – i.e. those that should have value semantics – aren’t usually subclassed and this point could therefore be moot. I may be wrong about that, though.</div></div><div><br></div><div><br></div><div>There are probably a lot of additional things to specify here, but maybe this could be a way forward. It would enable using things like NSCountedSet and NSURL in Swift just like it does now, with the possibility to add value types for them later without breaking existing code. In time, the <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">class</span>es could also be deprecated in favor of the <span style="color:rgb(187,44,162);font-family:Menlo;font-size:11px">struct</span>, if that is desired.</div><div><br></div><div><br></div><div>Cheers,</div><div><br></div><div>Marco</div></div></blockquote></div></div>