<div dir="ltr">I’m gonna come out and say I’m not a fan of this at all. I’m already pretty suspicious of operator overloading, and I think supporting this would make Swift code much more difficult to read. Also, while for some reason everyone ignores this, this kind of syntax is almost impossible for text editors to highlight, which I think is an important consideration for any changes to language syntax.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jul 31, 2017 at 5:09 PM, Gor Gyolchanyan via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">So I was thinking the other day (and by &quot;the other day&quot; I mean &quot;It just occurred to me&quot;) that Swift&#39;s custom operator declaration mechanism is pretty sweet (it&#39;s become even sweeter ever since numeric precedence values were replaced with purely relativistic precedence trees). There are currently only two problems with them that grind my operator-declaring endeavors to a painful halt:<div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>1. The fact that most punctuation characters on the keyboard (think - ASCII) are reserved, so any custom operator either has to be a long sequence of two or three non-reserved ASCII characters or have to include difficult-to-type unicode punctuation characters.</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>2. The fact that anything that passes as an identifier character (which includes a surprisingly wide array of punctuation characters) is off the table as well.</div><div><br></div><div>I have no good idea how to deal with the first problem, but the second problem seems to have a bafflingly simple solution that I can&#39;t believe I haven&#39;t noticed until now.</div><div>And the reason to even try to solve that problem is because Swift already has a lot of operators with identifiers in them:</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* infix is</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* infix as</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* infix as?</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* infix as!</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* prefix try</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* prefix try?</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* prefix try!</div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>* prefix throw</div><div>So this is hardly a new concept to Schwifty developers.</div><div><br></div><div>The way I think could this could be solved is by introducing custom keywords that can be defined just like custom operators can be.</div><div>The custom keyword has to be a valid identifier and is defined much like a non-infix custom operator (by writing `keyword`, followed by an identifier).</div><div><br></div><div>Custom operator definitios would now be permitted to have any number of non-adjacent keywords among usual punctuation characters.</div><div>Any identifier that matches a custom keyword has to be escaped with backticks just like it&#39;s the case for regular keywords.</div><div>Prefix operators may not end with a keyword.</div><div>Postfix operators may not begin with a keyword.</div><div>Infix operators that either begin or end with a keyword may not be used without whitespaces.</div><div><br></div><div>Here&#39;s an example:</div><div><br></div><div><div><font face="Menlo"><font color="#941751">precedencegroup</font> <wbr>AggregateFormingPrecedence {</font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">higherThan</font>: TernaryPrecedence</font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">lowerThan</font>: </font><span style="font-family:Menlo">LogicalDisjunctionP<wbr>recedence</span></div><div><font face="Menlo">}</font></div></div><div><font face="Menlo"><br></font></div><div><div><font face="Menlo"><font color="#941751">precedencegroup</font> <wbr>DimensionFormingPrecedence {</font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">higherThan</font>: </font><span style="font-family:Menlo">Aggregate</span><span style="font-family:Menlo">FormingPr<wbr>ecedence</span></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">lowerThan</font>: LogicalDisjunctionPrecedence</font></div><div><font face="Menlo">}</font></div></div><div><font face="Menlo"><br></font></div><div><font face="Menlo"><font color="#941751">keyword</font> of</font></div><div><font face="Menlo"><font color="#941751">keyword</font> by</font></div><div><div><font face="Menlo"><font color="#941751">infix</font> <font color="#941751">operator</font> of: </font><span style="font-family:Menlo">Aggregate</span><span style="font-family:Menlo">Fo<wbr>rmingPrecedence</span></div></div><div><font face="Menlo"><font color="#941751">infix</font> <font color="#941751">operator</font> by: DimensionFormingPrecedence</font></div><div><font face="Menlo"><br></font></div><div><div><font face="Menlo"><font color="#941751">public</font> <font color="#941751">struct</font> <font color="#008f00">Matrix</font>&lt;<font color="#008f00">Element</font>&gt; <font color="#941751">where</font> <font color="#008f00">Element</font>: <font color="#008f00">FloatingPoint</font> {</font></div></div><div><font face="Menlo"><br></font></div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">public</font> <font color="#941751">struct</font> <font color="#941751">Dimensions</font> {<br><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">let</font> rows: <font color="#008f00">Int</font><br><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">let</font> columns: <font color="#008f00">Int</font><br></font><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div><font face="Menlo"><br></font><div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">public</font> <font color="#941751">init</font>(dimensions: <font color="#008f00">Dimensions</font>, value: <font color="#008f00">Element</font>) {</font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">                </span><font color="#941751">self</font>.elements = .<font color="#941751">init</font>(repeating: value, count: dimensions.rows * dimensions.columns)</font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span>}</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">private</font> <font color="#941751">var</font> elements: [</font><span style="color:rgb(0,143,0);font-family:Menlo">Element</span><font face="Menlo">]</font></div><div><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap"><font face="Menlo">        </font></span></div><div><font face="Menlo">}</font></div></div><div><font face="Menlo"><br></font></div><div><font face="Menlo"><font color="#941751">public static func</font> by(_ rows: <font color="#008f00">Int</font>, _ columns: <font color="#008f00">Int</font>) -&gt; Matrix.Dimensions {</font></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">return</font> .<font color="#941751">init</font>(rows: rows, columns: columns)</font></div><div><font face="Menlo">}</font></div><div><font face="Menlo"><br></font></div><div><font face="Menlo"><font color="#941751">public static func</font> of&lt;<font color="#008f00">Element</font>&gt;(_ dimensions: Matrix.Dimensions, _ value: Element) -&gt; <font color="#008f00">Matrix</font>&lt;<font color="#008f00">Element</font>&gt; </font><font style="font-family:Menlo" color="#941751">where</font><span style="font-family:Menlo"> </span><font style="font-family:Menlo" color="#008f00">Element</font><span style="font-family:Menlo">:<wbr> </span><font style="font-family:Menlo" color="#008f00">FloatingPoint</font><span style="font-family:Menlo"> {</span></div><div><font face="Menlo"><span class="m_-5204152814233728088Apple-tab-span" style="white-space:pre-wrap">        </span><font color="#941751">return</font> .<font color="#941751">init</font>(dimensions: dimensions, value: value)</font></div><div><span style="font-family:Menlo">}</span></div><div><font face="Menlo"><br></font></div><div><font face="Menlo"><font color="#941751">let</font> m = </font><span style="font-family:Menlo">3 by 4 of 1.0 <font color="#797979">// m is of type Matrix&lt;Double&gt;</font></span></div><div><br></div><div>I feel like these kind of changes would be best considered in the early stages of a major release (namely, Swift 5) so that they have time to be refined and tested.</div><div>What do you guys think?</div><div><br></div></div></div><br>______________________________<wbr>_________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/<wbr>mailman/listinfo/swift-<wbr>evolution</a><br>
<br></blockquote></div><br></div>