<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="">Am 03.12.2017 um 20:04 schrieb Magnus Ahltorp via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>>:</div><br class="Apple-interchange-newline"><div class=""><div class=""><blockquote type="cite" class="">4 Dec. 2017 02:40 Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<br class=""><br class="">That’s a good principle. However, a dynamic member lookup is just a member lookup. By that principle, it should look like a member lookup :-)<br class=""><br 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:<br 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><br class=""><br class="">Further, adding something like .dynamic would completely undermind the proposal. You can already write:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>x.get(“foo”).get(“bar”)<br class=""><br class="">having to write:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>x.dynamic.foo.dynamic.bar<br class=""><br class="">has no point.<br class=""></blockquote><br class="">This example shows what many on this list don't believe: that any Swift method or member access can fail. If the return value of this "get" method is an IUO, or not an Optional at all, and doesn't throw, then the expression would have to fail hard if "foo" didn't resolve to something meaningful.<br class=""><br class="">The most common argument against this proposal is that someone could make an API using Dynamic Member Lookup that could fail even though it is not apparent to the caller. But, as we see in the example, this is just as possible today.<br class=""></div></div></blockquote><div><br class=""></div><div>I just wanted to add that the single purpose of a static type system is to ensure that the methods being called on a receiver are present at runtime and take arguments of the types known at compile time. Of course the type system does not guarantee that those calls to not fail. Even in Haskell there is no guarantee that a function call does not fail as it allows partial patterns (therefore `head []` crashes). Or a function call might enter an infinite loop. But, to repeat, the type system guarantees that the method or member itself will be present.</div><div><br class=""></div><div>Therefore I cannot follow the argument that it follows from the possible failure of a Swift method or member access that it is ok or even a comparable type of failure if the method or member itself is not present. This would imply that Swift’s static type system is unnecessary. Why check for the presence of a method or member if calling it or accessing it might fail anyway? No, I do not buy that argument. And I do not think that I have to provide examples where a static type system is of help.</div><div><br class=""></div><div>The remaining question therefore is whether it is ok to remove the static type system for certain isolated use cases and that might be the case. But I like others would prefer if those use cases would be isolated somehow visually. Someone proposed to require `dynamic` before expressions containing dynamic member lookups similar to `try`, with the additional option to enclose a whole block into `dynamic { … }` to express the same as prefixing each expression with `dynamic`. I still think this has merit:</div><div><br class=""></div><div>````</div><div><div><font face="Menlo" class="">let result = <b class="">dynamic</b> x.foo.bar // will crash if foo or bar are not present</font></div><div class=""><div><font face="Menlo" class=""><br class=""></font></div><div><font face="Menlo" class="">let result = <b class="">dynamic?</b> x.foo.bar // will return nil if foo or bar are not present</font></div></div><div><div><font face="Menlo" class=""><br class=""></font></div><div><span style="font-family: Menlo;" class="">// will crash if foo or bar are not present</span></div><div><font face="Menlo" class="">let result = <b class="">dynamic</b> {</font></div><div><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let y = x.foo.bar</font></div><div><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let z = y.baz(42)</font></div><div><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>return z.zork()</font></div><div><font face="Menlo" class="">}</font></div><div class=""><div><font face="Menlo" class=""><br class=""></font></div><div><span style="font-family: Menlo;" class="">// will return nil if foo or bar are not present</span></div><div><font face="Menlo" class="">let result = <b class="">dynamic?</b> {</font></div><div><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let y = x.foo.bar</font></div><div><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>let z = y.baz(42)</font></div><div><font face="Menlo" class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>return z.zork()</font></div><div><font face="Menlo" class="">} </font></div></div><div class="">````</div></div><div class=""><br class=""></div><div class="">It allows to clearly demarcate the border between regions which are fully statically type checked and those where the static type system be only partially available (depending on the types of the respective receivers) while not being very intrusive due to the block notation. </div><div class="">Of course I can still have a mixture of static and dynamic member accesses _within_ a dynamic block but at least I know that when I am outside of such a block there won’t be any dynamic member accesses. None. Zero.</div><div class=""><br class=""></div><div class="">-Thorsten</div></div><div><br class=""></div></div></body></html>