<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 3, 2017, at 9:39 AM, Chris Lattner &lt;<a href="mailto:clattner@nondot.org" class="">clattner@nondot.org</a>&gt; 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; line-break: after-white-space;" class="">On Dec 3, 2017, at 5:45 AM, Jonathan Hull &lt;<a href="mailto:jhull@gbis.com" class="">jhull@gbis.com</a>&gt; wrote:<div class=""><blockquote type="cite" class=""><div class=""><div class="">Hi Chris,<br class=""><br class="">I am definitely in favor of providing dynamic features in Swift, and of being able to interoperate easily with dynamic languages. I really like the idea overall.<br class=""></div></div></blockquote><div class=""><br class=""></div>Great!</div><div class=""><br class=""><blockquote type="cite" class=""><div class=""><div class=""><br class="">I was about to write up a different idea I had for partially mitigating some of the issues around being able to mistype method names, etc…, but then I remembered a usability principle that I first heard from members of the Lisa team (discovered the hard way): Things which behave the same should look the same, and things which behave differently need to look different.<br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">That’s a good principle. &nbsp;However, a dynamic member lookup is just a member lookup. &nbsp;By that principle, it should look like a member lookup :-)</div></div></div></div></blockquote><div><br class=""></div><div>The behavior is different though (the invisible guard rails which we normally rely on to prevent mistakes are missing), so it should look similar without being identical.</div><div><br class=""></div><div>If Swift were entirely dynamic, there wouldn’t be an issue here, because developers would have strategies for dealing with it. It is the rarity of use that causes the issue here. &nbsp;Swift developers have built up trust in the system to catch their typing mistakes, so if we make it so that the system can silently fail, there will be an increased error rate (above what you would have in a purely dynamic system).</div><div><br class=""></div><div>Let me give a non-computer analogy. There are lots of arguments about whether the toilet seat should always be put down for the next user or just be left in it’s current position. &nbsp;Some households have them randomly up or down based on who used them last. This equates to the dynamic case because no trust can be built that the seat will be down, so everyone learns to check before sitting. Let’s say we add a foot pedal though, which raises the seat when you step on it, and lowers it when it is not pressed (like a garbage can lid). &nbsp;Now everyone can reason about the state of the system and can trust that it will be down unless they step on the pedal. &nbsp;As a result, over time, people will be able to just sit without checking. &nbsp;This is great, but if we re-introduce a little bit of dynamism (let’s say someone can lift the seat without using the pedal and it will stay up)… now the people who have built trust in the system, and just sit, will fall in.</div><div><br class=""></div><div>The end result is that either some trust is lost in the system as a whole (people use the dynamic way of thinking when they don’t need to) or they continue to have errors when dealing with the rare dynamic cases.</div><div><br class=""></div><div>I also like Paul’s suggestion of different syntax coloring for the dynamic calls. &nbsp;In the toilet seat analogy, it is like one of those little lights you can buy that turns green or red depending on whether the seat is up or down.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class="">Further, I incorporated some of the conversation with Matthew into the proposal, showing how adding even a single sigil to dynamic member lookup to distinguish it is problematic:</div><div class=""><a href="https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438#increasing-visibility-of-dynamic-member-lookups" class="">https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438#increasing-visibility-of-dynamic-member-lookups</a></div><div class=""><br class=""></div><div class="">Further, adding something like .dynamic would completely undermind the proposal. &nbsp;You can already write:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>x.get(“foo”).get(“bar”)</div><div class=""><br class=""></div><div class="">having to write:</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">        </span>x.dynamic.foo.dynamic.bar</div><div class=""><br class=""></div><div class="">has no point.</div></div></div></div></blockquote><div><br class=""></div><div>Oh no, I meant a single ‘dynamic’ would enable dynamic lookup for the entire chain, so it would be:</div><div><br class=""></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>x.dynamic.foo.bar</div><div><br class=""></div><div>This is different than requiring a sigil for each lookup.</div><div><br class=""></div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="">What this means is that it is easy to wrap commonly used calls in a normal swift method:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func addTrick(_ name:String) {<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">        </span>self.dynamic.add_trick(name)<br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}<br class=""></div></div></blockquote></div><br class=""><div class="">This would require wrapping all calls for them to be usable.</div></div></div></blockquote><div><br class=""></div><div>I don’t think that chaining with ‘dynamic' is too large of a burden (when it works for the entire chain), so that would be the fallback for calls that haven’t been wrapped. Even if calls are never wrapped, I think this is workable.</div><div><br class=""></div><div>My expectation though is that frequently used calls would end up getting wrapped eventually, and the wrappers would covert to/from Swift types. &nbsp;Basically, I want a system which encourages people to thoughtfully Swift-ify™ the interface for working with python code incrementally over time. Python coders may have no incentive to do this, but Swift users of that code sure do.</div><div><br class=""></div><div>I guess what I am arguing is that we should prioritize/optimize the ease of creating that translation layer at the cost of making pure/direct calls into Python require an extra word of typing. &nbsp;Two birds, one stone.</div><div><br class=""></div><div>Thanks,</div><div>Jon</div><div><br class=""></div><div><br class=""></div></div></body></html>