If you examine the graph etatoby provided, the limit of 0^0 depends on which direction it's approached from: 1 from along the real axis; 0 from along the imaginary axis; and all sorts of [Q] from along a diagonal.
Similarly, we can take pairs of these integers to close under division to get the rationals. Let's denote such pairs n/m (m nonzero), so n'/m' is equivalent when nm'=n'm. The integers are represented as a pair by n/1.
Next we can close the rationals under the property that Cauchy sequences converge: take the set of all Cauchy sequences of rationals, and say two such sequences are equivalent if the term-wise difference between the two converges to the rational 0/1. This gives us the reals, with a rational q being identified with the sequence (q,q,q,...)
Finally, we can close the reals under being able to have polynomials have roots. It turns out adding the root of x^2+1 is all you need. The complex numbers then are the set of all polynomials with real coefficients, where two polynomials are equivalent if their difference is divisible by x^2+1. The reals can be identified as a complex number by thinking of r as a constant polynomial.
All I'm saying is that, while we commonly think of Z as a subset of Q as a subset of R as a subset of C, this is only after a sequence of closures of different kinds, each time creating a completely new set which the first number system is not actually a subset of (though the first number system can be identified as some subset in the new system).
With this in mind, it's completely reasonable to define exponentiation of something to the integer or to the rational as being a completely different operation from exponentiation to the real or to the complex. In fact, in Rudin, exponentiation to the real is defined as a limit of exponentiation to the rationals, which is defined as a positive root of real to the integer.
Why is the integer case obvious? I feel like the absolute simplest example juxtaposing 1^0=1 with 0^1=0 is enough to make figuring 0^0 obviously ambiguous. :)
Considering the integer exponent and real exponent cases separately isn't just a crazy idea of mine, the IEEE floating point spec does it too. The pown function is ^ where the second value is an integer and powr is ^ where the second value is real. (I'm ignoring the difference between doubles and reals.)
Why should pown(0, 0) be 1? pown(x, 0) is 1 for all x other than 0. If pown(0,0) is not 1, it breaks the binomial formula and lots of other convenient things. There's no other relevant limit: pown(0, -1) is undefined and pown(0, 1) is 0, and there's nothing in between. So if you're thinking of ^ as pown (e.g. you're a discrete mathematics person), 0^0 is 1.
On the other hand powr(0, 0) should be undefined. As etatoby's graph shows, the limit depends how you approach it. So if you're thinking of ^ as powr (e.g. you're a real analysis person), 0^0 is undefined.
To conclude, the IEEE floating point spec uses 2 (actually 3 for historical reasons) different functions for x^y. The value of 0^0 depends on which function you use. Arguing over the value of 0^0 is basically arguing whether pown or powr is the "right" function for x^y, and it obviously depends on the situation.
(To clarify: I'm not arguing that it should be done this way because the IEEE spec does it; I'm using the IEEE spec to try to explain the two cases.)
I'm not sure I understand what you mean there.
For any positive nonzero real value x, x^0=1, right? And 0^x=0 for all x too, yes?
The limit from the positive direction for x^0 is 1, you can get arbitrarily close to zero. The limit from the positive direction for 0^x is 0, and you can also get arbitrarily close to 0 here too.
etatoby's graph with isolines, the red and blue ones, shows those two cases specifically, and yeah, they arrive at 0 with two different values, meaning the answer is indeterminate (but not undefined).
Etatoby is right; 0^0 is indeterminate. I'm not arguing with that at all, it is a fact.
I'm saying I understand why people choose to ignore that 0^0 is indeterminate and choose instead to just define that 0^0=1.
I really like your pown() vs powr() example, because it actually demonstrates how in practice, choosing to return a defined value in some cases is the more practical choice.
That said, I think there's still a conflict even within pown(), even for the integer case, that's what I was getting at. pown(0,x) is 0 for all positive x except 0. Negative x is undefined due to the division by 0, and pown(0,0)=1 simply because 0^0 is chosen to be defined at 1. But if you imagine an integer limit starting from 10 going down to zero, there's a clear pattern:
pown(0,10)=0; pown(0,9)=0; ... pown(0,1)=0
pown(10,0)=1; pown(9,0)=1; ... pown(1,0)=1
IEEE chose to make the pown(x,0) rule more important than the pown(0,x) rule when it comes to x=0, even in the case of integers.
It feels wrong to introduce a distinction.
If you're doing things with x^n (integer n), such as combinatorics or polynomials, you need to have 0^0=1 or else you have lots of annoying special cases. e.g. if you have a polynomial sum(an * x^n), you don't want to have it break at x=0.
But if you're working with real or complex exponents, defining 0^0=1 is just strange.