Luke Palmer wrote:

Rod Adams writes:


Junctions are intended to be used mainly within conditionals and other
statements;



If the set of these "other statements" is limited, consider creating a
Junction class (which needs a "use Junction;" to activate), which
overloads the various comparison operators for when a Junction is
involved, and defines any/all/none/one as constructors? Throw in some
overloading or bindings for |/^/&, and it looks like you get
everything your asking for. Having a method evaluate: C< 5 ==
any(4,5,6) > means that the interpreter doesn't need to autothread.
This also makes it where only functions that were explicitly designed
to use Junctions, or ones which didn't declare their signature, and
thus are making no assumptions about what they are given, will perform
the Junctive evaluations.



Okay, I think your proposal is thinning.

I'm trying to salvage what I can, since people seem to be rejecting everything I offer.

Perl is a dynamically typed
language. I have no doubts that people will continue to ignore the type
system even though it's there. I probably will.


So will I.

Let me demonstrate something:

   sub is_prime($x) {
       my @primes;
       for 2..sqrt($x) {
           if $_ % none(@primes) == 0 {
               push @primes, $_;
           }
       }
       return 1 if $x % none(@primes) == 0;
   }

Run through your mind how this would be done with a junction in $x.
Particularly focus on:

   2..sqrt($x)

What the hell does that mean? Do you get a junction of lists out? Or
does sqrt die because it's not expecting a junction?


What on earth does C< for (2..sqrt(3|5)) {...} > mean in the current state of junctions?

But as written, yes, sqrt() would likely throw an exception under my proposal.

When I say:

   if is_prime(any(@stuff)) {...}

I expect to run the codeblock if any of my stuff is prime. Instead I
get an error, always. I could always do this:
if @stuff.grep:{ is_prime($_) } {...}


Should also be able to overload   Junction ~~ CodeRef  to make this work:

   if any(@stuff) ~~ &is_prime {...}

In this manner, you are explicitly controlling when and how the autothreading happens. There is no way for is_prime to slurp up the junction and pass it on in this case.

However, in the current scheme, if is_prime() is written to accept a slurpy list of parameters (either by design, or just a habit from the P5 days), we can have:

   sub is_prime {
       my @primes;
       for 2..sqrt(@_[0]) {
           if $_ % none(@primes) == 0 {
               push @primes, $_;
           }
       }
       return 1 if $x % none(@primes) == 0;
   }

Pushing the autothreading directly onto the C< for (2..sqrt(3|5)) {...} >, which as you pointed out earlier, is almost definitely _not_ what was wanted, whatever it means. (btw, My current analysis says it will stop at the lowest value in the junction.)

I view it as a definite plus to make the autothreading explicit. I doesn't need it to be ugly, just present.


In fact, that's all I need to shut up on this whole issue.

Something that says: "autothreading into functions only happens when you slap (whatever) in there."
I can live with auto-autothreading over operators (I'd rather not, though). But calling into a function needs something stronger. Yes, operators are functions, too, but if you're fancy enough to be writing you're own operators, you're fancy enough to take junctions into account.


Something like:

   if is_prime(Âany(@stuff)Â) {...}

Would more than suffice. It says that you're not attempting to pass the junction, but instead doing something in parallel, which is what the hyper operators are all about, anyways.

It's been the side effects of autothreading that has been my big hold up. If you make it happen explicitly, it's just another looping construct ( a very odd one, but one nonetheless ). If it happens implicitly, it's way too magical and dangerous for my tastes. Give me that, and I'll probably start liking Junctions. I've never argued that they weren't powerful.

But the whole point of junctions is to get rid of obscure expressions
like that.  Brent makes a fantastic case here.

The point is that when you say "makes no assumptions", you're giving the
sub writers too much credit.  I think a reasonable assumption
(especially for these alledged "novices" you keep talking about) that
these two code segments are equivalent:

   if $x == 2 {...}
   elsif $x == 3 {...}

And:

   if $x == 2 {...}
   if $x == 3 {...}

No matter what the value of $x.

Yet in the presence of junctions, they are not. Also note that this is
a practical example. I like the former, I know people who like the
latter. It's a matter of style, and it's one that will bite you if you
don't know about junctions.


You get into this problem when you allow any form of overloading of built in operators, not just with junctions. It'd be trivial to create an AlwaysTrue class, which overloads all forms of comparison against it to always return true. The utility of such a class is left as an exercise to the reader.

I am most specifically _not_ suggesting getting rid of operator overloads. Just implicit autothreading.

So what's it going to be? Avoiding the evil side of autothreading, or
not crippling the usefulness of junctions in the presence of unwary
code? It is a trade-off indeed.


I strongly suspect there is a middle ground to be had.

-- Rod Adams





Reply via email to