develooper Front page | perl.perl6.language | Postings from March 2005

Re: Junctions - feedback and desires

Thread Previous | Thread Next
Rod Adams
March 10, 2005 15:20
Re: Junctions - feedback and desires
Message ID:
Sam Vilain wrote:

> Rod Adams wrote:
>> I do not believe that is possible.
>> This is the "filtering" or "unification" behavior that people keep 
>> wanting junctions to have, which they do not.
> Aww!  But what about all the great problems that could be expressed
> with them?  I know of two languages that consider this to be a core
> feature now (Prolog, Oz[1]).

I'm not disputing that it would be powerful. I'm simply saying that as 
currently defined, junctions do not behave in this fashion. It also does 
not make a lot of sense to filter out restricting values in a none() 

And as one who recently proposed a way of getting Prolog like features 
in Perl (through Rules, not Junctions), I understand the appeal 
completely. Junctions are not the way to that goal. They are something 

>> A given junction always has all of the values it was made with. No 
>> more, no less. If you want something else, you have to make a new 
>> junction. Consider that it's been decided that :
>>    $j = 11|0;
>>    10 < $j < 1
>> Is true. $j retains the 0 even after the 0 failed a test.
> I can't see how this can be possible with the possibility of
> autothreading as described in [2].

because it gets interpreted as:

    10 < $j < 1
    --> (10 < $j) && ($j < 1)
    --> (10 < any(0, 11)) && (any(0, 11) < 1)
    --> any(10 < 0, 10 < 11) && any(0 < 1, 11 < 1)
    --> any(false, true) && any(true, false)
    --> true && true
    --> true.

> Maybe the example you suggest is
> true, if both comparisons happen "simultaneously", but what about this
> one?
> if ($j < 10) {
>     if ($j < 1) {
>         say "$j took on two values at once";
>     }
> }

The C<say> would occur, even with the first condition as C< $j > 10 >, 
as you likely intended it to be.
Taking multiple values at once is what junctions are all about.

People seem to forget the role the predicate plays in junction 
evaluation. You thread over the different values, gain a result, and 
then use the predicate to recombine the results into a single scalar.

If instead I had said:
    $j = 11 & 0;
    10 < $j < 1

it would be false, because C< all( true, false) > is false.

$j itself never changes. It is always a collection of values with a 
predicate. If you wish to have a junction with different values in it, 
you have to create a new one.

> Let's say that the implementation chose to implement the first if() by
> auto-threading.  The first thread where $j == 11 succeeds.  The second,
> where $j == 1 fails.  In the second thread, $j == 11 fails.

Except that the threadings are indendent of each other.

    $j = any(0,11);
    $j != $j;

is true.

    $j != $j
    --> any(0,11) != any(0,11)
    --> any(0 != any(0,11), 11 != any(0,11))
    --> any(any(0 != 0, 0 != 11), any(11 != 0, 11 != 11))
    --> any(any(false, true), any(true, false))
    --> any(true, true)
    --> true

    $j = all(0,11);
    $j == $j;

is false.

> It is by this assumption that the example in [3] was built.

That assumption is in err, and the example does not generate the 
solutions desired
See my response to it in

> But wait, isn't (10 < $j < 1) likely to produce the same opcode tree
> as if($j<10){if($j<1){}} ?

    if 10 < $j < 1 { ... }
    if 10 < $j { if $j < 1 { ... }}

Could easily wind up with the same opcodes. Unless the optimizer saw 
something in the first one where it could prove C< $j < 1 > is false.

> > As for the "current" value, there is only a current value during
> > threading.
> Isn't the threading conceptual, and actual threading invoked only when
> the optimiser has finished using available logic / set theory operations
> to prevent absurd numbers of threads being made that exit immediately?

The optimizer can skip threading over values that it can prove will not 
affect the outcome. That's short circuiting.

But asking the optimizer to know in advance what is absurd is a tall order.
Even without junctions, someone could make $j an object with an 
overloaded set of compare operators against Num. And there's no way for 
the compiler to know if those operators are consistent and transitive. 
(One could hope they were, but you never know).

I would not call the threading conceptual. It's a very real thing.

> 2.
> Some contexts, such as boolean contexts, have special rules for dealing
> with junctions. In any scalar context not expecting a junction of values,
> a junction produces automatic parallelization of the algorithm. In
> particular, if a junction is used as an argument to any routine 
> (operator,
> closure, method, etc.), and the scalar parameter you are attempting to
> bind the argument to is inconsistent with the Junction type, that
> routine is "autothreaded", meaning the routine will be called
> automatically as many times as necessary to process the individual scalar
> elements of the junction in parallel.

In the cases above, the routine being threaded over is the comparison 
operator, not the surrounding code block that contains it.

-- Rod Adams

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About