I think using is for equality check is a bad idea. I would think it checks for reference equality (i.e. two separate vectors can return false for it even if their contents is identical), especially considering it works like this in Python (well, with the exception of "primitive" values).
But I also would like to use words instead of digraphs. Sometimes in complex expressions it becomes difficult to parse a bunch of !s, ||s and &&s. Though introducing a whole bunch of keywords does not seem optimal. There could be a place for a feature which would allow using registered methods in a keyword-like fashion, something like this:
// .method is a placeholder syntax
if (a .and b) .or .not (c .ne d) { .. }
use core::time::DurationUnits;
let t = 1u32 .seconds;
// desugars into
if (a.and(b)).or((c.ne(d)).not()) { .. }
let t = 1u32.seconds();
// inside libcore
impl bool {
#[infix_quasi_keyword]
fn and(self, b: bool) -> bool { .. }
#[prefix_quasi_keyword]
fn not(self) -> bool { .. }
}
impl DurationUnits for u32 {
#[postfix_quasi_keyword]
fn seconds(self) -> Duration { Duration::from_secs(self) }
}
I also believe that keywords would increase legibility, especially for and, or and not since ! is also used for macro and never type, & is also used for references and | is also used for closures.
Digraphs, Trigraphs, and named tokens aren't for keyboard layouts not having the keys, but were for the characters not existing in some charsets (C had the named tokens under the iso646.h header as macros - using the header lets you write C in any ISO646-compatible charset).
However, rust specifies its basic source character set as UTF-8, which definately contains all of the sigils that rust uses (and many more). It doesn't have the same need.
Additionally, because these alternative tokens are all lexically (and not merely syntactically) identical, you get some really weird things like compl A(){} (which is a destructor definition) and A(A and){} which is a move constructor. I think this would not necessarily be a good thing to add to rust, which is sigil heavy in some aspects and is easily subject to the same kind of abuse. let y = and x; for example, would unintuitively be a shared reference to a temporary which has the value of a shared reference to x.
Of course, if we use keywords, it should not be just a direct substitution like C macro. These new keyword would only work for logical operations.
To me the goal of using keywords instead of sigils for logical operations would be precisely to reduce ambiguity. & would be only related to references, | only related to closures and ! only related to macros expansion (if we also use an actual named Never type).
Since Rust already has traits for most of its ops, inventing new unrelated keywords for them seems like a poor choice. So instead of is, it should be eq.
Or, it would be even simpler. Instead of adding keywords, add a syntax sugar for calling methods without needing parenthesis or the dot.
We could do this; we could, for instance, say that a `func` b is equivalent to a.func(b), which would allow bespoke infix operator syntax.
However, such operators primarily have value in larger expressions rather than a single binary operator. And larger expressions are precisely where more complexity would come in, most notably that we'd also have to deal with operator precedence.
That sounds rather backwards, since users of other languages will expect them to refer to the appropriate logical operation, rather than some other construct.
It also seems to me like it would be hard to read in incredibly nested code - a stream of identifiers, where one just blends into the one to its left and one to its right.
Syntactically, there's no ambiguity, and I'm unsure that there's any significant ambiguity from reading it that won't just be exagerated by this.
Note that I am not telling that introducing all the proposed keywords right now is a good idea. Not all of them seems usefull to me and that would change the language too much. But I believe that it might have been interesting to do that before 1.0 for the boolean operators.
I don't understand why it would be backward : the sigils for lambda, references and macro are already there. I don't see how it would be more confusing than it already is. That would just visually disambiguate these usages from logical operators.
There are quite a lot of language with keywords for logical operator, like Python, Basic, Pascal, Ada, ... that don't seem to disturb much. And they are quite self explanatory anyways, even for if you never heard about them,.
Currently there are no syntactical ambiguity but I remember that there were syntax decision that where constrained by that. I don't remind exactly witch ones but there where syntax problems with some closures improvement proposals that where conflicting with the or operator, as they were problems with comparison operators and generics that led to the infamous turbofish.
For me, the following examples are quite convincing about legibility at first glance of keywords for boolean operators:
let a = b & &c;
let x = || y || z;
let n = ! m!(o);
vs
let a = b and &c;
let x = || y or z;
let n = not m!(o)
Choosing in 2012 to have and/or instead of &&/|| would have been perfectly reasonable.
But today? I don't see the churn to encourage everyone to change as worth it, and having a mix -- potentially even in the same crate -- seems substantially worse than what we have now.
We have a very C-like syntax and operator set, and that's ok. Even if that's not the most beautiful set, at least it looks like most other braces-and-semicolons languages. Diverging from that doesn't seem clearly better, even if it makes individual operators better.
As non-English (even non-Western language) speaker, I don't like keywords (or logical operators) like and and or.
I expect programming languages to use sigils to represent very fundamental or special meanings in the code. To me (and possibly many other people who also aren't fluent English speaker), sigils can be quite easily distinguishable from english symbols. For example, when reading foo && !bar && baz == qux, I can quickly recognize identifiers (symbols) foo, bar, baz, and qux, and imagine syntax tree that has them as a leaf.
However, when special and/or fundamental things are represented with english-like keywords, it would take more time to get the code's meaning. For example, when I see foo and not bar and baz is qux, I'll be confused and takes time to understand the expression, because keywords (operators) and identifiers (operands) look similar and my eyes slip on them (even if they are syntax-highlighted).
Same reasoning applies to |args| body syntax, I prefer it over lambda args: body or something like that.
(Using same | to opening and ending would not be a good idea, but it is another topic.)
What I wanted to say is: Sigils would help some of non-English-native to read the code, and "naturally readable as an English-like statement" won't be nice feature for such people (at least for me). I think that comparisons, arithmetic operations, and logical operations are fundamental enough and worth using sigils.