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

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?


        sub anything_is_broken($subject) {
            grep { ! .test() } $subject.parts()

        if anything_is_broken($subject) {
        else {


        sub everything_is_working($subject) {
            ! grep { ! .test() } $subject.parts()

        if everything_is_working($subject) {
        else {

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

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.


Reply via email to