In article <[EMAIL PROTECTED]>, [EMAIL PROTECTED] (Luke Palmer) wrote: >Well, we see the same kind of thing with standard interval arithmetic: >[...]
It didn't bother me that junctions weren't ordered transitively. (Ordering had better work transitively for ordinary numbers, but junctions aren't numbers.) Yes, the 4<(0|6)<2 thing doesn't quite DWIM, but maybe I should just mean something else. Except then I started thinking about why, and I decided that it *should* DWEveryoneM. Funny things that aren't numbers can still be ordered intransitively, but the reason that this doesn't work the way we want is not so much because junctions are something funny, but because < is something funny. That is, x<y<z does not mean "y is between x and z", which is how most people probably read it. Instead, because of chain association, it means "x<y and y<z". Our problem then comes from using y in two different terms instead of a single 'between' term: If we had a 'between' operator, "y between [x,z]" would work even for junctions. The chain-association thing puzzled me a bit, because in the back of my mind I was still thinking of comparative operators as doing their chainy magic by returning a value to be applied to the following term (sort of like +) -- no 'and's involved. In 4<6<2, the 4<6 returns "6 but true", and then we're left with 6<2, which is false. Similarly, 4<(0|6)<2 first evaluates 4<(0|6) aka 4<0 | 4<6. Booleating a junction returns the elements that fit, in this case 6. Then we move on to evaluate 6<2, which again is false, just as we wanted. <http://groups-beta.google.com/group/perl.perl6.language/browse_thread/th read/41b18e5920ab2d78/4b24a002ab4ff9c9> Quoting from the first message in that thread: >If a boolean operation is applied in non-boolean context to a >junction, it will return a junction of only the values for which the >condition evaluated true. [...] > >* Junctions discard C<undef>s on-sight (i.e. C<undef> can never be a > member of a junction). >* Comparison operators return C<undef> if they fail, and their > left-hand side "C<but true>" if they succeed. >* Comparison operators are right-associative. Oops, my example above assumed < was left-associative and returned its right-hand side. But doesn't flipping it around that way solve this: >Unfortunately, the last change clobbers the left-short-circuiting >behavior of comparison operators. or are there funny edge cases or something that I'm not seeing? Anyway, the above-cited thread presents two versions of junctions and comparative operators, and I prefer the Lucian interpretation to the Damianian. It seems a bit more mathematical and a bit less specially-cased; both good things in my book. >But you can force a collapse like this: > my $x = 4 < $j; > if $x < 2 { say "never executed" } Because then we're explicitly taking the result of the first comparison and applying it to the second. Which is what 4<$j<2 ought to mean anyway. I think Autrijus's solution for Pugs is to treat < as list-associative (with a between[-like] function as the list op), but I'm not sure how that works when you try to mix different comparative operators. If every boolean function returns the junctive elements that make it true, then they can be chained indiscriminately: is_even(is_prime(1|2|3|4|5))>2 means is_even(2|3|5)>2 means (2)>2 means false. Incidentally, is there a way to decompose a junction? Something like a .conjunctions method that returns a list of all the conjunctive elements (if it isn't a conjunction, then it would return a single element which is the whole thing). $petticoat=(1 | 2 | 3 | (4&5)); $petticoat.conjunctions; # list containing (1|2|3|(4&5)) $petticoat.disjunctions; # list containing 1, 2, 3, (4&5) ($petticoat.disjunctions)[-1].conjunctions; # list 4, 5 - David "guilty by list association" Green