On Thu, 28 Oct 2010, Damian Conway wrote: > The apparent paradox ... is due to the assumption (employed in the > second interpretation) that < is identical to !>=. Certainly that is > true for simple scalar numbers, but not always for vector types such > as tuples, sets, bags, complex numbers...or junctions.
> That doesn't make either < or !>= intrinsically invalid on vector types > (though they obviously are inappropriate for *some* vector types); it just > means you can't reasonably treat the two operators as universally > interchangeable, just because they sometimes are. Well, I think returning or throwing an "Unordered" exception would be the appropriate way to handle those, both for complex numbers and for junctions. Anyone who thinks they're dealing with real numbers will reasonably expect "<" and "!>=" to be the same, and a junction can masquerade as anything (within each thread), including a real number. And what about when that difference is wrapped up inside a function? In other words, what's wrong when I expect the following two snippets to work the same way? A: sub anything_is_broken($subject) { grep { ! .test() } $subject.parts() } if anything_is_broken($subject) { fail($subject) } else { pass($subject) } B: sub everything_is_working($subject) { ! grep { ! .test() } $subject.parts() } if everything_is_working($subject) { pass($subject) } else { fail($subject) } Why should it make a difference whether $subject is a junction? > In summary, the "problem" here seems to be that, algebraically, > junctions don't behave exactly like non-junctions. Which is true, but no > more a problem than the fact that, algebraically, complex numbers don't > behave exactly like non-complex numbers, or that sets don't behave > exactly like non-sets, or that Rats don't behave exactly like Nums, > which don't behave exactly like Ints, which don't behave exactly like > ints either. When you're talking about built-in operators, that's plausible, because by looking for "!" in the operator name there are ways to DWIM-or-throw-an-exception. That's not true for user-defined functions, so I think the real problem is that the parallelizing of the expression that contains a junction may not be "obvious" at the point where it happens. Hmmm .... maybe one way to improve that might be to say that you can't put a junction into an untyped scalar, or indeed in any variable that isn't explicitly marked as "this thing might contain a junction". That would apply, as now, to function parameters and returns, but also to variables and aggregate members; indeed, *everywhere*. > And, of course, that's why Perl 6 has strong typing. So that, when > these differences in behaviour do matter, we can specify what kind(s) > of data we want to allow in particular variables, parameters or return > slots...and thereby prevent unexpected kinds of data from sneaking in > and violating (un)reasonable expectations or inducing (apparent) > paradoxes. :-) I don't think strong typing is enough, because we explicitly mask the application of type constraints by autothreading. Each thread sees a thing with the type it expects, but the problem comes when the threads are recombined; the result often won't be what's expected. Don't get me wrong, I think Junctions are a really clever way of writing concise conditional expressions, but I think algebraic consistency is more important than clever conciseness. -Martin