<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class="">
<br class=""><div><blockquote type="cite" class=""><div class="">On Mar 23, 2016, at 3:45 PM, Joseph Pamer <<a href="mailto:jpamer@apple.com" class="">jpamer@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 23, 2016, at 11:29 AM, Jordan Rose <<a href="mailto:jordan_rose@apple.com" class="">jordan_rose@apple.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">The most common use case I've seen for this has been drilling into a heterogeneous collection without specifying intermediate types, i.e. `pluginProperties["actions"][0]["name"]`. Some possible variations on this proposal could continue to allow that:</div><div class=""><br class=""></div><div class="">- Remove all lookup except the subscripts `(AnyObject) -> AnyObject?` and `(Int) -> AnyObject`.</div><div class="">- Instead of removing AnyObject lookup completely (the proposal), change the IUO-wrapped results (the current behavior) to use Optional, requiring developers to explicitly deal with the possibility of failure.</div><div class="">- Both of the above.</div><div class=""><br class=""></div><div class="">I know Joe Pamer has been looking into seeing how this feature is used by introducing a warning for it in the type checker. Before making any changes here we'd want to know how it affects real-world projects.</div></div></div></blockquote><div class=""><br class=""></div><div class="">I should be pushing a branch that does both of the above “real soon now”. (This branch also includes my recent experiments in inhibiting implicit bridging conversions.) I’ll be curious to know what people think once they’ve had a chance to play with these changes.</div><div class=""><br class=""></div><div class="">Thanks!</div><div class="">- Joe</div><br class=""></div></div></div></blockquote><div><br class=""></div><div>Good to hear! Is this change going to make this work on linux/etc so that behavior is consistent on all platforms too?</div><div><div class=""><br class=""></div><div class="">If it turns out that it's not practical to remove this behavior outright, what if we move the behavior to a new type that has this expectation built in, perhaps `ObjcObject` or something similar? If the importer keeps every use of `id` from objective-c imported as AnyObject, then a developer could opt-in to this behavior by casting to ObjcObject explicitly:</div><div class=""><br class=""></div><div class="">for thing in things {</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>(thing as ObjcObject).bar()</div><div class="">}</div><div class=""><br class=""></div><div class="">If we can't get this behavior to work on all platforms, exposing it through a dedicated ObjcObject type like this would help identify whether code that uses it is able to be used cross platform or not.</div></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">Jordan</div><div class=""><br class=""></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Mar 22, 2016, at 18:59 , Kevin Lundberg via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">In "Using Swift with Cocoa and Objective-C", this behavior is described as part of how AnyObject works:<div class=""><br class=""><div class=""><div class=""><i class="">“You can also call any Objective-C method and access any property without casting to a more specific class type." … "However, because the specific type of an object typed as AnyObject is not known until runtime, it is possible to inadvertently write unsafe code. As in Objective-C, if you invoke a method or access a property that does not exist on an AnyObject typed object, it is a runtime error.”</i></div><div class=""><br class=""></div><div class="">I propose that we remove this behavior entirely to push swift further in the direction of type safety.</div><div class=""><br class=""></div><div class=""><b class="">Rationale:</b></div><div class="">Even if you don’t mean to write code that relies on this behavior, it's easy to accidentally do so when interfacing with various Cocoa APIs due to type inference. A developer may not even realize that their code is unsafe since their code will compile just fine when calling obj-c visible methods. Removing this behavior would alleviate any confusion that a developer may have while writing this, especially as it is not a highly advertised feature of AnyObject. Furthermore, anyone who reads swift code using this will know with more certainty what types the author expects to be using here since an explicit cast will be required.</div><div class=""><br class=""></div><div class=""><b class="">Considerations:</b></div><div class="">If this is done, the way I see AnyObject behaving is similar to Any, where you need to manually downcast in order to call methods on things. Code would change from this:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">class Foo: NSObject { func bar() {} }</div><div class=""><div class="">let things = NSOrderedSet(object: Foo())</div><div class=""><br class=""></div><div class="">for thing in things { // thing is AnyObject</div><div class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>thing.bar() // happens to work but not verified by compiler, may crash in the future</div><div class="">}</div></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">to something like this:</div><div class=""><br class=""></div><div class="">//...</div><div class=""><br class=""></div><div class="">for thing in things {</div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>if let foo = thing as? Foo { // needs an explicit cast</div><div class=""><span class="Apple-tab-span" style="white-space:pre">                </span>foo.bar() // type checked, verified by compiler, won’t crash due to missing method</div><div class=""> }</div><div class="">}</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">One ancillary benefit that I can see of doing this is that it could make AnyObject consistent across darwin and other platforms. As far as I can tell, this behavior only exists on platforms where swift integrates with the objective-c runtime, and doing this will help swift code be more portable as it doesn’t rely on this implicit behavior.</div><div class=""><br class=""></div><div class="">Any thoughts?</div><div class=""><br class=""></div><div class="">--<br class=""><div class="">
<div class="">Kevin Lundberg</div><div class=""><a href="mailto:kevin@klundberg.com" class="">kevin@klundberg.com</a></div><div class=""><br class=""></div><br class="Apple-interchange-newline">
</div>
<br class=""></div></div></div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></body></html>