<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto">how does c code (and Python code, etc, other than ObjC) call Swift functions, methods, etc? <br><br><div id="AppleMailSignature"><div>C. Keith Ray</div><div><a href="https://leanpub.com/wepntk" style="background-color: rgba(255, 255, 255, 0); font-size: 13pt;">https://leanpub.com/wepntk</a><span style="background-color: rgba(255, 255, 255, 0); font-size: 13pt;"> <- buy my book?</span></div><div><a href="http://agilesolutionspace.blogspot.com/">http://agilesolutionspace.blogspot.com/</a></div><div>twitter: @ckeithray</div><div><a href="http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf">http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf</a></div></div><div><br>On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br><br></div><blockquote type="cite"><div><span></span><br><span></span><br><blockquote type="cite"><span>On Nov 10, 2017, at 4:20 PM, Joe Groff <<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>> wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>On Nov 10, 2017, at 4:12 PM, Charles Srstka <<a href="mailto:cocoadev@charlessoft.com">cocoadev@charlessoft.com</a>> wrote:</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>On Nov 10, 2017, at 5:51 PM, Joe Groff <<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>> wrote:</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>On Nov 10, 2017, at 3:45 PM, Charles Srstka <<a href="mailto:cocoadev@charlessoft.com">cocoadev@charlessoft.com</a>> wrote:</span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>On Nov 10, 2017, at 5:36 PM, Joe Groff <<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>> wrote:</span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>How `MyObject.foo(_:bar:)` gets implemented is its own business, as far as the compiler is concerned. The compile-time name resolution for the method isn't impacted.</span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>-Joe</span><br></blockquote></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>The compile-time name resolution for the method doesn’t happen *at all.*</span><br></blockquote></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><span>You declared the method in your @interface, and the compiler saw that and brought it in as what Swift considers to be a regular method, and your call on the Swift side was resolved to it by Swift's usual lookup rules. To do what Chris is suggesting requires changing the way calls get resolved in the compiler before the call is even formed.</span><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>The only thing that makes this the “usual lookup rules” is that the Objective-C bridge has already been implemented.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>As I mentioned in my original reply, I personally think the "importer" approach would be superior, and that in a perfect world we'd have type providers to make writing something like the ObjC importer but for a different language or other dynamic data source something that doesn't require invasive compiler hackery. The importer puts all of this:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><blockquote type="cite"><span>- It’s changing the compile-time name resolution! The Swift name is foo(bar:), but it’s changing that to fooWithBar:!</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>- It’s changing the signature! The argument took a String, but now it’s passing an NSString!</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>- It’s not resolving the method at compile-time! It’s passing the modified method name and the arg list to some objc_msgSend() function, which resolves it dynamically in a way that user code can intercept and interpret at runtime!</span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span></span><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><span>I’m just not seeing the conceptual difference here.</span><br></blockquote></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>below the fold as far as the rest of the language is concerned. You could just as well written what the importer synths up in Swift directly:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>func foo(bar: String) {</span><br></blockquote><blockquote type="cite"><span> unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, NSString) -> ().self)(self, "fooWithBar:", NSString(bar))</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>and the rest of the language would be none the wiser.</span><br></blockquote><span></span><br><span>Though, since you bring up objc_msgSend, the way it works in ObjC might be a better fit for Swift's name lookup model, since their keyword argument models are similar. If Swift had a 'method of last resort' like ObjC's, say as a strawman you could overload the '.' operator, then you could use it to provide an implementation for a method given a compound name in a similar way. So if you had:</span><br><span></span><br><span>struct Dynamic { func .(methodName: String) -> (Any...) -> Int }</span><br><span></span><br><span>let x = Dynamic()</span><br><span>x.foo(x: 0, y: 1)</span><br><span></span><br><span>Then, when we do name lookup into x for foo(x:y:) and that fails, we'd fall back to turning this into x.`func .`("foo(x:y:)")(0, 1). It would take a bit more work to turn this into something like a Python call, but would fit Swift's language model better.</span><br><span></span><br><span>-Joe</span><br><span></span><br><span></span><br><span>_______________________________________________</span><br><span>swift-evolution mailing list</span><br><span><a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a></span><br><span><a href="https://lists.swift.org/mailman/listinfo/swift-evolution">https://lists.swift.org/mailman/listinfo/swift-evolution</a></span><br></div></blockquote></body></html>