<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=""><div class="">I’m not sure this solves the Ruby ergonomics problem. Picking up from an earlier thread:</div><div class=""><br class=""></div><div class="">Chris wrote:</div><div class=""><blockquote type="cite" class="">Paul wrote:</blockquote><blockquote type="cite" class="" style="font-family: HelveticaNeue;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""></div></div></div></blockquote><blockquote type="cite" class=""><blockquote type="cite" class="" style="font-family: HelveticaNeue;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class=""><b class="" style="background-color: rgb(255, 255, 255);">An “always use parens” bridge to Ruby has bad ergonomics</b></div><div class=""><div class="" style="font-family: Helvetica; margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"></div></div><div class=""><span class="">Zero-arg Ruby methods are a mixture of property-like things that would certainly </span><i class="">not</i><span class=""> </span><span class="">use parens in Swift, and function-like things that certainly</span><span class=""> </span><i class="">would</i><span class="">:</span></div><div class=""><div class=""><br class=""></div><div class=""><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; color: rgb(102, 139, 73); background-color: rgb(255, 255, 255);"><span class=""> </span>// Idiomatic Swift:</div><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; background-color: rgb(255, 255, 255);"> post.author.name.reversed()</div><div class="" style="font-family: Helvetica; margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; color: rgb(102, 139, 73); background-color: rgb(255, 255, 255);"><span class=""> </span>// Swift bridging to Ruby…</div><div class="" style="font-family: Helvetica; margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; color: rgb(102, 139, 73); background-color: rgb(255, 255, 255);"><span class=""> </span>// …if no-args methods •must• use parens:</div><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; background-color: rgb(255, 255, 255);"> post.author().name().reverse()</div><div class="" style="font-family: Helvetica; margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; color: rgb(102, 139, 73); background-color: rgb(255, 255, 255);"><span class=""> </span>// …if no-args methods •can’t• use parens:</div><div class="" style="font-family: Menlo; margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; background-color: rgb(255, 255, 255);"> post.author.name.reverse</div><div class="" style="font-family: Helvetica; margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><br class=""></div><div class="" style="font-family: Helvetica; margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><span class="" style="font-family: "Helvetica Neue"; font-size: 13px;">If the goal is to make Swift mostly feel like Swift even when bridging to Ruby, then the bridge needs to support both access forms.</span></div></div></div></div></div></blockquote><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">Ok, that can certainly be implemented by the two proposals I have in flight. No obvious problem there.</div></blockquote></div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">Chris, can you elaborate? I think the proposal precludes this; I must be missing something!</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">As I read the proposal, the dynamic member subscript for <span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">post.author</span> returns either a property value or a DynamicCallable, depending on whether the thing is a property or a method — but <span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">post.author</span> and <span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">post.author()</span> would both look identical to that subscript implementation, and there’s no distinction on the Ruby side, so the subscript can’t know which one to return.</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">The getter could return something that is both a dynamic callable <i class="">and</i> has dynamic members that lazily make the implicit method call. But this has two serious problems:</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">1. The necessarily lazy evaluation of the property value leads to nightmare scenarios:</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class=""><div style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255);" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> post.author = sally</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> <span style="color: #323e7d" class="">let</span> oldAuthor = post.author()</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> post.author = fred</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> oldAuthor.name <span style="color: #668b49" class="">// "Sally"</span></div><div style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal; color: rgb(102, 139, 73);" class=""><span style="color: #000000" class=""> </span>// but</div><div style="margin: 0px; font-stretch: normal; font-size: 12px; line-height: normal; font-family: Helvetica; min-height: 14px;" class=""><br class=""></div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> post.author = sally</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> <span style="color: #323e7d" class="">let</span> oldAuthor = post.author</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> post.author = fred</div><div style="margin: 0px; font-stretch: normal; line-height: normal;" class=""> oldAuthor.name <span style="color: #668b49" class="">// "Fred"</span></div><div class=""><span style="color: #668b49" class=""><br class=""></span></div></div></div></div><div style="font-family: HelveticaNeue;" class="">2. This precludes bridging to Swift types, e.g. Ruby strings → Swift strings.</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">Therefore it seems the proposal forces <span style="font-family: Menlo; font-size: 11px; background-color: rgb(255, 255, 255);" class="">post.author().name().reverse()</span>. Something I'm missing?</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">Cheers,</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">Paul</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On Nov 27, 2017, at 12:04 AM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">I’d like to formally propose the inclusion of user-defined dynamic member lookup types.<br class=""><br class="">Here is my latest draft of the proposal:<br class=""><a href="https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438" class="">https://gist.github.com/lattner/b016e1cf86c43732c8d82f90e5ae5438</a><br class="">https://github.com/apple/swift-evolution/pull/768<br class=""><br class="">An implementation of this design is available here:<br class="">https://github.com/apple/swift/pull/13076<br class=""><br class="">The implementation is straight-forward and (IMO) non-invasive in the compiler.<br class=""><br class="">-Chris<br class=""><br class="">_______________________________________________<br class="">swift-evolution mailing list<br class="">swift-evolution@swift.org<br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></div></blockquote></div><br class=""></body></html>