Damian Conway wrote:

Rod Adams wrote:

Is this new, or yet another important detail I missed along the way? Or is this a side effect of not being able to store a Junction, and can go away if C< use Junctions > is turned on?


Yes, it's a side-effect of the new default prohibition on junction assignments (though I'm still working hard to convince everyone that that prohibition cripples junctions and that having to <use junctions> before you can assign a basic Perl 6 scalar datatype to a variable is an abomination).

FWIW, I agree with you that having something half enabled by default make little sense. But I'll accept it as a stop gap until I get my explicit threading.


And I really don't like the implications of how turning on "use junctions" can also suddenly change the threading semantics of junctions. Talk about subtleties in action...

I imagine some intermediate level programmer decides they are ready to start playing with stored junctions. He adds a "use junctions;" at the top of his file, thus turning it on for all functions written in that package. Suddenly, some of his function calls with stop implicitly threading, and instead start carping in some truly spectacular ways. Said programmer quickly takes away the "use junctions;", and never considers using stored junctions again. It's just not worth the trouble, in his mind.

If, however, he was conditioned to put in some »«'s whenever he wanted his junctions to thread, he would not encounter this problem.


I will, however, question if this is optimal. Compare two simple cases:

> C< $x == any(4,5,6) > and C< $x < all(4,5,6) >. Both of them are prime
> candidates to some optimizations, but the optimizations are likely rather different.
> If we pass the junction into the operator, then it can perform some custom tailored code,
> to make things much more efficient, instead of relying on a more generalized junction


optimizer to handle things.


Sure. That's why we have the ability to specify subroutines where junctive args are *not* autothreaded, by typing the corresponding parameter as taking a junction:

    multi sub infix:«==» (YourType $x, Junction $y) is symmetrical {...}
    multi sub infix:«<»  (YourType $x, Junction $y) is symmetrical {...}

These two multisubs can optimize for junctive arguments to their hearts' content.

I guess I misunderstood your statement of "literal junctions *will* autothread in all circumstances" to mean _all_ circumstances, not just ones where the callee didn't explicitly say they could accept them, or if the current "use junctions;" status is in alignment with the moon, or other such things.


I will allow you to alter that statement if you now find it insufficiently qualified.


I don't see that Patrick's response implies that at all. In fact, I think his statement that:


   >> Well, the ultimate answer is that both Dan and Patrick (and others)
   >> will negotiate the exact interface when we get to that point, and
   >> that we don't seem to be too concerned about it at the moment.
   >> (It could just be that we're both burying our heads in the sand
   >> hoping it'll be magically "solved" by the other.  :-)
   >>
   >> However, in working out these examples I'm fairly comfortable that
   >> it can be made to work at the Perl 6 compiler level if need be,
   >> although it will probably be a lot more efficient if we can find a
   >> way to do it within Parrot.

seems to confirm that detecting and reporting autothreaded side-effects is entirely possible.

Let me attempt to clarify the discrepancy as I see it.

I'll take Damian's recent comment of: " And if C< is_prime($x) > does happen to autothread when you weren't expecting it to, then one of two things will happen. Either the subroutine will be 'pure' in which case there's no problem in autothreading it; or else the subroutine will have side effects, in which case you'll get an explicit warning when the autothreading occurs. "

and my 19210 code of:

   $x = 3|4;
   $y = fun($x);
   sub fun ($x) {
       warn "enter: fun($x)\n" if $DEBUG;
       $x + 1;
   }

I hope it's clear that whether or not fun() has side effects is a runtime decision, and can't realistically be determined at function call time.
Now, let's assume that this falls under Damian's heading of "happens to autothread when I wasn't expecting it to."
If $DEBUG is off, no worries.
If $DEBUG is on, I expect my explicit warning, as promised.


What I am questioning is how perl decides when to give my warning. Does perl inspect fun() to see if there are any side effect causing calls in it? Or does it keep an internal note to itself saying "I'm autothreading. This class of functions is Bad.", and then when it encounters one of those functions, carp?

Now throw in a quote from Patrick (19212): "As you've written things above, C<fun> is autothreaded (your option #3), and we'll see two C<warn> output lines if $DEBUG is set."

Somehow, that's not the kind of "explicit warning" I was expecting from Damian's comment.



As for the references to pure-Parrot issue, no I did not previously supply any supporting code, but it was an extension of the issue above.

   $x = 3|4;
   $y = fun($x);
   sub fun ($x) {
       some_parrot_func($x);
       $x + 1;
   }

I can't write the supporting Parrot code, but suffice it to say that at this point in time, we do not know if some_parrot_func() has side effects or not, so we don't know if we should continue autothreading, or carp.


This is at least the second time Damian has implied that autothreading bombs out with output or other side effects (xref 19179). But the way I see it, determining if a given call has side effects or not is on par with the Halting Problem. You don't know until you try it. And with Parrot in the mix, it becomes even harder, since I doubt perl will be able to monitor whether or not there are any side effects of merit inside a given Python routine. But if Patrick, Dan, and their merry pack of helpers tell me they are confident in their ability to solve this problem, I'll trust them. I just want agreement that we are looking at the same problem before I accept it.




The programmer making the call, however, generally has a very good idea about the possible side effects, and can make a much better decision about it what is needed, and can express it with the simple presence or absence of »«.


This problem goes away completely with explicit autothreading. perl would no longer be making assumptions about what to autothread, and what to carp over.


But that's the whole point of junctions! Namely that perl works it out for you. If you don't want that to happen then don't use junctions (and don't allow them to be used, by specifying C<no junctions>).

I was thinking that the whole point of junctions was to superimpose several values onto a single variable. Without threading, junctions are meaningless, I'll give you that.


But I fail to see how trivially declared explicit threading vs implicit threading is found to be crippling to the concept. I invite you to convince me otherwise.

I see that adding the »« is my telling perl to "go work this junction out for me", not putting it in is telling perl "hold off on working this junction out for now... I want you to thread it later."


But I still don't like implicit autothreading, and likely never will. I don't know how to explain it, but it just feels very wrong. It's down there with using typeglobs to pass filehandles, which is thankfully history.


I understand your qualms, even if you can't nail down the exactly reasons for them.

However, I still disagree with them. I truly believe that junctions (including their autothreading behaviour) ought to be core to Perl 6...and not ham-strung in any way.

I concur that junctions in all their glory should be core to Perl 6, except implicit threading.


And it's not that I don't want junctions. I do want them. I just don't want implicit threading, and have yet to be convinced that it is essential to the concept.



if any is_prime«(@x) {...} # Explicitly threaded

Very cool, except it doesn't appear to cover the case of:

   if is_sqrt_of(»any(@x)«,@y) {...}

Or did Perl sneak currying in when I wasn't looking?

   if any (is_sqrt_of«(@x))(@y) {...}

I don't recall seeing anything like that, and I don't think it would work very well if it was.


Simply put,

I want my junctions.
I want my hyper operator superstrength arrays.
I want them both at the same time.
I never want to see implicit threading. Ever.




Reply via email to