<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="">On Nov 11, 2017, at 4:15 PM, Andrew Bennett <<a href="mailto:cacoyi@gmail.com" class="">cacoyi@gmail.com</a>> wrote:<div><blockquote type="cite" class=""><div class=""><div dir="ltr" class="">HI, this proposal looks really interesting!</div></div></blockquote><div><br class=""></div>Thanks!</div><div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><b class=""><font size="4" class="">Clarity on the proposal's intent</font></b></div><div class=""><b class="">Nice cheap bridges, or lowering barriers to bridging?</b></div></div></blockquote><div><br class=""></div><div>The later: I’m not overly concerned about constant time performance: dynamic languages are often slow (though exceptions exist, e.g. Javascript). So if there is a beautiful approach that works great but is a bit slower, that is fine with me.</div><div><br class=""></div><div>My desire is to enable access to “any” API in Python directly from Swift with natural syntax. This doesn’t mean it has to match Python of course: Python ranges and Swift ranges are syntactically very different, and Swift-in-Python should use Swift syntax. That said, there are a LOT of expression level similarities between Swift and Python, so things that can be the same should be.</div><div><br class=""></div><div>This proposal isn’t the only way to achieve that, of course. I’m open to other suggestions.</div><div><br class=""></div><div><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">I can see this providing a nice quick interface to Python from Swift, but I'm not sure if the exposed interface will be very Swifty (you probably have a much better idea of what is Swifty ;) than I do though). It seems you want it to be possible for everything to be dynamically exposed</div></div></blockquote></div><div><br class=""></div><div>Right: Python APIs are not “Swifty”. They do not use optionals or generics, use lowercase snake names, etc. IMO, that’s perfectly fine. Unlike the Objective-C interop in Swift - which aims to make legacy ObjC APIs feel Swifty, it is perfectly acceptable (and far less impact on the compiler) to just import Python directly into Swift. This is actually much better for the target audience anyway.</div><div><br class=""></div><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">Is it common for the the argument labels in other languages to be open ended, or are labels typically finite? If the answer is finite, why not use a Swift method as the wrapper?</div></div></blockquote><div><br class=""></div><div>Python keyword arguments are open ended. They get passed to the Python API as a dictionary.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">Do you want duck typing, and would it be better to expose this via a protocol?</div></div></blockquote><div><br class=""></div><div>I’m not sure how that can work, can you elaborate?</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><div class="">It seems like in almost every case you could do something like this:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo;" class=""><span style="color:rgb(186,45,162)" class="">func</span> myMethod<X: <span style="text-decoration:underline;color:rgb(112,61,170)" class="">P</span><span style="color:rgb(112,61,170)" class="">ythonConvertible</span> & <span style="color:rgb(112,61,170)" class="">CanQuack</span>, Y: <span style="color:rgb(112,61,170)" class="">PythonConvertible</span>>(a: <span style="color:rgb(79,129,135)" class="">X</span>? = <span style="color:rgb(186,45,162)" class="">nil</span>, b: <span style="color:rgb(79,129,135)" class="">Y</span>) {</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo;" class=""> <span style="text-decoration:underline" class="">p</span>ythonBridge.call(<span style="color:rgb(209,47,27)" class="">"myMethod"</span>, arguments: [<span style="color:rgb(209,47,27)" class="">"a"</span>: <span style="color:rgb(79,129,135)" class="">X</span>, <span style="color:rgb(209,47,27)" class="">"b"</span>: <span style="color:rgb(79,129,135)" class="">Y</span>])</div><div style="margin: 0px; font-stretch: normal; line-height: normal; font-family: Menlo;" class="">}</div></div></div></div></blockquote><div><br class=""></div><div>The currency type is PyVal (name TBD of course), just like AnyObject for Objective-C. I’m not sure what the code above is getting at.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">It might be good to add some <b class="">use-cases</b> (a popular Python library perhaps) to the proposal where this type of bridge would be insufficient :).</div></div></blockquote><div><br class=""></div><div>There are lots of examples. In data science, NumPy and Pandas are two examples. The Python community is 1 or 2 orders of magnitude larger than Swift’s community and there is 25 years of code out there to interop with. The point of this is to make it all accessible.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">It seems like this proposal pushes the responsibility of Swifty-ness and type-safety to the caller.</div></div></blockquote><div><br class=""></div><div>Yes, welcome to dynamic languages :-)</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""> At some point you'll have to write a type-safe bridging layer, or write your entire program in non-Swifty code ("The most obvious way to write code should also behave in a safe manner"). Is the main goal to <b class="">lower the barrier to Python</b> and other dynamic languages? or is it to provide a cheap nice Swifty bridge? I have the above concerns about the latter.</div></div></blockquote><div><br class=""></div><div>It’s the later. Many Python APIs are already wrappers around C code, so if someone cares about investing a bunch of effort into making a great Swift API, it would generally make sense to wrap the C API in Swift, not wrap the Python API in Swift.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><b class=""><font size="4" class="">Alternative sugar</font></b></div><div class=""><br class=""></div><div class="">Ruby has Keyword Arguments for similar sugar:</div><div class=""><font face="monospace, monospace" class=""><b class=""><br class=""></b></font></div><div class=""><font face="monospace, monospace" class=""><b class="">def</b> foo(regular, hash={})</font><br class=""></div><div class=""><font face="monospace, monospace" class=""> <b class="">puts</b> "the hash: #{</font><span style="font-family:monospace,monospace" class="">hash}</span><span style="font-family:monospace,monospace" class="">"</span></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">I'm sure you're aware of it, but I'll explain for completeness, any trailing argument labels are stored and passed as a hash:</div><div class=""><br class=""></div><div class=""><pre class="gmail-prettyprint gmail-lang-rb gmail-prettyprinted" style="margin-top:0px;margin-bottom:1em;padding:5px;border:0px;font-family:Consolas,Menlo,Monaco,"Lucida Console","Liberation Mono","DejaVu Sans Mono","Bitstream Vera Sans Mono","Courier New",monospace,sans-serif;font-stretch:inherit;line-height:inherit;vertical-align:baseline;width:auto;max-height:600px;overflow:auto;color:rgb(57,51,24);word-wrap:normal"><span class="gmail-pln" style="font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(48,51,54)">foo</span><span class="gmail-pun" style="font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(48,51,54)">(</span><span class="gmail-pln" style="font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(48,51,54)">regular</span><span class="gmail-pun" style="font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(48,51,54)">,</span><span class="gmail-pln" style="font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(48,51,54)"> bar: "hello", bas: 123</span><span class="gmail-pun" style="font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit;margin:0px;padding:0px;border:0px;font-stretch:inherit;line-height:inherit;vertical-align:baseline;color:rgb(48,51,54)">) <b class=""># outputs 'the hash: [</b></span><b class=""><span style="color:rgb(48,51,54);font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit" class="">bar: "hello", bas: 123</span><span style="color:rgb(48,51,54);font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit" class="">]’</span></b></pre></div></div></blockquote><div>Python is similar, but allows them to be intermixed with positional arguments.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">Have you considered an alternative like this? For example:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170);" class=""><span style="color:rgb(186,45,162)" class="">func</span><span style="" class=""> myMethod(regular: </span>Int<span style="" class="">, store: </span><span style="color:rgb(186,45,162)" class="">@argcapture</span><span style="" class=""> [</span>String<span style="" class="">: </span>PythonConvertible<span style="" class="">]) -> </span>PythonConvertible</div></div><div class=""><br class=""></div><div class="">I'm sure you have good reasons, it might make the implementation bleed out into other parts of the codebase. It would be good to include it in the proposal <b class="">alternatives</b> section though. At the moment most of the "alternatives" in the proposal just seem to be extensions to the same solution :)</div></div></blockquote><div><br class=""></div><div>I’m not sure what you’re getting at here. The system I’ve sketched out does not incorporate Python declarations, everything is dynamic. It is extremely simple. This is a huge feature :-) I think it is entirely non-scalable to do something like the ObjC importer for every language that Swift wants to interop with.</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><b class=""><font size="4" class="">Clarity</font></b></div><div class=""><b class="">Perhaps just that things are more clear to me now</b></div><div class=""><br class=""></div><div class="">If my extrapolation is correct a user will implement a single type that will allow a subset of a good portion of another language to be exposed (object method and property bridging). I'm guessing that the dynamic member proposal you're planning will not work with methods, it will require a property, I think this helps explain some of the motivations. It might be nice to have a more complete example that includes dynamic members. I didn't find it clear from the proposal that it would only be necessary to implement this protocol once per language.</div></div></blockquote><br class=""></div><div>I’m sorry, I don’t understand what you mean.</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><br class=""></body></html>