Moritz Lenz wrote: > Jon Lang wrote: >> By the principle of least surprise, I'd recommend against this. Most >> programmers, when they see 'sqrt(1)', will expect a return value of 1, > > And that's what they get unless they write it as sqrt(1 + 0i).
I suppose that you _could_ use the programmer's choice of whether or not to use complex numbers in the argument list as the indicator of whether to return one answer or a junction of them. Of course, this could lead to subtle bugs where the programmer assigns a complex value to $x and later takes the sqrt($x), but forgets that he assigned a complex number earlier. This may or may not be sufficient grounds for requiring an explicit declaration that you want junctions. >> and won't want to jump through the hurdles involved in picking '1' out >> of 'any(1, -1)'. > > 1 and -1 aren't just separated by a complex plane, they are really > distinct numbers True enough. I fail to see how that invalidates my point, though: if you're going to mess with multiple complex planes, why wouldn't you also address the issue of distinct numbers as well? The latter issue is intimately connected to the former, as I demonstrate below. >> And even then, I'm concerned that it might very quickly get out of >> hand. Consider: >> >> pow(1, 1/pi() ) :any - 1 >> >> (I think I got that right...) > > Not quite. Afaict the only functions that might return a junction are > Complex.angle and Complex.log. Why is that? Complex numbers can exist on multiple complex planes even if you don't explicitly look at the angle. One example of this phenomenon in action takes the form of a 'proof' that 1 == -1: 1 == sqrt(1) == sqrt(-1 * -1) == sqrt(-1) * sqrt(-1) == i * i == -1 #< Assumes complex numbers throughout. > The equality between the first and second steps means that the 1 inside the sqrt can only have an angle that is a multiple of 4pi. Because of this, the -1's that appear in the third step cannot exist on the same complex plane with each other: e.g., if the first one has an angle of pi, the second has to have an angle of -pi, 3pi, 7pi, 11pi, ... As a result of this, the signs of the sqrts in the fourth step must be opposed: if the first sqrt(-1) returns i, the second sqrt(-1) must return -i, and vice versa. That means that there's a negative term missing in the fifth step, which would cancel out the negative term that appears in the final step. At the very least, we need to add infix:<**> and all related functions (e.g., sqrt) to the list of functions that might return a junction. And when and if Perl 6 adds constraint programming to its repertoire, it will have to be smart enough to properly constrain complex planes as well as complex values. -- Bringing this back down a bit closer to Earth: if you supply a complex number using rectilinear coordinates, a case could be made that you've provided insufficient information, and that the complex number ought to be stored as a junction of all of the different complex plane representations for that otherwise-distinct value. If you supply a complex number using polar coordinates, you have been able to supply the choice of complex plane as well as a distinct value; so only one representation should be stored. That is: (1 + 0 * i).angle == any (0, 2 * pi, 4 * pi, ...); exp(0 * i).angle == 0; exp(2 * pi * i).angle == 2 * pi; So: (1 + 0 * i) == any (exp(0), exp(2 * pi * i), exp(4 * pi * i), ...); Extending this further: exp($C) effectively reinterprets a complex number's rectilinear coordinates as polar coordinates, and log($C) does the inverse. So as long as $C contains a single value, exp($C) should always return a complex number that exists on a single complex plane, established by $C's imaginary component; conversely, log($C) ought to return a complex value that is represented on every possible complex plane, since neither the angle nor the magnitude of $C provides enough information to determine which plane to use. Of course, there may be (and probably are) technical difficulties that make this unworkable. >> Since pi is an irrational number, there are infinitely many distinct >> results to raising 1 to the power of 1/pi. > > No. exp($x) is a single, well-defined value. True, as long as $x is a single, well-defined value. But I wasn't talking about exp($x); I was talking about pow($x, $y), $x ** $y, sqrt($x), and so on. Just as: sqrt(1 + 0 * i) == sqrt(any(exp(0), exp(2 * pi * i), exp(4 * pi * i), ...)) == any(exp(0), exp(pi * i), exp(2 * pi * i), ...) it is also the case that: (1 + 0 * i) ** pi == any(exp(0), exp(2 * pi * i), exp(4 * pi * i), ...) ** pi == any(exp(0), exp(2 * pi * pi * i), exp(4 * pi * pi * i), ...) And all of those answers are distinct values. > But you do have a point that we can't really use infinite junctions > unless we can ensure that we can do all sorts of arithmetics with it > without losing laziness. And I don't think we can prove that (but I > might give it it shot if I have some spare time) Just noting that we're not totally in disagreement. :P -- Jonathan "Dataweaver" Lang