-1<br><div class="gmail_quote"><div dir="ltr">On Fri, Mar 10, 2017 at 6:18 AM Haravikk via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg">So the topic of global functions like min/max came up on the thread about adding a standard clamp method, and it got me to thinking whether there was a better way to define most global methods.<div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">Currently for example there are two global functions min and max; very useful, and don&#39;t make much sense as instance methods, but they&#39;re not as easily discoverable as a static method declared under relevant type(s). We could get around this by defining such functions both as a static method, and as a global function, but it means duplicate code and by convention only.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">An alternative is to remove the need for duplicate methods using a new global keyword for a method declaration, telling Swift to define it as both a static method <b class="gmail_msg">and</b> a global function. This allows the function to be grouped logically under a type, making it a bit neater, but without losing the benefit of the global definition. For example:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>protocol Comparable {</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>global func min(_ a:Self, _ b:Self) -&gt; Self { return a &lt; b ? a : b }</font></div><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>global func max(_ a:Self, _ b:Self) -&gt; Self { return a &gt; b ? a : b }</font><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>}</font></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">With this single definition both of the following are now valid:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>let min = Int.min(1, 3)</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>let max = max(5, 10)</font></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In the second case, Swift looks at all global definitions for &quot;max&quot; in order to locate the best match, leading it to Int.max.</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">It&#39;s a relatively small change, but helps with neatness. It may also be good for consistency if we ever get the ability to define operators within types (though I&#39;m not sure where we are with that?), as they could potentially just use the same format like-so:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>struct MyType : Equatable {</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">                </span>global func == (_ a:MyType, _ b:MyType) -&gt; Bool { /* Determine equality */ }</font></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>}</font></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I just think it&#39;s a neater way to do this than currently requiring separate declarations for the static and global versions, especially since one usually just calls the other anyway, anyone have any thoughts?</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">I normally argue against new keywords, but in this case it may be justified, as I considered an attribute but it would only end up requiring static anyway, so it seemed neater to just have a new category &quot;above&quot; static that is both static and global, since a global non-static doesn&#39;t make any sense. However, one advantage of a @global attribute is that it could potentially take a different name for the global function, so I could (but probably wouldn&#39;t) define something like:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"><font face="Monaco" class="gmail_msg"><span class="m_4442166515936765386Apple-tab-span gmail_msg" style="white-space:pre-wrap">        </span>@global(&quot;min&quot;) static func smallerOfTwo(_ a:Self, _ b:Self) -&gt; Self { return a &lt; b ? a : b }</font></div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">So here, although the method name is smallerOfTwo, it is exposed globally as &quot;min&quot;. Though I don&#39;t know much need there would be for something like that.</div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div>