<div dir="ltr"><div class="gmail_extra">Operators, Nouns, and Verbs</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">There&#39;s an issue that I think it&#39;s worth bringing it out into the open for everyone to see so that we all know it is present. Solutions are possible, but they go beyond the scope of the identifier proposal. Here&#39;s the brief statement of the problem:</div><div class="gmail_extra"><ol><li>Operators are verbs. They <i>operate</i> on their arguments.<br></li><li>Math symbols are not always verbs. ∑ is a verb (and an operator). ∞ is usually understood to be a noun.<br></li><li>Operator <i>symbols</i> (that is: identifiers) are just names. They are neither inherently verbs nor inherently nouns.</li></ol>We tend (at first glance) to prefer for nouns to be treated as identifiers and operators as verbs. Operator identifiers confuse the issue because we are calling them <i>operator</i> identifiers. A better name might be &quot;math symbol identifiers&quot;, because it doesn&#39;t have the same association. Unfortunately there is no Unicode category for &quot;Math symbols that are verbs&quot;. This is true, in part, because there actually isn&#39;t general agreement about how symbols are used in math. Once you get past the basic stuff, a symbol means whatever you define it to mean in the current publication, and math authors grab symbols entirely for the convenience of the authors. Hopefully, but not always, in a way that reflects or suggests a generally recognized intuition. Often no general agreement exists.<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">If we actually wanted to solve the noun/verb issue, we need to acknowledge that being a noun (verb) is orthogonal to being a conventional identifier (math symbol identifier). Here is one way to separate the concepts in Swift:</div><div class="gmail_extra"><ol><li>Make it true that <i>any</i> identifier can be either a conventional identifier or a math symbol identifier. We already do this in several places.</li><li>Make it true that <i>any</i> identifier (including a conventional identifier) can be treated like a reserved word (that is: like an operator) for parse purposes. </li></ol>From a parse perspective, the thing that makes an identifier into an operator is that (a) it has been given some status as a reserved identifier, and (b) it has a defined precedence rule. It would be possible to re-imagine the meaning of Swift&#39;s operator declaration syntax to mean &quot;this identifier is now being given reserved-word status, and should be treated for parse purposes as an operator while this declaration is lexically in scope&quot;. No change is required to the current language. This re-interpretation would allow us to say (for example):</div><div class="gmail_extra"><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra">infix operator LazyAnd : *somePrecedence*</div></blockquote><div class="gmail_extra"><br></div><div class="gmail_extra">which would introduce &quot;LazyAnd&quot; as an operator token <i>even though the identifier does not use math symbols as its characters.</i> Simultaneously, it would allow us to bind ∞ and use that identifier without forcing a noun (∞) to be a verb simply because it has symbols in the name.</div><div class="gmail_extra"><i><br></i></div><div class="gmail_extra">I personally believe that this would resolve some of the confusion about operators, because it would separate the &quot;how do we tokenize?&quot; question from the &quot;what behaves like an operator?&quot; question. It would also allow us to preserve the existing mathematical use of many math symbols that are (by convention) nouns. From a lexer/parser perspective, the concrete change is that we go from &quot;it&#39;s an operator because it&#39;s made up of math symbols&quot; to &quot;it&#39;s an operator because it&#39;s an identifier and it&#39;s in the list of things that are in scope as operators&quot; (effectively a look-up table). That&#39;s the entire change.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Unfortunately every change comes at a cost, and the cost of this one is that we would once again have to be thoughtful about white space. Why? Because:</div><div class="gmail_extra"><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra">a.!  // selection of a field named &quot;!&quot; in object a</div><div class="gmail_extra">a.!+ // selection of a field named &quot;!+&quot; in object a</div><div class="gmail_extra">a.! + // selection of field named &quot;!&quot; in object a followed by operator (?) +</div></blockquote><div class="gmail_extra"><br></div><div class="gmail_extra">You can build comparable examples without field names:</div><div class="gmail_extra"><br></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra">! b // two identifiers</div><div class="gmail_extra">!+ b // two identifiers</div><div class="gmail_extra">! + b// two identifiers</div><div class="gmail_extra">a+b // three identifiers</div></blockquote><div class="gmail_extra"><br></div><div class="gmail_extra">How confusing would this become? We have some limited experience, but only limtied, in BitC. BitC allowed operator definitions to use conventional identifiers in the way I sketched above (actually, we did full-up mixfix, but that&#39;s another topic), and it worked very well. BitC did <i>not</i> allow operators to be used as general-purpose identifiers, but in hindsight I believe that we probably should have done so.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Keep in mind that this is exactly the same &quot;think about white space&quot; issue that we already know from conventional identifiers. </div><div class="gmail_extra"><br></div><div class="gmail_extra">From a &quot;but would this be too weird?&quot; standpoint, all of the <i>current</i> minglings of identifiers without white space would be preserved, so &quot;a+b&quot; would continue to behave like you expect. But just like</div><div class="gmail_extra"><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_extra">a.b__and c</div><div class="gmail_extra">a.b __and c</div></blockquote><div class="gmail_extra"><br></div><div class="gmail_extra">mean two very different things in C++, it would now be true that </div><div class="gmail_extra"><br></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_extra">a.!&amp;&amp;c  // ident dot ident ident</div><div class="gmail_extra">a.! &amp;&amp;c // ident dot ident ident ident</div></blockquote><div class="gmail_extra"><br></div><div class="gmail_extra">would mean different things.</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">I don&#39;t know if I&#39;m being helpful or just confusing the issue further, but I hope this helps people think about this stuff better.</div><div class="gmail_extra"><br></div><div class="gmail_extra"><br></div><div class="gmail_extra">Jonathan</div></div>