<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi Chris,<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Nov 10, 2017, at 9:37 AM, Chris Lattner 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=""><div class="">Hello all,</div><div class=""><br class=""></div><div class="">I have a couple of proposals cooking in a quest to make Swift interoperate with dynamically typed languages like Python better. Instead of baking in hard coded support for one language or the other, I’m preferring to add a few small but general purpose capabilities to Swift. This is the first, which allows a Swift type to become “callable”.</div></div></div></blockquote><div><br class=""></div><div>I’m generally in favor of adding new features if they simplify the language model or subsume existing special cases, either moving them into the standard library or simplifying their implementation. However this proposal looks like a strictly additive feature, which introduces yet another kind of callable thing. We already have:</div><div><br class=""></div><div>- Statically dispatched functions</div><div>- VTable-dispatched class methods</div><div>- Witness table dispatched protocol methods</div><div>- ObjC methods</div><div>- Dynamic method dispatch on AnyObject</div><div>- Enum case constructors</div><div>- Curried functions and various thunks, etc</div><div><br class=""></div><div>I don’t see the new dynamic callable you are proposing replacing or generalizing any of the above, it will simply be a whole new code path.</div><div><br class=""></div><div>This all comes at a great cost. If you look at the implementation of calls in lib/SILGen/SILGenApply.cpp you will see there is a great deal of complexity there to deal with all the different special cases. The type checker also has a lot of complexity related to method calls and member accesses.</div><div><br class=""></div><div>I would be against adding yet another new type of call to the language at this point. Even if the implementation is relatively small it is yet another special case we have to maintain forever.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><span style="color: rgb(36, 41, 46); font-family: -apple-system, system-ui, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; font-size: 16px; orphans: 2; widows: 2;" class="">Swift is well known for being exceptional at interworking with existing C and Objective-C APIs, but its support for calling APIs written in scripting langauges like Python, Perl, and Ruby is quite lacking. These languages provide an extremely dynamic programming model where almost everything is discovered at runtime.</span></div></div></blockquote><div><br class=""></div><div>Most other statically compiled languages don’t attempt to solve this problem of interoperating with Python and Ruby either. I’m not sure this is a feature users expect or one that should be prioritized, given all the other work that remains in the implementation that will actually improve the day to day experience of developers.</div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">We propose introducing this protocol to the standard library:</p><div class="highlight highlight-source-swift" style="box-sizing: border-box; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; font-variant-ligatures: normal; orphans: 2; widows: 2;"><pre style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; margin-top: 0px; margin-bottom: 0px; word-wrap: normal; padding: 16px; overflow: auto; line-height: 1.45; background-color: rgb(246, 248, 250); border-radius: 3px; word-break: normal;" class=""><span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">protocol</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">DynamicCallable</span> {
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">associatedtype</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">DynamicCallableArgument</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">associatedtype</span> <span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">DynamicCallableResult</span>
<span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">func</span> <span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">dynamicCall</span>(<span class="pl-smi" style="box-sizing: border-box;"><span class="pl-en" style="box-sizing: border-box; color: rgb(111, 66, 193);">arguments</span></span>: [(<span class="pl-c1" style="box-sizing: border-box; color: rgb(0, 92, 197);">String</span>, DynamicCallableArgument)]) <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">throws</span> <span class="pl-k" style="box-sizing: border-box; color: rgb(215, 58, 73);">-></span> DynamicCallableResult
}</pre></div></div></div></blockquote><div>This is not really very general at all, because it assumes all arguments have the same type, along with all results. Why would arguments and results have different types if they’re type erased anyway? And why are string keyword names privileged in any way? What about varargs, inout parameters and other Swift-specific modifiers on calls?</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Before this proposal, the Swift language has two types that participate in call syntax: functions and metatypes (for initialization). Neither of those may conform to protocols at the moment, so this introduces no possible ambiguity into the language.</p><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div><div>However, it rules out a possible type checker optimization — currently we can assume that if a type variable is the subject of both a conformance constraint and an apply constraint, the constraint system is invalid. With your change we could not make this assumption anymore.</div></div><div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">It is worth noting that this does not introduce the ability to provide dynamicly callable <code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.05); border-radius: 3px;" class="">static</code>/<code style="box-sizing: border-box; font-family: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 13.6px; padding: 0.2em 0px; margin: 0px; background-color: rgba(27, 31, 35, 0.05); border-radius: 3px;" class="">class</code> members. We don't believe that this is important given the goal of supporting dynamic languages like Python, but if there is a usecase discovered in the future, it could be explored as future work. Such future work should keep in mind that call syntax on metatypes is already meaningful, and that ambiguity would have to be resolved somehow.</p><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div>This is the problem with this proposal — it solves a very narrow use case, but it introduces a piece of ABI that we have to maintain forever. When future generalizations are discovered, we will have to add yet another mechanism, complicating the language model further.<br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(234, 236, 239); color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-variant-ligatures: normal; orphans: 2; widows: 2;" class=""><a href="https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d#discussion" aria-hidden="true" class="anchor" id="user-content-discussion" style="box-sizing: border-box; color: rgb(3, 102, 214); text-decoration: none; float: left; padding-right: 4px; margin-left: -20px; line-height: 1;"><svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z"></path></svg></a></h2><h2 style="box-sizing: border-box; margin-top: 24px; margin-bottom: 16px; line-height: 1.25; padding-bottom: 0.3em; border-bottom-width: 1px; border-bottom-style: solid; border-bottom-color: rgb(234, 236, 239); color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">Effect on ABI stability</h2><p style="box-sizing: border-box; margin-top: 0px; margin-bottom: 16px; color: rgb(36, 41, 46); font-family: -apple-system, system-ui, 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; font-variant-ligatures: normal; orphans: 2; widows: 2;" class="">This is a strictly additive proposal with no ABI breaking changes.</p><div class=""><br class=""></div></div></div></blockquote><div><br class=""></div>However, it adds *new* ABI which we will have to maintain forever.</div><div><br class=""></div><div>A strong -1 from me here.</div><div><br class=""></div><div>Slava</div><br class=""></body></html>