<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="">On Nov 20, 2017, at 6:12 PM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:<div><blockquote type="cite" class=""><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;"><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 class="" style="font-family: Helvetica; font-size: 12px;"><br class=""></div><div class="" style="font-family: Helvetica; font-size: 12px;">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 class="" style="font-family: HelveticaNeue;">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 class="" style="font-family: HelveticaNeue;"><br class=""></div><div class="" style="font-family: HelveticaNeue;"><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=""> </span><span class="" style="color: rgb(50, 62, 125);">extension</span><span class=""> </span>RubyObj<span class="">: </span>DynamicMemberLookupProtocol<span class=""> {</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 class="" style="margin: 0px; font-stretch: normal; font-size: 11px; line-height: normal; font-family: Menlo; background-color: rgb(255, 255, 255); min-height: 13px;"> <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 class="" style="font-family: HelveticaNeue;"><br class=""></div><div class="" style="font-family: HelveticaNeue;">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 style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Right, that should work directly!</div><br class="Apple-interchange-newline"></div></blockquote></div><br class=""><div class="">I just sent out draft 2 of the DynamicCallable proposal, which directly includes support for this. Thanks for the discussion and insight!</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div></body></html>