HaloO,

Richard Hainsworth wrote:
( $a <= any(-1,+1) && any(-1,+1) <= $b )    (*****A****)
[..]
      $tmp = any(-1,+1);
      $a <= $tmp && $tmp <= $b (*****B*****)

Quite how the lines I have labelled (****A****) and (*****B*****) are
different, I do not understand. Unless wrapping a junction in a variable
produces a different result.

That was my initial reaction as well.  A closer examination of
Martin's message indicates that he tends to think that hitting a
junction ought to thread the entire program throughout the rest of the
lifespan of said junction, so that (e.g.) the thread that runs the
comparison "$a <= -1" in (*****B*****) is the same thread that runs
the comparison "-1 <= $b".  OTOH, since (*****A*****) spells out two
separate junctions, it would thread each one separately; resulting in
four threads being used to resolve the expression.  In theory, at
least; in practice, he's looking for ways to simulate such threading
without actually having to mess with all of the overhead that a
literal implementation thereof would entail.

I like to throw in that junctions are value types. That is the two
literal junctions in (*****A*****) are one and the same object and hence
the global auto-threading should be the same as with an explicit
variable. I like the idea of global auto-threading because it matches
the behavior of the unitary state changes of quantum systems. That is
it is the individual states that interact in a non-entangled fashion
as part of a larger ensemble of execution paths ala Feynman. Just as
in quantum mechanics there are collapse points of junctions in boolean
context e.g. in an if statement. But if we define that && is not
collapsing than it becomes part of a scope that a junction auto-threads
through. Note that the collapse points are statically known from the
structure of the source code! Literal junctions within this stretch of
code need to be assembled as implicit parameters of the code block that
implements the conditional of an if block. With the parameters upfront
it is unimportant if the runtime systems starts multiple threads or
iterates the junction sequentially. But a lightweight thread
implementation boosts performance, of course.

An important thing that has to go into the spec is how side-effective
code is handled in conditionals. E.g.

   if $x.foo < $x.bar < $x.baz {...}

first of all is specced to evaluate $x.bar only ones. But is it also
specced that the three calls are evaluated left to right such that .foo
can influence .bar? Also the $x.baz can be short circuited.

The point I want to make is that in quantum computation a NOT gate
*does* flip the individual value of the entangled states of a qubit.
That is !any(0,1) becomes any(1,0) in such a way that it knows which
0 has become 1 and vice versa for as long as the scope of the junction runs. As of now this negation in Perl 6 is a no-op! And we should stop
to compare the current junctions to quantum superposition!

Other equivalences should hold as well. E.g. if one expands $x ^ $y
to (!$x && $y) || ($x && !$y) it should result in the same program
behavior irrespective of $x or $y being junctions.


In both cases, the problem arises when you apply a predicate to a
junction, and then use the junction within code that only gets
executed according to the truth of the predicate.

This implies that junctions also thread through the controlled block
of an if. I hope that my assertion that structural analysis of the code
suffices to define the points where the auto-threads are re-assembled
into a junction still holds in this case.


What I'm hearing is that a decision has already been made on this
matter, so we're stuck with it no matter how counterintuitive the
results of that decision are.

You mean the decision that junction is now a native type with
a private .eigenstates method? I think that is reasonable. The
nativeness of the type is reflected in the fact that the junctive
behavior becomes a structural property of the code. That is the
junction as such has no magic. This magic is in the compiler!
The junction as a native type is a simple list of values.

The above to me implies BTW some finer control for signatures
to specify what kind of junction they allow. E.g. :(Int $)
auto-threads from the outside, :(Object $) passes a junction
without auto-threading. But is :(junction of Int $) the right
way to say that you want to deal with any(1,2,3) but not
any('a','b','c')?


That means that:

   0 <= -1 | +1 <= 0


which is true, because using standard chaining semantics we have
0 <= -1|1 and -1|1 <= 0

No, there should be an outer scope that is in charge of auto-threading
the junction through which was created by the compiler from the -1|+1
even though it sits in the middle of the conditional. I would call that
junction propagation.



Since the first condition is true (+1 >= 0) and the second condition is true
(-1 <=0), the compound is true.
Why you might want such a condition, I dont know. But that is the way
junctions are designed to work.

Hmm, I think we have to think auto-threading semantics through some
more.


Right now, yes.  I'm arguing that the way that they're designed to
work doesn't DWIM.  Try a slightly different example:

   0 <= $x <= 1 # 0 is less than $x is less than 1.
   $x ~~ 0..1 # $x is in the range of 0 to 1.

I submit that most people would expect these two statements to be
conceptually equivalent to each other: they may go about tackling the
issue from different angles, but they should always end up reaching
the same conclusion.  But as things stand now, if $x = -2 | 2, these
result in two very different conclusions: the first evaluates as true,
the second as false.  This most certainly doesn't do what I mean until
I have been indoctrinated into the intricacies of Perl and learned to
think like it does - which runs directly counter to the principle of
DWIM.

I fully agree. There should be equivalence tests of the above sort
in the test spec.


Yes.  And my answer is that the desired meaning of "0 <= -1 | +1 <= 0"
is closer to "(0 <= -1 <= 0) or (0 <= +1 <= 0)" than it is to "(0 <=
-1 or 0 <= +1) and (-1 <= 0 or +1 <= 0)".  The trick is to figure out
how to get this result without needing a nightmarish amount of
overhead to do it.

A structural analysis of the code that generates an auto-threading
point before "0 <= -1 | +1 <= 0" and an assembly point after it
should result in any(False,False) which is false.


Regards TSa.
--

"The unavoidable price of reliability is simplicity" -- C.A.R. Hoare
"Simplicity does not precede complexity, but follows it." -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan

Reply via email to