<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=""><div><blockquote type="cite" class=""><div class="">On Nov 20, 2017, at 6:06 PM, Paul Cantrell <<a href="mailto:cantrell@pobox.com" class="">cantrell@pobox.com</a>> wrote:</div><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=""><br class="">I think you’re missing the idea here: the idea isn’t to provide exactly syntax mapping of Ruby (or Python) into Swift, it is to expose the underlying semantic concepts in terms of Swift’s syntax. In the case of Python, there is a lot of direct overlap, but there is also some places where Swift and Python differs (e.g. Python slicing syntax vs Swift ranges). In my opinion, Swift syntax wins here, we shouldn’t try to ape a non-native syntax in Swift.<br class=""><br class=""><blockquote type="cite" class="">For mapping to Swift, I would say that parens are needed; we can’t guess whether a `foo.bar` is meant to be asking for the value of attribute bar or a reference to method bar.<br class=""></blockquote><br class="">+1<br class=""></div></blockquote><div class=""><br class=""></div><div class="">Chris, did you follow at all the earlier chain of emails where Brent, Jean-Daniel and I hashed this out at length? You may not have got to it yet….</div></div></div></div></blockquote><div><br class=""></div>Perhaps not, I’m just catching up on this thread now. Keep in mind I know almost nothing about Ruby :-)</div><div><br class=""></div><div><br class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><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 style="font-family: HelveticaNeue;" class="">Zero-arg Ruby methods are a mixture of property-like things that would certainly </span><i class="" style="font-family: HelveticaNeue;">not</i><span style="font-family: HelveticaNeue;" class=""> </span><span style="font-family: HelveticaNeue;" class="">use parens in Swift, and function-like things that certainly</span><span style="font-family: HelveticaNeue;" class=""> </span><i class="" style="font-family: HelveticaNeue;">would</i><span style="font-family: HelveticaNeue;" class="">:</span></div><div class=""><div class="" style="font-family: HelveticaNeue;"><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="" style=""> </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="" style=""> </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="" style=""> </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="" style=""> </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 style="font-family: "Helvetica Neue"; font-size: 13px;" class="">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><br class=""></div><div>Ok, that can certainly be implemented by the two proposals I have in flight. No obvious problem there.</div><div><br class=""></div><div><br class=""></div><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><div class=""><div class=""><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; background-color: rgb(255, 255, 255); min-height: 14px;"><div class="" style="margin: 0px; font-stretch: normal; line-height: normal; min-height: 14px;"><b class="">Separating method calls from property accesses solves the problem</b></div><div style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px;" class="">Brent wrote:</div></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;"><div class=""><blockquote type="cite" class="" style="font-family: HelveticaNeue; font-size: 13px;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div dir="auto" class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><div class=""><div class="">If we had separate subscripts for methods and properties, then the property subscript could immediately call the appropriate getters and setters, while the method subscript could return a ready-to-call `Method` object.</div></div></div></div></div></blockquote></div></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></div><div style="font-family: HelveticaNeue;" class="">Better yet, why bother with the ready-to-call Method-like object? Just call it! A Ruby binding with separate property and method handling would then look like this:</div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class=""><div class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(88, 126, 168); background-color: rgb(255, 255, 255);"><span class="" style=""> </span><span class="" style="color: rgb(50, 62, 125);">extension</span><span class="" style=""> </span>RubyObj<span class="" style="">: </span>DynamicMemberLookupProtocol<span class="" style=""> {</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);"> <span class="" style="color: rgb(50, 62, 125);">func</span> callDynamicMethod(dynamicMethod method: <span class="" style="color: rgb(88, 126, 168);">String</span>, args: [<span class="" style="color: rgb(88, 126, 168);">RubyObject</span>]) -> <span class="" style="color: rgb(88, 126, 168);">RubyObj</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);"> get {</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(50, 62, 125);">return</span> RubyObject_send(rubyObject, method: member, args: args)</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 style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;" class=""> <br class="webkit-block-placeholder"></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(50, 62, 125);">subscript</span>(dynamicMember member: <span class="" style="color: rgb(88, 126, 168);">String</span>) -> <span class="" style="color: rgb(88, 126, 168);">RubyObj</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);"> <span class="" style="color: rgb(50, 62, 125);">get</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);"> <span class="" style="color: rgb(50, 62, 125);">return</span> RubyObject_send(rubyObject, method: member, args: [])</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(50, 62, 125);">set</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);"> RubyObject_send(rubyObject, method: <span class="" style="color: rgb(133, 62, 100);">"</span>\<span class="" style="color: rgb(133, 62, 100);">(</span>member<span class="" style="color: rgb(133, 62, 100);">)="</span>, args: [newValue])</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);"> }</div></div><div style="font-family: HelveticaNeue;" class=""><br class=""></div><div style="font-family: HelveticaNeue;" class="">When Swift sees myObj.name, it uses the getter subscript. When Swift sees myObj.name(), it uses the method invocation. Both work in Swift just as they do in Ruby — and more importantly, Ruby APIs wouldn’t feel so very awkward when used from Swift.</div></div></div></blockquote><br class=""></div><div>Right, that should work directly!</div><div><br class=""></div><div>-Chris</div><div><br class=""></div><br class=""></body></html>