<div dir="ltr">Hm. Taking the NSOutlineViewDelegate example, ideally it would be generic and you would supply it a type, but that not being the case I would be hesitant to do the implicit type casting. What happens if you get it wrong in one place and not the other? Something like<div><br></div><div><div>    func outlineView(outlineView: NSOutlineView, viewForTableColumn tableColumn: NSTableColumn, item: String) -&gt; NSView? {</div><div>        ...</div><div>    }</div><div><br></div><div>    func outlineView(outlineView: NSOutlineView, shouldSelectItem item: NSURL) -&gt; Bool {</div><div>        ...</div><div>    }</div><div><br></div><div>I&#39;m not sure how NSOutlineView should function in that case. Does one of them silently fail? Cause a runtime exception? With AnyObject, imperfect as it is, you have the opportunity to do the casting yourself and handle errors gracefully. You could even wrap it in your own generic protocol that is just a proxy that does the type casting. Or extend the protocol and overload the methods with more strongly typed arguments.</div></div><div><br></div><div>I actually think making the programmer be explicit about types is an advantage of things like generic protocols. It helps avoid problems like the inconsistent types thing. Obviously, you can still get the types wrong, but that feels like a product of a bad API and not deficiency in the language.</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Dec 16, 2015 at 4:40 PM Terrence Katzenbaer &lt;<a href="mailto:tkatzenbaer@me.com">tkatzenbaer@me.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><div style="font-family:SFNSText,&#39;Helvetica Neue&#39;,Helvetica,sans-serif">Sorry, that last reply was impolitely succinct.</div><div style="font-family:SFNSText,&#39;Helvetica Neue&#39;,Helvetica,sans-serif"><br></div><div style="font-family:SFNSText,&#39;Helvetica Neue&#39;,Helvetica,sans-serif">In practice, doing that workaround is strange and difficult to remember (especially for beginners). Additionally, it requires that the user bind the protocol to a specific type to even be used. Adding generic protocols would also require the user to bind the protocol. </div><div style="font-family:SFNSText,&#39;Helvetica Neue&#39;,Helvetica,sans-serif"><br></div><div style="font-family:SFNSText,&#39;Helvetica Neue&#39;,Helvetica,sans-serif">Additionally, unless I&#39;m mistaken, Objective-C allows you to conform to protocols in the way I&#39;m proposing. Of course, it wouldn&#39;t be wise to take every feature Objective-C has and implement it into Swift.</div></div><div><br>On Dec 16, 2015, at 01:32 PM, Terrence Katzenbaer &lt;<a href="mailto:tkatzenbaer@me.com" target="_blank">tkatzenbaer@me.com</a>&gt; wrote:<br><br></div><div><blockquote type="cite"><div dir="auto"><div>The limitations are that the Cocoa and Cocoa Touch frameworks don&#39;t implement this behavior.<br></div><div><br>On Dec 16, 2015, at 1:25 PM, Ian Ynda-Hummel &lt;<a href="mailto:ianynda@gmail.com" target="_blank">ianynda@gmail.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">I actually think that generic protocols as they exist in Swift 2 are expressive enough to do what you want to do.<div><br></div><div>Let me check my understanding, though. You want a definition of a method of the same name with a signature whose arguments are at least as specific as those defined in the protocol to implicitly do the appropriate casting, correct? So to supply a Swift 2 example, your code would be equivalent to this:</div><div><br></div><div><div>    class Foo { }</div><div><br></div><div>    class Bar: Foo { }</div><div><br></div><div>    protocol FooDelegate {</div><div>        typealias FooType: Foo</div><div>        func didPerformSomeAction(object: FooType)</div><div>    }</div><div><br></div><div>    class FooController: FooDelegate {</div><div>        typealias FooType = Foo</div><div>        func didPerformSomeAction(object: Foo) {}</div><div>    }</div><div><br></div><div>    class ProposedFooController: FooDelegate {</div><div>        typealias FooType = Bar</div><div>        func didPerformSomeAction(object: Bar) {}</div><div>    }</div></div><div><br></div><div>What are the limitations there?</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Dec 16, 2015 at 4:08 PM Terrence Katzenbaer &lt;<a href="mailto:tkatzenbaer@me.com" target="_blank">tkatzenbaer@me.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div><blockquote type="cite"><div><div style="white-space:pre-wrap">This seems to be better addressed with a generic protocol.<br></div></div></blockquote></div></div><div><div>I did consider a generic protocols, and it would be good to have some discussion on this vs. my proposed solution.</div></div><div><div><br></div><div><blockquote type="cite"><div><div style="white-space:pre-wrap">While there are currently some limitations surrounding generics, and so I won&#39;t give specific examples, this has been stated as an area of focus for Swift 3.</div></div></blockquote></div></div><div><div><span>Isn&#39;t this mailing list&#39;s purpose to discuss and propose changes to Swift 3? It seems like you&#39;re dismissing this as a &quot;wontfix&quot; with hopes that improving generics would resolve this issue in its entirety.</span></div></div><div><div><br>On Dec 16, 2015, at 12:58 PM, ilya &lt;<a href="mailto:ilya.nikokoshev@gmail.com" target="_blank">ilya.nikokoshev@gmail.com</a>&gt; wrote:<br><br></div><div><blockquote type="cite"><div><div style="white-space:pre-wrap">&gt; It seems more expressive and more functionally correct to be able to implement a method strengthening AnyObject to my model type while still conforming to the protocol (since my model would pass &quot;is AnyObject&quot;).<br><br>This seems to be better addressed with a generic protocol. While there are currently some limitations surrounding generics, and so I won&#39;t give specific examples, this has been stated as an area of focus for Swift 3. <br><br>&gt; If my NSOutlineView contained objects of a single type, it makes little sense to be forced to implement a method solely for handling AnyObjects or being forced to typecast to my model type.<br><br>In this example NSOutlineView should be specialized to some type T then.</div><br><div class="gmail_quote"><div dir="ltr">On Wed, Dec 16, 2015 at 23:45 Terrence Katzenbaer via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>Maybe I shouldn&#39;t have mentioned anything about the runtime since that&#39;s more about the implementation instead of the general idea... Something more &quot;swifty&quot; could be a compile check on the newly strengthened arguments.<br></div><div><br></div><div>If I understand your example code, it&#39;s calling didPerformSomeAction(object: Bar) instead of the Foo version because of function overloading? It seems this functionally satisfies not having to typecast, but it doesn&#39;t solve the verbosity problem since you&#39;re still forced to implement the extraneous didPerformSomeAction(object: Foo).</div><div><br></div><div>Using the Cocoa framework as an example, NSOutlineViewDelegate has the method:<span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#5c2699;font-family:&#39;menlo&#39;,monospace"></span></div><div><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#aa3391;font-family:&#39;menlo&#39;,monospace">optional</span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9"> </span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#aa3391;font-family:&#39;menlo&#39;,monospace">func</span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9"> </span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;font-family:&#39;menlo&#39;,monospace">outlineView</span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9">(</span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;font-family:&#39;menlo&#39;,monospace">_</span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9"> </span><code style="background-color:transparent;border:0px;font-size:0.85em;margin:0px 0px 15px;outline:0px;padding:0px 0px 6px;vertical-align:baseline;font-family:&#39;menlo&#39;,monospace;word-wrap:break-word"><em style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#414141;line-height:1.5">outlineView</em></code><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9">: </span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#5c2699;font-family:&#39;menlo&#39;,monospace"><a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSOutlineView_Class/index.html#//apple_ref/swift/cl/c:objc(cs)NSOutlineView" style="background-color:transparent;border:0px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:inherit;text-decoration:none" target="_blank">NSOutlineView</a></span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9">,</span><br style="font-family:&#39;menlo&#39;,monospace;font-size:12px"><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9">         </span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;font-family:&#39;menlo&#39;,monospace">shouldSelectItem</span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9"> </span><code style="background-color:transparent;border:0px;font-size:0.85em;margin:0px 0px 15px;outline:0px;padding:0px 0px 6px;vertical-align:baseline;font-family:&#39;menlo&#39;,monospace;word-wrap:break-word"><em style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#414141;line-height:1.5">item</em></code><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9">: </span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#5c2699;font-family:&#39;menlo&#39;,monospace"><a href="https://developer.apple.com/library/mac/documentation/Swift/Reference/Swift_AnyObject_Protocol/index.html#//apple_ref/swift/intf/s:PSs9AnyObject" style="background-color:transparent;border:0px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:inherit;text-decoration:none" target="_blank">AnyObject</a></span><span style="font-family:&#39;menlo&#39;,monospace;font-size:12px;background-color:#f9f9f9">) -&gt; </span><span style="background-color:transparent;border:0px;font-size:12px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:#5c2699;font-family:&#39;menlo&#39;,monospace"><a href="https://developer.apple.com/library/mac/documentation/Swift/Reference/Swift_Bool_Structure/index.html#//apple_ref/swift/struct/s:Sb" style="background-color:transparent;border:0px;margin:0px;outline:0px;padding:0px;vertical-align:baseline;color:inherit;text-decoration:none" target="_blank">Bool</a></span></div><div><br></div><div>If my NSOutlineView contained objects of a single type, it makes little sense to be forced to implement a method solely for handling AnyObjects or being forced to typecast to my model type.</div><div><br></div><div>It seems more expressive and more functionally correct to be able to implement a method strengthening AnyObject to my model type while still conforming to the protocol (since my model would pass &quot;is AnyObject&quot;).</div></div><div><div><br>On Dec 16, 2015, at 12:35 PM, Ian Ynda-Hummel &lt;<a href="mailto:ianynda@gmail.com" target="_blank">ianynda@gmail.com</a>&gt; wrote:<br><br></div><div><blockquote type="cite"><div><div dir="ltr">Sorry, that should be<div><br></div><div><div>    extension FooDelegate where Self: BarController {<br></div><div><div>        func didPerformSomeAction(object: Bar) {}</div><div>    }</div></div></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Dec 16, 2015 at 3:32 PM Ian Ynda-Hummel &lt;<a href="mailto:ianynda@gmail.com" target="_blank">ianynda@gmail.com</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">-1<div><br></div><div>I think the basic problem is saying the runtime should fail. I feel like a large part of the power of Swift is letting the compiler and the programmer make strong assumptions about types specifically to prevent the runtime from dealing with it.</div><div><br></div><div>In fact, the type system can save us here! I wrote some code you can play with here: <a href="http://swiftstub.com/318278733" target="_blank">http://swiftstub.com/318278733</a></div><div><br></div><div>The basic idea is that if you do something like</div><div><br></div><div>    extension FooDelegate where Self: BarController {<br></div><div><div>        func didPerformSomeAction(object: Foo) {}</div><div>    }</div></div><div><br></div><div>calls to didPerformSomeAction with an argument of type Bar will call the right one for the type! There might be better ways to do that, but that is what immediately came to mind.</div></div><div dir="ltr"><div><br></div><div dir="ltr"><div><div class="gmail_quote"><div dir="ltr">On Wed, Dec 16, 2015 at 2:43 PM Terrence Katzenbaer via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 0.8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div>Because APIs are designed to be generic, protocols that must be conformed generally use types like Object or other base classes for a given framework. This introduces type casting verbosity when implementing the protocol for a specific use. I would like to see the ability to strengthen argument types in functions declared for protocol conformance.</div><div><br></div><div>An example:</div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;"><span style="color:#0433ff">class</span> Foo { }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;"><span style="color:#0433ff">class</span> Bar: <span style="color:#3495af">Foo</span> { }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;"><span style="color:#0433ff">protocol</span> FooDelegate {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">    <span style="color:#0433ff">func</span> didPerformSomeAction(object: <span style="color:#3495af">Foo</span>)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;"><span style="color:#0433ff">class</span> FooController: <span style="color:#3495af">FooDelegate</span> {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">    <span style="color:#0433ff">func</span> didPerformSomeAction(<span style="color:#0433ff">var</span> object: <span style="color:#3495af">Foo</span>) {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;color:#008f00"><span style="color:#000000">        </span>// I know that object must be a Bar instance</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">        object = object <span style="color:#0433ff">as</span>! <span style="color:#3495af">Bar</span></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;color:#008f00"><span style="color:#000000">        </span>// do something with object</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">    }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">}</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;min-height:13px"><br></p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;color:#008f00"><span style="color:#0433ff">class</span><span style="color:#000000"> ProposedFooController: </span><span style="color:#3495af">FooDelegate</span><span style="color:#000000"> { </span>// Type &#39;ProposedFooController&#39; does not conform to protocol &#39;FooDelegate&#39;</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">    <span style="color:#0433ff">func</span> didPerformSomeAction(object: <span style="color:#3495af">Bar</span>) {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;color:#008f00"><span style="color:#000000">        </span>// do something with Bar instance</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">    }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;">}</p></div><div><br></div><div>The glaring issue I see outright is how the runtime should fail when `didPerformSomeAction` in `ProposedFooController` is called with a non-Bar instance... But perhaps it /should/ fail outright because the programmer has explicitly stated that the type should be Bar.</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:&#39;menlo&#39;;color:#eee8e4"><br></p><br></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=t5fkNsX-2F7-2FAygTFNPNE08PALgkjkO6I8wpsdssDS0ugoflEETQHfxbRSSUNh46A-2BBnty0AXF7-2F6V5IQrrWPPBPAAl2lhLAQfBmDE5XvduAb6E464TtuafU3IXuGYZPz4mvZzryd8ZWjagjCwHhDshUoA4qyLHUW5EmcqV4f7vbArb-2FwoFZqUuYa9zXycao6i5RWqdYAQSDNHXQd4qkIKr7cbGbIUUbSKIQr58UPkaXc-3D" alt="" width="1" height="1" border="0" style="min-height:1px;width:1px;border-width:0;padding:0;margin:0"></div>_______________________________________________<br> swift-evolution mailing list<br> <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></blockquote></div></div></div></div></blockquote></div></div></blockquote></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1p9Jer2O6jVE9KWvo-2B9iUaEyN8slp4IizyiLwsfp54M-2FnzR5STGC9MU24XI53qPK0EKL3pukSBY3LCV0xXmD7OTBqOmyp7R3uBB4vJ2QF7gW8Snxc5GvovhKLuDg3IalLtDP9chFlGDa8rakeF-2Bk6RvpsfZQGSa8uYTIU-2FLi2OIyxTgjc88Kv64Vt9jIejvLr4ScKi2ufvu0NLNxHUire5kPGeigUFcKV5nIYoLrk9Q-3D" alt="" width="1" height="1" border="0" style="min-height:1px;width:1px;border-width:0;padding:0;margin:0"></div>_______________________________________________<br> swift-evolution mailing list<br> <a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br> <a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></blockquote></div></div></blockquote></div></div></blockquote></div></div></blockquote></div></blockquote></div></div></blockquote></div>