Semantics of ^^

Bill Baxter wbaxter at gmail.com
Tue Dec 8 09:42:33 PST 2009


On Tue, Dec 8, 2009 at 2:32 AM, Don <nospam at nospam.com> wrote:
> Based on everyone's comments, this is what I have come up with:
>
> --------------------
> x ^^ y is right associative, and has a precedence intermediate between
> multiplication and unary operators.

Is that consistent with math?   I think in math they usually write
(-1)^n with parens.
See for example the sin power series here:
http://en.wikipedia.org/wiki/Power_series

What's the rationale for going against math here?

> * The type of x ^^ y is the same as the type of x * y.

Like it.

> * If y == 0,  x ^^ y is 1.

Need to mention what happens when x is also 0.

> * If both x and y are integers, and y > 0,  x^^y is equivalent to
>   { auto u = x; foreach(i; 1..y) { u *= x; } return u; }
> * If both x and y are integers, and y < 0, an integer divide error occurs,
> regardless of the value of x. This error is detected at compile time, if
> possible.

Can you explain why you think that's necessary?  Seems like going too
far towards a nanny compiler for no particularly good reason.

The fact that 2^^-1 isn't particularly useful doesn't make it
particularly error prone.  No more so than integer division when the
person meant floating point division.  I just find it unexpected that
a language would single out exponentiation for this kind of treatment.

> * If either x or y are floating-point, the result is pow(x, y).
> --------------------
> Rationale:
> (1) Although the following special cases could be defined...
>  * If x == 1,  x ^^ y is 1
>  * If x == -1 and y is even, x^^y == 1
>  * If x == -1 and y is odd, x^^y == -1
> ... they are not sufficiently useful to justify the major increase in
> complexity which they introduce.

Hmm, I'm not so sure about that.  I saw examples of this being used
even in the small sampling of search results from Python and Fortran
code that I looked at.  Many mathematical constructs are defined as
having a leading sign of (-1)^^n  (like the sin series formula linked
above).

> In all other cases, a negative exponent
> indicates an error; it should be rewritten as (cast(real)x) ^^ y. Making
> these cases errors makes everything much simpler, and allows the compiler to
> use range propagation on the value of y to detect most exponentiation errors
> at compile time. (If those cases are legal, the compiler can't generate an
> error on x^^-2, because of the possibility that x might be 1 or -1).

I didn't see this error as adding much value when there was nothing
clearly lost from it.  But here you're showing there is a real price
to pay for this nanny compiler behavior.   To me that makes the error
clearly not worth the price of admission.  I also think that since 0^0
and 0^-1 and such are mathematically undefined, careful users of opPow
will already have to put some if() check before blindly doing an x^^y.
 Instead of
   if(x!=0 || y!=0)  x^^y;
the people who care can just change the check to
   if(x!=0 || y>0) x^^y;

Doesn't changing that one operator there doesn't seem like an undue
burden upon those who are careful checkers of their values.

> Also note that making it an error leaves open the possibility of changing it
> to a non-error later, without breaking code; but going from non-error to
> error would be more difficult.

I think it's pretty clear that the error goes too far right now
without taking a wait-and-see stance.

--bb



More information about the Digitalmars-d mailing list