Rust already has lots of arithmetic-related operators (+, -, *, /) which are based on traits (Add, Sub, Mul, Div). There also exists a pow function for all the integers types (signed or unsigned), as well as for floats. The same is true for the Wrapping and Saturating structs under std::num, so the only difference really between raising a number to an exponent and performing addition, subtraction, multiplication or division operations is the fact that a dedicated Pow trait doesn't exists, along side a dedicated raise-to-power symbol.
Most other languages use the **, and even though Rust uses the * operator for dereferencing, it also uses it as its multiplication operator, which means that there is probably a way to get around that limitation, although that is an issue that should be explored further.
Considering that this would be a major language change if finally implemented, and taking into account the fact that currently trying to raise a number to an exponent using the x**y syntax yields from the compiler the following error:
error[E0614]: type `{integer}` cannot be dereferenced
--> src/main.rs:2:22
|
2 | println!("{}", 2**16);
| ^^^ can't be dereferenced
which means that this change wouldn't break any already-existing code, my opinion is that this feature could be shipped with the next Rust edition (Rust 2027)
I didn't think of that. Nevertheless, that is an issue with the particular operator. My main point is that there should probably be a dedicated operator.
I also doubt that there are many people out there multiplying numbers that way when multiplication can be performed that way too. We could use crater to check the impact of that change, although I believe that operator precedence may be a bigger issue
That's the status quo in other languages too, like Python or Javascript, which despite having a dedicated pow operator (**) don't have a dedicated square root operator.
That doesn't really answer my question. C and C++ which is my background doesn't have operators for either. So from first principles, why pow specially? What are the use cases that motivate this?
For an RFC you would need to argue by for example showing actual real world code examples where this would make an substantial difference in readability.
One reason a power operator would be nice is that it would reduce the need to qualify the type of the base when it is a literal (to allow method dispatch to work). I frequently have to write expressions like 3_usize.pow(3). 3 ** 3 would be subject to type inference and numeric fallback, like other operators are, so it would not require such annotation. In principle, the same argument applies to sqrt(), but I find myself writing far more pows of this sort than sqrt.
That said, I don’t know that it's worth adding another precedence level (** would presumably be higher than *, but would it also be higher than as?) and generally enlarging the language for.
break any already-existing code
Adding an ** operator is the type of change that can be made across an edition. The edition migration would simply insert a space into a**b to create the unambiguous a* *b, and a prefix ** token would become a “double dereference” operator (which is already a kind of thing that has to be done for a && b vs &&thing).
(I’m not saying that this operator should be added, just that adding it is not a particularly problematic change.)
I'm curious as to the context of this. I think I have used pow maybe 2-3 times in my 10+ years career. Sqrt is not common either, but certainly more common (tens to hundreds of times).
Just writing x*x for squaring? About as common as sqrt for me. Higher powers? Extremely uncommon.
&& is not ambiguous, because it's used as unary or binary operator.
Rust added turbofish and requires parens in some places to avoid ambiguity between << and generics.
Rust also doesn't have pre-decrement that would make -- whitespace-sensitive.
I think ** would be the first ambiguity of this kind for Rust, so it is a big deal.
Rust adopted the C-family syntax where * is already doing two important jobs. IMHO languages without this dereference operator aren't a good precedent for Rust.
^^ would make more sense as a "logical xor" operator, rather than exponentiation. It'd be confusing, mathematically, to use it for exponentiation, because ^^ also commonly refers to tetration.
a && b is ambiguous in a similar way to the proposed ** operator, due to both being available as binary (single), binary (double) and prefix operators. Rust Playground
One of the reasons this is not much of an issue in practice for && is that it can only be used with boolean values and for them both meanings have the same result with the exection of side-effects. On the other hand * and ** would have very different meanings.
First, languages like C, C++, C# does not have "logical xor". So, I don't expect, that Rust wish to add "logical xor".
Second, "logical xor" has no shortcut (in opposite to && and ||), it must check both argument to make the conclusion. So, even if Devs wish, Lazy "logical xor" is just not possible to add into the language.
Third, you could easily emulate "logical xor" a xor b with a != b , so it is not in priority for Devs.
Forth, most people recognize in 2 ^ 16 powering, so while ^ is a bitwise xor in Rust, I suggest to add ^^ for powering (in expressions like 2 ^^ 16).
I am writing code that deals with both images and voxels (volume data). It is very common to break up a large region into rectangles or cubes, whose area or volume is the square or cube of the edge length, and need to know what that area or volume is.
There are also various cases of 2^n, which I could write as 1 << n but I don't feel like expressing “power of two scaling” with “bit shift” is clearer.
That depends on what you are doing. For me, who is working with a fair bit of embedded and hardware registers I feel like the bitshift is the natural way to think about it. (Hex and base two is also natural ways to work with constants.)
So what if it has no shortcut? What rule states that logical operations must have a shortcircuit behavior? If it were some fundamental truth, why would Saturating::MAX + n +m not short-circuit for unsigned types as well?
I can follow "C doesn't have it" (with the same lame "no short-circuit behavior" excuse), but it is actually more useful there because it works on non-bool types. In Rust where logical operations only support bool…yes, it is 100% redundant with !=.
First, it is definitely a lie, no one mathematician use double AND to represent XOR.
This ⊻ is Unicode for Xor. And this ⋀ is Unicode for And.
And ^ is called Circumflex Accent, but yes, it looks like And operator.
Second, when you are talking about ^^ looks like "logical xor", you are talking not about math, but about ... C/C++/C#/... programming languages convention: & for bit-AND, | for bit-OR, ^ - for bit-XOR and ... && for logical AND, || for logical OR.
Third, I don't understand your contra-arguments. Be consistent. If you are against ^^ to represent powering because of "how math looking operator", then you must be against ! means negation, not factorial, % percent as a ... reminder, and double less-then << and greater-than >> as bit-shift.
As a conclusion, ^^ is a very good candidate for powering operator in Rust.
I don't have an opinion on ^^ as an exponentiation operator. I'm objecting to the argument that ^^ can't be logical XOR because it cannot short circuit.