Front page | perl.perl6.language | Postings from February 2005

## Re: Junctive puzzles.

From:
David Green
Date:
February 9, 2005 17:05
Subject:
Re: Junctive puzzles.
Message ID:
david.green-EA6067.18051109022005@x6.develooper.com
```In article <20050208160048.GA18159@navi.cx>, luke@luqui.org (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
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.

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

```