I have a feeling, that at least some of the people objecting to ^^ and/or to **, may actually be objecting to the idea of having an exponentiation operator at all, but they feel they have to justify that objection with something about the syntax.
So let's have some polls. Vote your conscience, no justification required.
First: Should Rust add an exponentiation operator? No nuance.
Yes
No
0voters
Second: If Rust were to add an exponentiation operator, it should be spelled...
Speaking only for myself: I'd love to see an exponentiation operator, but I'd much rather see it be ** (with the additional work to disambiguate that), and would find ^^ unintuitive as it evokes the part of my brain that sees &/&&, |/||, and ^, and assumes ^^ must be related to ^. The fact that most languages use either^ or **, while ^^ is much less common, adds to that concern.
If we don't end up wanting to add **, then I'd sooner add a Pow trait and see if we can make .pow more capable, or consider other potential alternatives.
I personally am indifferent to whether there is an exponentiation operator, but, for much the same reasons as you give, would prefer it to be ** than ^^.
Also, the inclusion of โ in my second poll was not a joke. We do have all of Unicode to work with and the usual objections to non-ASCII punctuators become weaker the more rarely used the punctuator would be.
I am on mobile right now but from what I remember โ isn't somewhere on my PC keyboard. I believe that we would want an operator that can be easily typed from a standard keyboard.
TBH, I just don't think there's a need for a pow operator. Notably, it's frequently heterogeneously-typed, and chaining is quite uncommon in comparison to things like x + y + z or a * b * c.
As a result, I actually rather like the extra parens from x.pow(y.pow(z)) vs x.pow(y).pow(z) if that ever does come up.
And in the common case of something like x ** 2 + y ** 2 + z ** 2 or similar, I really don't think x.pow(2) + y.pow(2) + z.pow(2) is bad at all. And in some ways it's really good, like how it makes the precedence involved really clear.
So for people who want it, why do you want the operator for it specifically?
(Admittedly I also think that we also shouldn't have had certain other heterogeneous non-symmetric operators like shifts, since a << b << c is also kinda weird.)
This is one of the "usual objections to non-ASCII punctuators" that I believe becomes weaker the more rarely the symbol would be used.
Note that for numerical-computation reasons, squares specifically should be computed using multiplication, x*x + y*y + z*z. rustc can actually be trusted to emit a multiplication for x.powi(2) right now, but I can imagine some of the desire for a power operator coming from people who expect anything that looks like a function call to actually result in a function call to a generic library routine. Yeah, that hasn't been true for a long time, but the meme of its being true is still pretty widespread in my experience.
I've seen what happens with languages (e.g. Haskell) that support operators using punctuation that isn't available on the vast majority of keyboards, and I don't think that's a road we should go down.
It would remove the need to learn pow vs. powf vs. powi distinction and select the implementation according to the input type. (This is arguably a point against an operator, since it could implicitly use the less ideal one. Of course, lints could give advice in the matter. Make your own judgement of this consequence.)
error[E0689]: can't call method `pow` on ambiguous numeric type `{float}`
--> src/lib.rs:2:14
|
2 | a * 0.25.pow(b)
| ^^^
|
help: you must specify a concrete type for this numeric value, like `f32`
|
2 | a * 0.25_f32.pow(b)
| ++++
A Pow operator trait would eliminate this highly annoying restriction and let you write just 0.25 ** b, because there is no ambiguity about what method is to be selected (it would be exactly ::core::ops::Pow::pow()).
Haskell/GHC allows user-defined operators and arbitrary Unicode (including Unicode variations of built-in functions as well). And it's often the case that library implementations end up looking extremely inscrutable, with their documentation being "go read this dissertation", with notation and operators that most people can't type without copy-pasting and don't know how to pronounce and talk about. (That's already a problem with user-defined operators, but it becomes even more of a problem when you adopt arbitrary Unicode symbols.)
I don't like having an operator because exponentiation isn't typically directly supported by hardware and is not normally assumed to be a single, O(1) operation.
Seeing how I voted Something else ... in followups. My preferred syntax would be 2 exp 10 or 2 e 10, or 2 pow 10. And my preferred way to achieve it would be to allow syntax sugar for fn pow(self, n: usize) -> usize to be have a two call conventions 3.pow(2) and 3 pow 2.
I'm not sold on arbitrary infix notation, it makes parsing in for example macros much harder.
There could be a marker for it 4 #pow 5 or such. I saw @josh mention
`pow`
But ` is awful to type of many European keyboard layouts, since it is a dead key (waits for a second key press to combine into รจ ร etc). It also makes it so much more annoying in Markdown, since now you need to use double `` for everything.