<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="">Hi everyone,<div class=""><br class=""></div><div class="">With the holidays and many other things behind us, the core team had a chance to talk about python interop + the dynamic member lookup proposal recently.</div><div class=""><br class=""></div><div class="">Here’s where things stand: we specifically discussed whether a counter-proposal of using “automatically generated wrappers” or “foreign classes” to solve the problem would be better. &nbsp;After discussion, the conclusion is no: the best approach appears to be DynamicMemberLookup/DynamicCallable or something similar in spirit to them. &nbsp;As such, I’ll be dusting off the proposal and we’ll eventually run it.</div><div class=""><br class=""></div><div class="">For transparency, I’m attaching the analysis below of what a wrapper facility could look like, and why it doesn’t work very well for Python interop. &nbsp;I appologize in advance that this is sort of train-of-thought and not a well written doc. &nbsp;</div><div class=""><br class=""></div><div class="">That said, it would be really great to get tighter integration between Swift and SwiftPM for other purposes! &nbsp;I don’t have time to push this forward in the short term though, but if someone was interested in pushing it forward, many people would love to see it discussed seriously.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><b class="">A Swift automatic wrapper facility:</b></div><div class=""><b class=""><br class=""></b></div><div class="">Requirements:</div><div class="">&nbsp;- We want the be able to run a user defined script to generate wrappers.</div><div class="">&nbsp;- This script can have arbitrary dependencies and should get updated when one of them change.</div><div class="">&nbsp;- These dependencies won’t be visible to the Xcode build system, so the compiler will have to manage them.</div><div class="">&nbsp;- In principle, one set of wrappers should be able to depend on another set, and wants “overlays”, so we need a pretty general model.</div><div class=""><br class=""></div><div class="">I don’t think the clang modules based approach is a good way to go.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">Proposed Approach: Tighter integration between SwiftPM and Swift</b></div><div class=""><br class=""></div><div class="">The model is that you should be able to say (strawman syntax):</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;import Foo from&nbsp;<a href="http://github.com/whatever/mypackage" class="">http://github.com/whatever/mypackage</a></div><div class=""><div class="">&nbsp; &nbsp;import Bar from&nbsp;<a href="file:///some/path/on/my/machine" class="">file:///some/path/on/my/machine</a></div></div><div class=""><br class=""></div><div class="">and have the compiler ask SwiftPM to build and cache the specified module onto your local disk, then have the compiler load it like any other module. &nbsp;This means that “generated wrappers” is now a SwiftPM/llbuild feature, and we can use the SwiftPM “language” to describe things like:</div><div class=""><br class=""></div><div class=""><div class="">1. Information about what command line invocation is required to generate the wrappers.</div><div class="">2. Dependency information so that the compiler can regenerate the wrappers when they are out of date.</div><div class="">3. Platform abstraction tools since things are in different locations on linux vs mac, Python 2 vs Python 3 is also something that would have to be handled somehow.</div><div class="">4. The directory could contain manually written .swift code, serving the function similar to “overlays” to augment the automatic wrappers generated.</div><div class=""><br class=""></div><div class="">We care about Playgrounds and the REPL, and they should be able to work with this model.</div><div class=""><br class=""></div></div><div class="">I think that this would be a very nice and useful feature. &nbsp;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">Using Wrappers to implement Python Interop:</b></div><div class=""><br class=""></div><div class="">While such a thing would be generally useful, it is important to explore how well this will work to solve the actual problem at hand, since this is being pitched as an alternative to DynamicMemberLookup. &nbsp;Here is the example from the list:</div><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><div class=""><pre class="ex" style="margin-top: 1.3em; margin-bottom: 1.3em; color: rgb(60, 60, 60); padding: 0.9em; background-color: rgb(238, 238, 238); border: 1px solid rgb(221, 221, 221); font-size: 13.0321px; font-variant-ligatures: normal; orphans: 2; widows: 2; font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace !important;"><span class="kw" style="color: rgb(92, 92, 160);">class</span> BankAccount:
    <span class="kw" style="color: rgb(92, 92, 160);">def</span> __init__<span class="hili" style="background-color: rgb(223, 223, 223);">(self, initial_balance: <span class="pr" style="color: rgb(92, 92, 160);">int</span> = 0) -&gt; None</span>:
        self.balance = initial_balance
    <span class="kw" style="color: rgb(92, 92, 160);">def</span> deposit<span class="hili" style="background-color: rgb(223, 223, 223);">(self, amount: <span class="pr" style="color: rgb(92, 92, 160);">int</span>) -&gt; None</span>:
        self.balance += amount
    <span class="kw" style="color: rgb(92, 92, 160);">def</span> withdraw<span class="hili" style="background-color: rgb(223, 223, 223);">(self, amount: <span class="pr" style="color: rgb(92, 92, 160);">int</span>) -&gt; None</span>:
        self.balance -= amount
    <span class="kw" style="color: rgb(92, 92, 160);">def</span> overdrawn<span class="hili" style="background-color: rgb(223, 223, 223);">(self) -&gt; <span class="pr" style="color: rgb(92, 92, 160);">bool</span></span>:
        <span class="kw" style="color: rgb(92, 92, 160);">return</span> self.balance &lt; 0

my_account = BankAccount(15)
my_account.withdraw(5)
<span class="pr" style="color: rgb(92, 92, 160);">print</span>(my_account.balance)</pre></div></div></div></div></blockquote></div><div class=""><br class=""></div><div class="">The idea is to generate a wrapper like this (potentially including the type annotations as a refinement):</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">typealias</span>&nbsp;BankAccount =&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span></div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">extension</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;</span><span class="" style="color: rgb(112, 61, 170);">PyVal</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;{&nbsp;</span>// methods on BankAccount</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">init</span>(initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) { … }</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;deposit(amount:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;{ … }</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;withdraw(amount:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;{ … }</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;overdrawn() -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;{ … }</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div></div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">my_account = BankAccount(initial_balance:&nbsp;<span class="" style="color: rgb(39, 42, 216);">15</span>)</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">my_account.withdraw(amount:&nbsp;<span class="" style="color: rgb(39, 42, 216);">5</span>)</div></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">print(my_account.balance)</div></div></blockquote><div class=""><div class=""><br class=""></div></div><div class=""><br class=""></div><div class="">It is worth pointing out that this approach is very analogous to the “type providers” feature that Joe pushed hard for months ago, it is just a different implementation approach. &nbsp;The proposal specifically explains why this isn’t a great solution here:</div><div class=""><a href="https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438#introduce-f-style-type-providers-into-swift" class="">https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438#introduce-f-style-type-providers-into-swift</a></div><div class=""><br class=""></div><div class="">That said, while there are similarities, there are also differences with type providers. &nbsp;Here are the problems that I foresee:</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><div class=""><b class="">1) This design still requires DynamicMemberLookup</b></div><div class=""><br class=""></div><div class="">This is because Python doesn’t have property declarations for the wrapper generator to process. &nbsp;The code above shows this on the last line: since there is no definition of the “balance" property, there will be no “balance member” declared in the PyVal extension. &nbsp;A wrapper generator can generate a decl for something it can’t “see”. &nbsp;You can see this in a simpler example:</div><div class=""><br class=""></div><div class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><pre class="lang-py prettyprint prettyprinted" style="margin-top: 0px; margin-bottom: 1em; padding: 5px; border: 0px; font-variant-ligatures: normal; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: 13px; line-height: inherit; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; vertical-align: baseline; width: auto; max-height: 600px; overflow: auto; background-color: rgb(239, 240, 241); color: rgb(57, 51, 24); word-wrap: normal; orphans: 2; widows: 2;"><code class="" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; line-height: inherit; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, sans-serif; vertical-align: baseline; white-space: inherit;"><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(16, 16, 148);">class</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);"> </span><span class="typ" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(43, 145, 175);">Car</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">object</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">):</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">
    </span><span class="kwd" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(16, 16, 148);">def</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);"> __init__</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">(</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">self</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">):</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">
        self</span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">.</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">speed </span><span class="pun" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);">=</span><span class="pln" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(48, 51, 54);"> </span><span class="lit" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant-ligatures: inherit; font-variant-position: inherit; font-variant-caps: inherit; font-variant-numeric: inherit; font-variant-alternates: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(125, 39, 39);">100</span></code></pre></div></div></div></blockquote></div></div></div></div></div><div class=""><br class=""></div><div class="">We really do want code like this to work:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;mini =&nbsp;<span class="">C</span>ar()</div></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">print(<span class="" style="color: rgb(79, 129, 135);">mini</span>.speed)</div></div></blockquote><div class=""><br class=""></div><div class="">How will the wrapper generator produce a decl for ‘speed’ when no decl exists? &nbsp;Doug agreed through offline email that "we’d need to fall back to foo[dynamicMember: “speed”] or something like DynamicMemberLookup.” to handle properties.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">2)&nbsp;</b><b class="">Dumping properties and methods into the same scope won’t work</b></div><div class=""><br class=""></div><div class="">I didn’t expect this, and I’m not sure how this works, but apparently we accept this:</div><div class=""><br class=""></div></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);">struct<span class="" style="color: rgb(0, 0, 0);">&nbsp;S {</span></div></div></div><div class=""><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;x:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span></div></div></div><div class=""><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;x(<span class="" style="color: rgb(186, 45, 162);">_</span>&nbsp;a:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span>&nbsp;{&nbsp;<span class="" style="color: rgb(186, 45, 162);">return</span>&nbsp;a }</div></div></div><div class=""><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div></div></div></blockquote><div class=""><div class=""><div class=""><br class=""></div></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);"><div class="" style="margin: 0px; line-height: normal;"><span class="">let</span>&nbsp;x =&nbsp;<span class="" style="color: rgb(79, 129, 135);">S</span>(x:&nbsp;<span class="" style="color: rgb(39, 42, 216);">1</span>)</div></div></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);"><div class="" style="margin: 0px; line-height: normal; color: rgb(79, 129, 135);">x<span class="">.</span>x &nbsp; &nbsp; &nbsp; &nbsp;// returns 1, not a curried method. &nbsp;Bug or feature?</div></div></div><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);"><div class="" style="margin: 0px; line-height: normal;"><span class="" style="color: rgb(79, 129, 135);">x</span>.<span class="" style="color: rgb(49, 89, 93);">x</span>(<span class="" style="color: rgb(39, 42, 216);">42</span>) &nbsp; &nbsp;// returns 42</div></div></div></blockquote><div class=""><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);"><blockquote class="" style="font-family: Helvetica; font-size: 12px; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div class="" style="margin: 0px; line-height: normal;"><br class=""></div></div></blockquote></div></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;">That said, we reject this:</div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">struct</span><span class="" style="font-family: Menlo; font-size: 11px;">&nbsp;S {<br class=""></span><span class="" style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(186, 45, 162);">var</span><span class="" style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">&nbsp;x:&nbsp;</span><span class="" style="font-family: Menlo; font-size: 11px; color: rgb(112, 61, 170);">Int</span><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div class="" style="margin: 0px; line-height: normal;">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;x() -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span>&nbsp;{&nbsp;<font color="#ba2da2" class="">...</font>&nbsp;} &nbsp;// invalid redeclaration of x</div></div></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);"><div class="" style="margin: 0px; line-height: normal;">}</div></div></div></blockquote><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);"></div></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;">which means that we’re going to have problems if we find a way to generate property decls (e.g. in response to @property in Python).</div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;">Even if we didn’t, we’d still have a problem if we wanted to incorporate types because we reject this:</div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);">struct<span class="">&nbsp;S {</span></div></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;x:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span></div></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;<span class="">x</span>:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Float &nbsp;// invalid redeclaration of X.</span></div></div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><span class="" style="font-family: Menlo; font-size: 11px;">}</span></div></blockquote><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="">This means that even if we have property declarations (e.g. due to use of the Python @property marker for computed properties) we cannot actually incorporate type information into the synthesized header, because multiple classes have all their members munged together and will conflict.</div><div class=""><br class=""></div><div class="">Further, types in methods can lead to ambiguities too in some cases, e.g. if you have:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">extension</span><span class="" style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">&nbsp;PyVal { &nbsp; &nbsp;// Class Dog</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;f(a:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Float</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">Float</span>&nbsp;{&nbsp;<font color="#ba2da2" class="">...</font>&nbsp;}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class=""><span class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">extension</span><span class="" style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);">&nbsp;PyVal { &nbsp; &nbsp;// Class Cat</span></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;f(a:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span>) {}</div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(62, 30, 129);">print</span>(<font color="#4f8187" class="">myDog</font>.<span class="" style="color: rgb(49, 89, 93);">f</span>(a:&nbsp;<span class="" style="color: rgb(39, 42, 216);">1</span>))</div></blockquote><div class=""><br class=""></div><div class="">This compiles just fine, but prints out “()" instead of the result of your Dog method, because we select the second overload. &nbsp;In other cases, I suspect you’d fail to compile due to ambiguities. &nbsp;This is a case where types are really harmful for Python, and one of the reasons that the Python types do not affect runtime behavior at all.</div><div class=""><div class="" style="color: rgb(186, 45, 162); font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);"><blockquote class="" style="font-family: Helvetica; font-size: 12px; margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;"><div class="" style="margin: 0px; line-height: normal; color: rgb(79, 129, 135);"><br class=""></div></div></blockquote></div></div><div class=""><b class="">3) It’s unclear how to incorporate initializers into this model.</b></div><div class=""><br class=""></div><div class="">The example above included this as suggested. &nbsp;It looks nice on the surface, but presents some problems:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">typealias</span>&nbsp;BankAccount =&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">extension</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;</span><span class="" style="color: rgb(112, 61, 170);">PyVal</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;{&nbsp;</span>// methods on BankAccount</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">init</span>(initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span>) { … }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class=""><br class=""></div></div></blockquote><div class="">This has a couple of problems. &nbsp;First of all, in Python classes are themselves callable values, and this break that. &nbsp;Second this mooshes all of the initializers for all of the Python classes onto PyVal.</div><div class=""><br class=""></div><div class="">While it might seem that this would make code completion for initializers ugly, this isn’t actually a problem. &nbsp;After all, we’re enhancing code completion to know about PyVal already, so we can clearly use this trivial local information to filter the list down.</div><div class=""><br class=""></div><div class="">The actual problem is that multiple Python classes can have the same initializer, and we have no way to set the ‘self’ correctly in this case. &nbsp;Consider:</div><div class=""><br class=""></div><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><div class=""><pre class="ex" style="margin-top: 1.3em; margin-bottom: 1.3em; color: rgb(60, 60, 60); padding: 0.9em; background-color: rgb(238, 238, 238); border: 1px solid rgb(221, 221, 221); font-size: 13.0321px; font-variant-ligatures: normal; orphans: 2; widows: 2; font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace !important;"><span class="kw" style="color: rgb(92, 92, 160);">class</span> BankAccount:
    <span class="kw" style="color: rgb(92, 92, 160);">def</span> __init__<span class="hili" style="background-color: rgb(223, 223, 223);">(self, initial_balance: <span class="pr" style="color: rgb(92, 92, 160);">int</span> = 0) -&gt; None</span>: …</pre></div></div></div></div></blockquote><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space;"><div class=""><div class=""><pre class="ex" style="margin-top: 1.3em; margin-bottom: 1.3em; color: rgb(60, 60, 60); padding: 0.9em; background-color: rgb(238, 238, 238); border: 1px solid rgb(221, 221, 221); font-size: 13.0321px; font-variant-ligatures: normal; orphans: 2; widows: 2; font-family: 'Bitstream Vera Sans Mono', 'DejaVu Sans Mono', Monaco, Courier, monospace !important;"><span class="kw" style="color: rgb(92, 92, 160);">class</span> Gyroscope:
    <span class="kw" style="color: rgb(92, 92, 160);">def</span> __init__<span class="hili" style="background-color: rgb(223, 223, 223);">(self, initial_balance: <span class="pr" style="color: rgb(92, 92, 160);">int</span> = 0) -&gt; None</span>: …</pre></div></div></div></div></blockquote><div class="">These will require generating one extension:</div><div class=""><br class=""></div></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">extension</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;</span><span class="" style="color: rgb(112, 61, 170);">PyVal</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;{&nbsp;</span>// methods on BankAccount</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">init</span>(initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">Int</span>) {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(0, 0, 0);">&nbsp; &nbsp;&nbsp;</span><span class="" style="color: rgb(186, 45, 162);">self</span><span class="" style="color: rgb(0, 0, 0);">.</span><span class="" style="color: rgb(186, 45, 162);">init</span><span class="" style="color: rgb(0, 0, 0);">(&nbsp;</span>/* what Python class do we allocate and pass here?&nbsp; BankAccount or Gyroscope? */<span class="" style="color: rgb(0, 0, 0);">&nbsp;)</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><br class=""></div></div></blockquote><div class="">I can think of a couple of solutions to this problem, I’d appreciate suggestions for other ones:</div><div class=""><br class=""></div><div class=""><b class="">3A) Classes turn into typealiases, initializers get name mangled:</b></div><div class=""><br class=""></div><div class="">something like:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">typealias</span>&nbsp;BankAccount =&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);">extension<span class="" style="color: rgb(0, 0, 0);">&nbsp;</span><span class="" style="color: rgb(112, 61, 170);">PyVal</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;{</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">init</span>(BankAccount_initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) { … }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">...</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;my_account = BankAccount(BankAccount_initial_balance:&nbsp;<span class="" style="color: rgb(39, 42, 216);">15</span>)</div><div class=""><br class=""></div></div></blockquote><div class="">I don’t like this: this is ugly for clients, and BankAccount is still itself not a value.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><b class="">3B) Classes turn into global functions:</b></div><div class=""><br class=""></div><div class="">something like:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;BankAccount(initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;{… }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">...</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;my_account = BankAccount(initial_balance:&nbsp;<span class="" style="color: rgb(39, 42, 216);">15</span>)</div><div class=""><br class=""></div></div></blockquote><div class="">This makes the common cases work, but breaks currying and just seems weird to me. &nbsp;Maybe this is ok? &nbsp;This also opens the door for:</div><div class=""><br class=""></div></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class=""><span class="" style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255); color: rgb(0, 132, 0);">// type annotation for clarity only.</span></div></div></blockquote><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;BankAccount:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;= BankingModule.BankAccount&nbsp;</div><div class=""><span class="" style="color: rgb(0, 132, 0);"><br class=""></span></div></blockquote><div class="">which makes “BankAccount” itself be a value (looked up somehow on the module it is defined in). &nbsp;</div><div class=""><br class=""></div><div class=""><b class="">3C) Classes turn into types that are callable with subscripts?</b></div><div class=""><br class=""></div><div class="">We don’t actually support static subscripts right now (seems like a silly limitation…):</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">struct</span>&nbsp;BankAccount {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span>// error, subscripts can’t be static.</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">static</span>&nbsp;<span class="" style="color: rgb(186, 45, 162);">subscript</span>(initial_balance initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;{ … }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">…</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;my_account = BankAccount[initial_balance:&nbsp;<span class="" style="color: rgb(39, 42, 216);">15</span>]</div><div class=""><br class=""></div></div></blockquote><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><br class=""></blockquote></div><div class="">But we could emulate them with:</div><div class=""><br class=""></div><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">struct</span>&nbsp;BankAccountType {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">subscript</span>(initial_balance initial_balance:&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>) -&gt;&nbsp;<span class="" style="color: rgb(112, 61, 170);">PyVal</span>&nbsp;{ … }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;BankAccount:&nbsp;<span class="" style="color: rgb(112, 61, 170);">BankAccountType</span>&nbsp;{&nbsp;<span class="" style="color: rgb(186, 45, 162);">return</span>&nbsp;BankAccountType() }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">…</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;my_account = BankAccount[initial_balance:&nbsp;<span class="" style="color: rgb(39, 42, 216);">15</span>]</div><div class=""><br class=""></div></div></blockquote><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"></blockquote></div></div><div class=""><br class=""></div><div class="">this could work, but the square brackets are “gross”, and BankAccount is not a useful Python metatype. &nbsp;We could improve the call-side syntax by introducing a “call decl” or a new “operator()” language feature like:</div><div class=""><br class=""></div><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(112, 61, 170); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">extension</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;</span>BankAccountType<span class="" style="color: rgb(0, 0, 0);">&nbsp;{</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">func</span>&nbsp;() (initial_balance: PyVal) -&gt; PyVal { … }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;BankAccount:&nbsp;<span class="" style="color: rgb(112, 61, 170);">BankAccountType</span>&nbsp;{&nbsp;<span class="" style="color: rgb(186, 45, 162);">return</span>&nbsp;BankAccountType() }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">…</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;my_account = BankAccount(initial_balance:&nbsp;<span class="" style="color: rgb(39, 42, 216);">15</span>)</div><div class=""><br class=""></div></div></blockquote><div class=""><div class=""><blockquote class="" style="margin: 0px 0px 0px 40px; border: none; padding: 0px;"></blockquote></div></div><div class=""><br class=""></div><div class="">but this still doesn’t solve the “BankAccount as a python value” problem.</div><div class=""><br class=""></div><div class=""><b class="">4) Throwing / Failability of APIs</b></div><div class=""><br class=""></div><div class="">Python, like many languages, doesn’t require you to specify whether APIs can throw or not, and because it is dynamically typed, member lookup itself is failable. &nbsp;That said, just like in C++, it is pretty uncommon for exceptions to be thrown from APIs, and our Error Handling design wants Swift programmers to think about error handling, not just slap try on everything.</div><div class=""><br class=""></div><div class="">The Python interop prototype handles this by doing this:</div><div class=""><br class=""></div><div class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162); background-color: rgb(255, 255, 255);">extension<span class="" style="color: rgb(0, 0, 0);">&nbsp;</span><span class="" style="color: rgb(112, 61, 170);">PyVal</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;{</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span>/// Return a version of this value that may be called.&nbsp; It throws a Swift</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0); background-color: rgb(255, 255, 255);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span>/// error if the underlying Python function throws a Python exception.</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">public</span>&nbsp;<span class="" style="color: rgb(186, 45, 162);">var</span>&nbsp;throwing :&nbsp;<span class="" style="color: rgb(112, 61, 170);">ThrowingPyVal</span>&nbsp;{</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; &nbsp;&nbsp;<span class="" style="color: rgb(186, 45, 162);">return</span>&nbsp;ThrowingPyVal(<span class="" style="color: rgb(186, 45, 162);">self</span>)</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">&nbsp; }</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);">}</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal;">.. and both PyVal and ThrowingPyVal are callable. &nbsp;The implementation of DynamicCallable on ThrowingPyVal throws a Swift error but the implementation on PyVal does not (similar mechanic exists for DynamicMemberLookup).</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);"><div class="" style="font-family: Helvetica; font-size: 12px;">This leads to a nice model: the PyVal currency type never throws a Swift error (it aborts on exception) so users don’t have to use “try” on everything. &nbsp;However, if they *want* to process an error, they can. Here is an example from the tutorial:</div><div class="" style="font-family: Helvetica; font-size: 12px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px;"><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(186, 45, 162);">do<span class="" style="color: rgb(0, 0, 0);">&nbsp;{</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span class="" style="color: rgb(186, 45, 162);">let</span><span class="" style="color: rgb(0, 0, 0);">&nbsp;x =&nbsp;</span><span class="" style="color: rgb(186, 45, 162);"><b class="">try</b></span><span class="" style="color: rgb(0, 0, 0);">&nbsp;</span><span class="" style="color: rgb(79, 129, 135);">Python</span><span class="" style="color: rgb(0, 0, 0);">.</span><span class="" style="color: rgb(79, 129, 135);">open</span><span class="" style="color: rgb(0, 0, 0);">.</span><span class="" style="color: rgb(79, 129, 135);">throwing</span><span class="" style="color: rgb(0, 0, 0);">(</span><span class="" style="color: rgb(209, 47, 27);">"/file/that/doesnt/exist"</span><span class="" style="color: rgb(0, 0, 0);">)</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(62, 30, 129);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span>print<span class="" style="color: rgb(0, 0, 0);">(x)</span></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;">}&nbsp;<span class="" style="color: rgb(186, 45, 162);">catch</span>&nbsp;<span class="" style="color: rgb(186, 45, 162);">let</span>&nbsp;err {</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(209, 47, 27);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span><span class="" style="color: rgb(62, 30, 129);">print</span><span class="" style="color: rgb(0, 0, 0);">(</span>"file not found, just like we expected!"<span class="" style="color: rgb(0, 0, 0);">)</span></div><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;"><br class=""></div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);"><span class="" style="color: rgb(0, 0, 0);">&nbsp;&nbsp;</span>// Here is the error we got:</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;">&nbsp;&nbsp;<span class="" style="color: rgb(62, 30, 129);">print</span>(err)</div><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo;">}</div></div><div class="" style="font-family: Helvetica; font-size: 12px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px;">In practice, this works really nicely with the way that “try” is required for throwing values, but produces a warning when you use it unnecessarily.</div><div class="" style="font-family: Helvetica; font-size: 12px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px;">Coming back to wrappers, it isn’t clear how to handle this: a direct port of this would require synthesizing all members onto both PyVal and&nbsp;ThrowingPyVal. &nbsp;This causes tons of bloat and undermines the goal of making the generated header nice.</div><div class="" style="font-family: Helvetica; font-size: 12px;"><br class=""></div></div></div><div class="">-Chris</div><div class=""><br class=""></div></div></div><div class=""><br class=""></div></body></html>