<div dir="ltr">Thanks for taking the time to respond. I think my confusion started from a misinterpretation that each method you&#39;re exposing from python would need a new implementation of the protocol. I&#39;ve worked out my mistake, and you helped clarified with:<div><span style="font-size:12.800000190734863px"><br></span></div><div><span style="font-size:12.800000190734863px">&gt; The system I’ve sketched out does not incorporate Python declarations, everything is dynamic</span><br></div><div><span style="font-size:12.800000190734863px"><br></span></div><div><span style="font-size:12.800000190734863px">You&#39;ve addressed the other things that didn&#39;t stem from that :)</span></div><div><span style="font-size:12.800000190734863px"><br></span></div><div><span style="font-size:12.800000190734863px">Thanks,</span></div><div><span style="font-size:12.800000190734863px">Andrew</span></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Nov 12, 2017 at 12:27 PM, Chris Lattner <span dir="ltr">&lt;<a href="mailto:sabre@nondot.org" target="_blank">sabre@nondot.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><span class="">On Nov 11, 2017, at 4:15 PM, Andrew Bennett &lt;<a href="mailto:cacoyi@gmail.com" target="_blank">cacoyi@gmail.com</a>&gt; wrote:</span><div><span class=""><blockquote type="cite"><div><div dir="ltr">HI, this proposal looks really interesting!</div></div></blockquote><div><br></div></span>Thanks!</div><div><span class=""><br><blockquote type="cite"><div dir="ltr"><div><b><font size="4">Clarity on the proposal&#39;s intent</font></b></div><div><b>Nice cheap bridges, or lowering barriers to bridging?</b></div></div></blockquote><div><br></div></span><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></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></div><div>This proposal isn’t the only way to achieve that, of course.  I’m open to other suggestions.</div><span class=""><div><br></div><div><blockquote type="cite"><div dir="ltr"><div>I can see this providing a nice quick interface to Python from Swift, but I&#39;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></div></span><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><span class=""><div><br></div><blockquote type="cite"><div dir="ltr"><div>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></div></span><div>Python keyword arguments are open ended.  They get passed to the Python API as a dictionary.</div><span class=""><br><blockquote type="cite"><div dir="ltr"><div>Do you want duck typing, and would it be better to expose this via a protocol?</div></div></blockquote><div><br></div></span><div>I’m not sure how that can work, can you elaborate?</div><span class=""><br><blockquote type="cite"><div dir="ltr"><div><div>It seems like in almost every case you could do something like this:</div><div><br></div><div><div style="margin:0px;font-stretch:normal;line-height:normal;font-family:Menlo"><span style="color:rgb(186,45,162)">func</span> myMethod&lt;X: <span style="text-decoration:underline;color:rgb(112,61,170)">P</span><span style="color:rgb(112,61,170)">ythonConvert<wbr>ible</span> &amp; <span style="color:rgb(112,61,170)">CanQuack</span>, Y: <span style="color:rgb(112,61,170)">PythonConvertible</span>&gt;(a: <span style="color:rgb(79,129,135)">X</span>? = <span style="color:rgb(186,45,162)">nil</span>, b: <span style="color:rgb(79,129,135)">Y</span>) {</div><div style="margin:0px;font-stretch:normal;line-height:normal;font-family:Menlo">    <span style="text-decoration:underline">p</span>ythonBridge.call(<span style="color:rgb(209,47,27)">&quot;myMethod&quot;</span><wbr>, arguments: [<span style="color:rgb(209,47,27)">&quot;a&quot;</span>: <span style="color:rgb(79,129,135)">X</span>, <span style="color:rgb(209,47,27)">&quot;b&quot;</span>: <span style="color:rgb(79,129,135)">Y</span>])</div><div style="margin:0px;font-stretch:normal;line-height:normal;font-family:Menlo">}</div></div></div></div></blockquote><div><br></div></span><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><span class=""><br><blockquote type="cite"><div dir="ltr"><div>It might be good to add some <b>use-cases</b> (a popular Python library perhaps) to the proposal where this type of bridge would be insufficient :).</div></div></blockquote><div><br></div></span><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><span class=""><br><blockquote type="cite"><div dir="ltr"><div>It seems like this proposal pushes the responsibility of Swifty-ness and type-safety to the caller.</div></div></blockquote><div><br></div></span><div>Yes, welcome to dynamic languages :-)</div><span class=""><br><blockquote type="cite"><div dir="ltr"><div> At some point you&#39;ll have to write a type-safe bridging layer, or write your entire program in non-Swifty code (&quot;The most obvious way to write code should also behave in a safe manner&quot;). Is the main goal to <b>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></div></span><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><blockquote type="cite"><div dir="ltr"><span class=""><div><b><font size="4">Alternative sugar</font></b></div><div><br></div><div>Ruby has Keyword Arguments for similar sugar:</div><div><font face="monospace, monospace"><b><br></b></font></div><div><font face="monospace, monospace"><b>def</b> foo(regular, hash={})</font><br></div><div><font face="monospace, monospace">    <b>puts</b> &quot;the hash: #{</font><span style="font-family:monospace,monospace">hash}</span><span style="font-family:monospace,monospace">&quot;</span></div><div><br></div><div><br></div><div>I&#39;m sure you&#39;re aware of it, but I&#39;ll explain for completeness, any trailing argument labels are stored and passed as a hash:</div><div><br></div></span><div><pre class="m_-6133027315549987401gmail-prettyprint m_-6133027315549987401gmail-lang-rb m_-6133027315549987401gmail-prettyprinted" style="margin-top:0px;margin-bottom:1em;padding:5px;border:0px;font-family:Consolas,Menlo,Monaco,&quot;Lucida Console&quot;,&quot;Liberation Mono&quot;,&quot;DejaVu Sans Mono&quot;,&quot;Bitstream Vera Sans Mono&quot;,&quot;Courier New&quot;,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="m_-6133027315549987401gmail-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="m_-6133027315549987401gmail-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="m_-6133027315549987401gmail-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="m_-6133027315549987401gmail-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="m_-6133027315549987401gmail-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: &quot;hello&quot;, bas: 123</span><span class="m_-6133027315549987401gmail-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># outputs &#39;the hash: [</b></span><b><span style="color:rgb(48,51,54);font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit">bar: &quot;hello&quot;, bas: 123</span><span style="color:rgb(48,51,54);font-family:inherit;font-style:inherit;font-variant-caps:inherit;white-space:inherit">]’</span></b></pre></div></div></blockquote><div>Python is similar, but allows them to be intermixed with positional arguments.</div><span class=""><br><blockquote type="cite"><div dir="ltr"><div>Have you considered an alternative like this? For example:</div><div><br></div><div><div style="margin:0px;font-stretch:normal;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(186,45,162)">func</span><span> myMethod(regular: </span>Int<span>, store: </span><span style="color:rgb(186,45,162)">@argcapture</span><span> [</span>String<span>: </span>PythonConvertible<span>]) -&gt; </span>PythonConvertible</div></div><div><br></div><div>I&#39;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>alternatives</b> section though. At the moment most of the &quot;alternatives&quot; in the proposal just seem to be extensions to the same solution :)</div></div></blockquote><div><br></div></span><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><span class=""><br><blockquote type="cite"><div dir="ltr"><div><b><font size="4">Clarity</font></b></div><div><b>Perhaps just that things are more clear to me now</b></div><div><br></div><div>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&#39;m guessing that the dynamic member proposal you&#39;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&#39;t find it clear from the proposal that it would only be necessary to implement this protocol once per language.</div></div></blockquote><br></span></div><div>I’m sorry, I don’t understand what you mean.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-Chris</div><div><br></div><br></font></span></div></blockquote></div><br></div>