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

Reply via email to