Re: Tweaking junctions

2010-11-01 Thread Moritz Lenz
On 10/22/2010 06:16 AM, Damian Conway wrote:
 That is, a C$value is an eigenstate of a C$junction if-and-only-if:
 
 $value !~~ Junction$value ~~ $junction

In general this definition makes it impossible to return a list of
eigenstates from the junction. Just think of junctions containing Code
objects. Or anything more complicated than the built-in value types.

 But the C!eigenstates method (as currently defined) does not return
 a list of such eigenstates. Instead it merely returns a partially-flattened
 list of the raw internal values of the junction...which is not (usually) the
 same thing at all.

Right; but afaict it's the only thing that can actually be implemented.
And because it doesn't make all too much sense, it's specced to be private.



Re: Tweaking junctions

2010-11-01 Thread Damian Conway
Moritz wrote:

     $value !~~ Junction    $value ~~ $junction

 In general this definition makes it impossible to return a list of
 eigenstates from the junction. Just think of junctions containing Code
 objects.

Well, that's a deficiency in smartmatching: that Callable ~~ Code doesn't
check for identity between the two objects. Likewise the Regex ~~ Regex
doesn't check for identity. Likewise Range ~~ Range testing for identical
endpoints. Etc. ;-)

The definition of eigenvalues() is supposed to be abstractly
descriptive, not specifically constructive. The idea is simply: any
leaf state inside the junction to which the junction could collapse.

Now the implementation I already provided does currently rely on
smartmatching, but that will be fixed pronto, now that you've kindly
pointed out that smartmatching is...well...broken on several interesting
types of states. :-)


 Right; but afaict it's the only thing that can actually be implemented.
 And because it doesn't make all too much sense, it's specced to be private.

Fine. But please change the name anyway.

If we all agree it's not returning eigenstates, and some of us believe it
*can't* every return eigenstates, then it certainly shouldn't be called
C.eigenstates.

Damian


Re: Tweaking junctions

2010-11-01 Thread Moritz Lenz


On 11/01/2010 12:41 PM, Damian Conway wrote:
 Moritz wrote:
 
 $value !~~ Junction$value ~~ $junction

 In general this definition makes it impossible to return a list of
 eigenstates from the junction. Just think of junctions containing Code
 objects.
 
 Well, that's a deficiency in smartmatching: that Callable ~~ Code doesn't
 check for identity between the two objects. Likewise the Regex ~~ Regex
 doesn't check for identity. Likewise Range ~~ Range testing for identical
 endpoints. Etc. ;-)

Sorry, I disagree. It's exactly what smartmatching was designed to be.
If you don't want that kind of behaviour, use infix:eqv or infix:===
instead.

 The definition of eigenvalues() is supposed to be abstractly
 descriptive, not specifically constructive. The idea is simply: any
 leaf state inside the junction to which the junction could collapse.

Junctions only collapse to Bool::True or Bool::False.

So an attempt to fix your definition could be

'any leaf state inside the junction, which makes the junction collapse
to True if compared to the junction as a whole'

but begs for a more concrete comparison rule. For which, IMHO
smartmatching would be nice, since I mostly use junctions for
smartmatching. Which brings us into the dilemma I mentioned before.


 Right; but afaict it's the only thing that can actually be implemented.
 And because it doesn't make all too much sense, it's specced to be private.
 
 Fine. But please change the name anyway.
 
 If we all agree it's not returning eigenstates, and some of us believe it
 *can't* every return eigenstates, then it certainly shouldn't be called
 C.eigenstates.

Agreed.

Cheers,
Moritz


Re: Tweaking junctions

2010-11-01 Thread Moritz Lenz
Food for thought, a few non-junction solutions:

On 10/22/2010 06:16 AM, Damian Conway wrote:
 # Find the list of common elements in two lists...
 sub intersection (@list1, @list2) {
 (any(@list1)  any(@list2).eigenstates;
 }

sub intersection(@list1, @list2) {
uniq gather for @list1 X @list2 - $a, $b {
 take $a if $a eqv $b
}
}

or

sub interseection(@list1, @list2) {
   (@list1 X= @list2).grep({ .key eqv .value}).key.uniq
}

Admittedly it's not as declarative, but it's explicit about the
comparison used (which is a plus, in my eyes).

If you want to use eq or ===, hash based solutions come to mind too.

 # Find the factors of a number...
 sub factors (Num $n) {
 ( $n/any(1..$n) ).eigenstates.grep({ $^q.Int == $q });
 }


sub factors($n) {
($n X/ 1..$n).grep: { .Int == $_ }
}

or

sub factors($n) {
   (1..$n).grep: { %n %% $_ }
}

 # Check for an unacceptable password, and list all when warning...
 constant UNACCEPTABLE = any  Godel Escher Bart etc... ;
 
 if $passwd ~~ UNACCEPTABLE {
 say Unacceptable password. Don't use any of these:;
 say UNACCEPTABLE.eigenstates¬».fmt(\t%s\n);
 }

constant UNACCETABLE = Godel Escher Bach;

if $passwd ~~ any UNCACCEPTABLE {
say Unacceptable password. Don't use any of these:;
say UNACCEPTABLE».fmt(\t%s\n);
}


Re: Tweaking junctions

2010-11-01 Thread Buddha Buck
On Mon, Nov 1, 2010 at 7:24 AM, Moritz Lenz mor...@faui2k3.org wrote:
 On 10/22/2010 06:16 AM, Damian Conway wrote:
 That is, a C$value is an eigenstate of a C$junction if-and-only-if:

     $value !~~ Junction    $value ~~ $junction

 In general this definition makes it impossible to return a list of
 eigenstates from the junction. Just think of junctions containing Code
 objects. Or anything more complicated than the built-in value types.

[Originally sent to Moritz alone because of Reply not sending to the list]


Is it too late in this discussion to point out that, in non-perl
usage, eigenstates are associated with the operator, not with the
value fed into the operator?

[Added at Moritz request]

In linear algebra, eigenvectors and eigenvalues are non-trivial
solutions to the equation Ax=λx, where x is a vector in a vector
space, A is a operator (a function from a vector space to itself) and
λ is a member of the field the vector space is defined over.  For a
given operator A, only certain values of λ allow that equation to be
solved, and those values are called the eigenvalues for A.  Also,
for a given operator A, only certain vectors x will solve the
equation, and those vectors are called eigenvectors.  It should also
be clear that different values of λ work with different sets of
vectors x  (the solutions to Ax = ax and Ax=bx are different if a !=
b), so it's typical to talk about the eigenvectors of A associated
with a given eigenvalue λ.

Since A is linear, if Ax=λx  and Ay=λy, then A(ax) = a(Ax) = a(λx) =
λ(ax) and A(x+y)=Ax+Ay=λx+λy=λ(x+y), so fir a given eigenvalue λ,
there are typically multitudes of eigenvectors which form a vector
space of their own.  Eigenvectors for different eigenvalues are
orthogonal, and any eigenvector can be scaled to be a unit
eigenvector.  If an operator has a full set of eigenvalues, one can
pick a set of unit eigenvectors to act as a natural orthonormal basis
for the operator.  If operator A has three eigenvalues a, b, c, and
three unit eigenvectors x, y, z, such that Ax=ax, Ay=by, and Az=cz,
then if w = dx+ey+fz, Aw = a(dx)+b(ey)+c(fz), which is really easy to
compute.

In quantum mechanics, especially the Heisenberg matrix formulation
(but by analogy, also every other formulation, including wave
mechanics), quantum states are represented by vectors in a complex
vector space, and vectors which differ by a real-valued scaling factor
are generally considered equivalent.  Transformations (i.e., anything
which modifies the quantum state of the system, including but not
limited to the passage of time) are represented by (unitary) operators
on the state space.  (Unitary in this case means that the norm of Ax
is the same as the norm of x, for all x.)  The standard notation is a
bit odd, where the 'ket' |x represents a system in state x (and
therefore |x+y a state in a superposition of x and y), The 'bra' x|
is the complement of the ket |x, and can be multiplied by a ket to
get a braket x|y which represents the probability that a system in
state y is also in state x.  |x is, naturally, usually normalized
such that x|x = 1.  Operators act on kets and return kets, so A|x
is the braket notation way of writing the linear algebra Ax.
Naturally, that means that y|A|x is the probability that a system
that starts in state x will be in state y after the transform A.

Since A is a linear operator, it has eigenvalues and eigenvectors.  In
the quantum mechanical world, where vectors represent states, the
eigenvectors are called eigenstates.  Eigenstates |i, |j of an
operator A have the property that i|A|i = j|A|j = 1, but i|A|j =
0 (informally, if you start in an eigenstate of A, then the transform
leaves you unchanged).  However, A|i+j = |ai+bj, so A can change the
nature of a superposition of states.  i|i+j = 1/2, j|i+j = 1/2,
but i|A|i+j = a/(a+b), j|A|i+j = b/(a+b).

Schrodinger's Wave Equation, in matrix notation, is of the form Hx=Ex,
where H is the Hamiltonian operator of the system, and E is the
energy of the system, so the only allowed solutions of the wave
equations are for energy levels E which are eigenvalues of H,and for
quantum states which are eigenstates of H.  Similar equations exist
for virtually every observable, so the only allowable momenta are
the eigenvalues or eigenstates of the momentum operator, the only
allowable positions are the eigenvalues or eigenstates of the position
operator, etc.

So asking for the eigenstates of a quantum superposition is asking the
wrong object for the property.


Re: Tweaking junctions

2010-11-01 Thread Dave Whipp

Buddha Buck wrote:

Is it too late in this discussion to point out that, in non-perl
usage, eigenstates are associated with the operator, not with the
value fed into the operator?

[cut]

So asking for the eigenstates of a quantum superposition is asking the
wrong object for the property.


Probably is, yes :(. I argued the same thing a couple of years back 
(http://dave.whipp.name/sw/perl6/perl6_xmas_2008.html -- wow, p6/rakudo 
has advanced a lot since then!) when I suggested bra-ket notation for 
extracting the values of a junction:


  $player_value = max | 4..21 |==| $player_value_junc |

(in this case, the value of a blackjack hand). Since then, I simplified 
this idea to use a more perl6ish meta-operator:


  $player_value = max 4..21 G== $player_value_junc

My current belief is that it is likely that there'll eventually be 
sufficient core functionality that I'll be able to implement something 
like this as a module. So I don't push it except when someone else 
starts a thread about the values of a junction :).



Dave.


Re: Tweaking junctions

2010-10-29 Thread Martin D Kealey
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
junctions.

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?

A:

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

if anything_is_broken($subject) {
fail($subject)
}
else {
pass($subject)
}

B:

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

if everything_is_working($subject) {
pass($subject)
}
else {
fail($subject)
}

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
DWIM-or-throw-an-exception.

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.

-Martin


Re: Tweaking junctions

2010-10-29 Thread Damian Conway
Martin D Kealey suggested:

 Well, I think returning or throwing an Unordered exception would be
 the appropriate way to handle those, both for complex numbers and for
 junctions.

For complex numbers that might be true, because the order relationship
between two complex numbers isn't expressible in-band.

But for junctions, the relationship of sometimes , somtimes = is
entirely expressible. It's just: any(True, False).


 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()
}


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

 Why should it make a difference whether $subject is a junction?

Because, although the two subroutines seem like they're complementary,
they actually only partition the universe when the universe is strictly
one-dimensional. And sometimes not even then.

For example, here's a *non-junctive* scalar subject for which the two
don't provide consistent answers either:

class Part {
has $.value;
method test { $.value != 0 }
}

class Subject {
has Part @.parts;
method parts { @.parts.pick(2) }
}

my Subject $subject .= new(0..9);

say anything_is_broken($subject);# 0 (because .parts picked 3 and 7)
say everything_is_working($subject); # 0 (because .parts picked 9 and 0)

In other words, it isn't the junctive-ness that creates unexpected
behaviour, it's the assumption that every scalar works the same way.


 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.

But that's not a unique property of junctions; that not obviousness
is equally true of any scalar that, for example, simply overloads .Num
or .Str or .Bool.

For instance:

if $result { say $result }

can easily print 0, which is not obvious, but is still both correct
and useful (when, for example, $result the result of a call to Csystem).


 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*.

But junctions are an intrinsic part of Perl 6. So it's unreasonable to
*not* expect them. And if you want to not expect them, you can just mark
your variables that way, with (ironically):

my $subject where none(Junction);

Besides, are you also going to extend this segregation of junctions to
not allow C0 but true in untyped scalars either? Because how else will
you avoid the non-obviousness of:

 if $result { say $result }

???


 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.

Huh? If the variables are strongly typed as non-junctive, a junction
will never be able sneak past into or out-of an autothreading.


 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.

Aha. I see that we mean different things when we use the term algebraic
consistency. You seem to want all algebras to be universally
consistent; I want each algebra to be internally consistent. Or to put
it another way, you appear to want:

A given operator or function does one consistent thing
(regardless of the specific types of its operands)

whereas I want:

A given operator or function does one thing
(consistent with the specific types of its operands)

In other words, you seem to be arguing for monomorphism, whereas I'm
definitely arguing for polymorphism. Neither is inherently better, but
one is inherently more powerful. While I deeply respect your
position, I'm going to keep arguing for that more powerful alternative.

Damian


Re: Tweaking junctions

2010-10-28 Thread Damian Conway
Martin D Kealey asked:

 Or do we not invert junctions, and run the risk of unexpected
 action-at-a-distance instead?

I think our current approach is correct. That is: we invert
junctions on operators that are themselves intrinsically inverted
(such as !=, !~~, !), but do not invert on those that are not
(such as ==, ~~, =). Or rather, we *never* invert junctions at all, but
merely honour the standard semantics of the prefix:! metaoperator:
hoisting the negation outside the entire operation and applying it
once the underlying operation is complete.

The apparent paradox you demonstrated with the two interpretations of
C$foo  ($bar | $zot) 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.

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.

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. :-)


With regard to your other point:

 If it's about parallel data handling, then we have to be prepared to
 (notionally) fork the entire rest of the runtime, even as far as
 having a definition of what return value the parent process sees (from
 exit) when those threads are implicitly collapsed at termination.

That's certainly true, although junctions are supposed to guarantee
to coalesce all the threads they may generate back into a single superimposed
result back in the originating thread.

The problem only arises if an operation or subroutine that has been
junctively threaded terminates without returning. But that's just
having a side-effect, which we already know is inappropriate for
junctions (and hyperoperators, and autothreaded loops, and pretty much
any other kind of parallel construct).

Damian


Re: Tweaking junctions

2010-10-28 Thread Darren Duncan

Damian Conway wrote:

If it's about parallel data handling, then we have to be prepared to
(notionally) fork the entire rest of the runtime, even as far as
having a definition of what return value the parent process sees (from
exit) when those threads are implicitly collapsed at termination.


That's certainly true, although junctions are supposed to guarantee
to coalesce all the threads they may generate back into a single superimposed
result back in the originating thread.

The problem only arises if an operation or subroutine that has been
junctively threaded terminates without returning. But that's just
having a side-effect, which we already know is inappropriate for
junctions (and hyperoperators, and autothreaded loops, and pretty much
any other kind of parallel construct).


Could thread termination without a return reasonably be treated as another way 
of saying returns nothing or alternately returns an empty junction (a junction 
ranging over zero values)?  Or would that instead better be treated as an error 
such that returning nothing should have been done explicitly? -- Darren Duncan


Re: Tweaking junctions

2010-10-27 Thread Martin D Kealey

I have to admit to feeling uneasy about the whole action-at-a-distance
effect that junctions are capable of producing. They sit around pretending
to be a scalar, only to pop up and wreak havoc with ones expectations of
linearity when you're not expecting it.

That unexpected-action-at-a-distance is somewhat mitigated by autothreading
functions where the junction is presented as a direct parameter, but being
able to defer a junction by putting it inside an aggregate seems like asking
for trouble unless we make sure that it behaves as much like an ordinary
scalar as possible when it does finally get collapsed.

I think we need to decide whether junctions are just about flow control, or
are more generalized parallel data handling, typified as a way of handling
sets.

If it's about parallel data handling, then we have to be prepared to
(notionally) fork the entire rest of the runtime, even as far as having a
definition of what return value the parent process sees (from exit) when
those threads are implicitly collapsed at termination. And deciding what
happens when, in the process of autothreading junction A, you wind up
collapsing junction B in different ways (including perhaps not collapsing
it)? Right now I don't think we're up for all that.

For the sake of flow control, do we have a formal algebra of how we apply
distributive rules so that all the elements of the resulting junction are
booleans and the result of the collapse is obvious?

In the simple cases it's (supposedly) obvious:
$foo == ($bar | $zot)   === ($foo == $bar) | ($foo == $zot)

But what about:
$foo != ($bar | $zot)   === not($foo == ($bar | $zot))
=== not(($foo == $bar) | ($foo == $zot))
=== (not($foo == $bar))  (not($foo == 
$zot))
=== ($foo != $bar)  ($foo != $zot)

Moreover, what about:
$foo  ($bar | $zot)=== ($foo  $bar) | ($foo  $zot)
versus:
$foo  ($bar | $zot)=== not($foo = ($bar | $zot))
=== not(($foo = $bar) | ($foo = $zot))
=== (not($foo = $bar))  (not($foot = 
$zot))
=== ($foo  $bar)  ($foo  $zot)

In short, in order to avoid unexpected action at a distance, it's logical to
invert the junction type, but in doing so you hit some very nasty corner
cases. How do you know whether a function is saying X has property Y or
X does not have property ~Y ? Which of Y or ~Y are we talking about?

It seems fair enough to infer that equality comparison is Y rather than
~Y, but any other sort of comparison is fraught.

This leads me to the conclusion that collapsing a junction over an ordered
comparison should fail in the same way that an ordered comparison involving
complex numbers or vectors should fail (or more generally, an ordered
comparison of any aggregate should fail unless the aggregate type defines some
sensible ordering; there should be no default).

Indeed, the whole notion of autothreading a junction over an arbitrary
function (to produce a boolean that can be used for flow control) starts to
sound fishy: how do we decide whether a given function should be treated
like ==, where the distributive rule produces the same junction type, or
like !=, where the distributive rule produces the inverse junction type?

Or do we not invert junctions, and run the risk of unexpected
action-at-a-distance instead?

-Martin


Re: Tweaking junctions

2010-10-26 Thread Damian Conway
Jon Lang wrote:

 Personally, I don't think that it should be a public method: one thing
 about junctions is that you can use them interchangeably with ordinary
 scalars; giving them a public method breaks that.  In particular, code
 that makes use of a Junction public method would break if you were to
 hand it a non-Junction.

On the other hand, I would argue that, because non-junctive scalars are
just an (uninteresting ;-) special degenerate case of junctions, they
should have a public .eigenvalues() too!  It would, of course, just return
their uninteresting degenerate special-case scalar value.

Alternatively, I would note that Perl 6 already provides a perfectly
good way to handle this issue. If you're calling $someval.eigenvalues(),
you're inherently assuming that you're calling it on a Junction. If
there's any possibility that what you're calling it on *isn't* a
junction, then you should either be unsurprised to get the exception that will
be thrown, or else you should explicitly cater to the possibility with:

 my @values = $val.?eigenvalues;

or perhaps:

 my @values = $val.?eigenvalues // $val;

Although, if that second form is to become the standard safe approach,
that argues to me that non-junctions ought to have a .eigenvalues() too,
so that the first alternative above just DWIMs.


BTW, given Larry's recent clarification about Sets producing a list of
their keys in list context, I have absolutely no objection to
.eigenvalues() returning a Set, rather than a List. Indeed, I think it
would be even more valuable that way.

Damian


Re: Tweaking junctions

2010-10-26 Thread Todd Olson

On 2010-Oct-25, at 15:14, Damian Conway wrote:

 Yes, Ted Z. pointed out to me that, as the name of this construct,
 every has ambiguity and synonym issues. Other possibilities are:
 
select(@values)  one(3..7)
those(@values)  one(3..7)
whichever(@values)  one(3..7)
itemize(@values)  one(3..7)
extract(@values)  one(3..7)
 
 ...of which, only Cselect really seems a good alternative.
 
 Any other suggestions most welcome!

Applying a slightly more stringent test example,
the above terms, plus a few new suggestions,
separates in to two groups

  these work for me

@nv = those(@values)  one(3..7)
@nv = only(@values)  one(3..7)
@nv = solely(@values)  one(3..7)
@nv = exclusively(@values)  one(3..7)
@nv = whichever(@values)  one(3..7)

  these do not work for me

@nv = select(@values)  one(3..7)
@nv = extract(@values)  one(3..7)
@nv = isolate(@values)  one(3..7)
@nv = locate(@values)  one(3..7)
@nv = itemize(@values)  one(3..7)


It is tempting to use

@nv = sift(@values)  one(3..7)
@nv = winnow(@values)  one(3..7)

however, like 'filter' it is confusing what they focus attention on.
Often they focus on what is being discarded
   To winnow the chaff from the grain
yet sometimes they focus on what is being retained
   it's difficult to winnow out the truth
   it's difficult to sift out the truth

I wonder if some times we might desire what is to be discarded,
that is the complement of the outcome this conversation started with.

(@keep, @discard) = filter(@values)  one(3..7)
(@grain, @chaff)  = winnow(@values)  one(3..7)
(@truth, @lies)   = sift(@values)  one(3..7)


Regards,
Todd


Re: Tweaking junctions

2010-10-25 Thread Ben Goldberg
On Oct 22, 6:41 pm, dam...@conway.org (Damian Conway) wrote:
 Dave Whipp wrote:
  When this issue has been raised in the past, the response has been that
  junctions are not really intended to be useful outside of the narrow purpose
  for which they were introduced.

 Hmm. There are intentions, and then there are intentions. I know
 what I intended when I invented the original idea, and it wasn't just the 
 narrow
 purpose for which they were added to Perl 6. :-)

  Problem 2 could be solved by defining a new (and public!)
  C.eigenstates method in the Junction class. [...]

  I think that you're proposed solution is a bit too specific:

 That's because I didn't explain Part B of my nefarious plan! namely
 that, if you'd only give me proper eigenstates, I'd give you an even
 nicer alternative.

 I actually think that the meta doesn't belong on the operator at all
 (though I have no problem with that idea in itself).

 Instead, I think the meta should be placed on the data (which, of
 course, is what any(), all(), one(), and none() already do).

 So I'm going to go on to propose that we create a fifth class of
 Junction: the transjunction, with corresponding keyword Cevery.
[snip]

I'm probably missing something, but wouldn't it have been easier to
write that module by using eval STRING to create all of those infix
operators?

Start with a list of the names of the operators, generate a string
containing all four argument variations for each operator, then eval
it.



Re: Tweaking junctions

2010-10-25 Thread Damian Conway
Ben Goldberg asked:

 I'm probably missing something, but wouldn't it have been easier to
 write that module by using eval STRING to create all of those infix
 operators?

Sure. But the module is already slow to start up. I was concerned
that it would get even slower with an embedded eval. But, in the
name of maintainability, I probably should benchmark it both ways.

Thanks for pointing that out, Ben.

Damian


Re: Tweaking junctions

2010-10-25 Thread Dave Whipp

Damian Conway wrote:


So I'm going to go on to propose that we create a fifth class of
Junction: the transjunction, with corresponding keyword Cevery.

[...]

say (^10 G[] one(3,7));

3 4 5 6


which could also be:

say every(^10)  one(3,7);
# Every value up to 10 that's greater than 3 or 7 but not both

[...]

I just think those all read much better than the (otherwise excellent)
meta-operator. In much the same way that the existing junctive types
read better than their functional or operator-oriented alternatives.


I think that the two proposals are equivalent, in the sense that either 
can be trivially implemented using the other. So it is indeed a question 
of which one reads better and fits in better. And I agree, your Cevery 
proposal does read better (at least to an English speaker).


However, I am a little concerned that the transjunction magically 
changes an operator that returns a Boolean value into one that returns a 
list. If the usage of a transjuction is non-local to its creation then 
this could result in surprises, and hence frustrating debugging sessions.


If I wanted to write intentionally confusing code (which sometimes 
happens due to carelessness) then I might take advantage of the fact 
that Cevery is, in English, a synonym for Call, not Cany:


  if every(@values)  one(3..7) {...}




I'd like these in the core language (for performance and universal
accessibility), but if not, I already have a nearly-complete
implementation of a module implementing them, which runs successfully on
the current release of Rakudo*. I append said model for your amusement
(and suggestions!).


++

Dave.


Re: Tweaking junctions

2010-10-25 Thread Damian Conway
Dave Whipp noted:

 I think that the two proposals are equivalent, in the sense that either can
 be trivially implemented using the other.

Agreed.


 However, I am a little concerned that the transjunction magically changes
 an operator that returns a Boolean value into one that returns a list.

Technically, it turns the operator into one that returns a transjunction.

The surprise occurs because tranjunctions self-eigenvalue in a list context.
That's a huge convenience in direct usages, but not an essential component
of the proposal if indeed it proves too surprising in indirect usages.

However, if we did lose that feature then usages like:

say eigenvalues every(@number)  one(3,7);

sacrifices more than a little of the construct's original appeal, I think.


 If I wanted to write intentionally confusing code (which sometimes happens
 due to carelessness) then I might take advantage of the fact that Cevery
 is, in English, a synonym for Call, not Cany:

  if every(@values)  one(3..7) {...}

Yes, Ted Z. pointed out to me that, as the name of this construct,
every has ambiguity and synonym issues. Other possibilities are:

select(@values)  one(3..7)
those(@values)  one(3..7)
whichever(@values)  one(3..7)
itemize(@values)  one(3..7)
extract(@values)  one(3..7)

...of which, only Cselect really seems a good alternative.

Any other suggestions most welcome!

Damian


Re: Tweaking junctions

2010-10-25 Thread Dave Whipp

Damian Conway wrote:


Yes, Ted Z. pointed out to me that, as the name of this construct,
every has ambiguity and synonym issues. Other possibilities are:

select(@values)  one(3..7)
those(@values)  one(3..7)
whichever(@values)  one(3..7)
itemize(@values)  one(3..7)
extract(@values)  one(3..7)

...of which, only Cselect really seems a good alternative.

Any other suggestions most welcome!


My suggestion is, of course, to move it to the operator:

  @values G one(3..7)

which has a pleasing (to my mind) symmetry with Perl6-isms such as

  @values X* 2


Failing that, perhaps Cfilter might work (though I always find myself 
wanting to qualify a filter as either filter-in or filter-out).


Re: Tweaking junctions

2010-10-23 Thread Brandon S Allbery KF8NH
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

On 10/22/10 13:00 , Dave Whipp wrote:
 Damian Conway wrote:
 I've been thinking about junctions, and I believe we may need a small
 tweak to (at least) the jargon in one part of the specification.
 
 When this issue has been raised in the past, the response has been that
 junctions are not really intended to be useful outside of the narrow purpose
 for which they were introduced.

It occurs to me:  If their purpose is that narrow, why are they wasting
conceptual space in the core language?

- -- 
brandon s. allbery [linux,solaris,freebsd,perl]  allb...@kf8nh.com
system administrator  [openafs,heimdal,too many hats]  allb...@ece.cmu.edu
electrical and computer engineering, carnegie mellon university  KF8NH
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.10 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkzC5gsACgkQIn7hlCsL25Wp8ACbBzcg2kACC/hmtTD1GUGe2lD2
2ucAmgNSPb5F6T3SqqHMvvG7UzFR9M3D
=1x5F
-END PGP SIGNATURE-


Re: Tweaking junctions

2010-10-23 Thread Damian Conway
Brandon mused:

 It occurs to me:  If their purpose is that narrow, why are they wasting
 conceptual space in the core language?

Well, mainly because their purpose isn't narrow at all: it's parallelized data
comparisons (all(@values)  $threshold), and multiway comparisons
(all(@values) ~~ any(@ranges)), and distributed sub calls on a
set of arguments (foo(any @alternatives), and subroutine call
parallelism (foo  bar)($arg), and type unions (my Wax|Polish $shimmer),
and type intersections (my $coefficient where Num  0..1), and parallel
lookup of arrays and hashes ($name ~~ %known_aliases{any $suspect}),
and multiway existence checks (if any %f...@args} :exists), and
convenient multiple file tests ($fh ~~ :r  :w  :!x), and overlapping
or exhaustive matches (my $results = m:ex/foo/), and complex matching
logic expressed declaratively (my $is_valid = Num  {$_0} | Str  /zero|one/).

And, of course, they're in the core because there's no point in having
that much power and usefulness if it's not fast too.

Damian


Re: Tweaking junctions

2010-10-23 Thread yary
In general I like where this is going but need a little hand holding
here- I'm not an expert on junctions or anything perl6-

 So I'm going to go on to propose that we create a fifth class of
 Junction: the transjunction, with corresponding keyword Cevery.

It seems that by these definitions every isn't quite a junction-

every(@list)  comparision-op  value
to mean ...
   grep  * comparision-op value,  @list;

You'll need to specify but not necessarily in the same order if you
want junctive autothreading to work on every as it does with other
junctions. In which case it should probably be returning a junction
and not an ordered list.

Which reminds me, .eigenvalues strictly speaking is a set and not a
list. !eigenstates can be whatever the internal representation is...
not that I've checked the synopsis on that...

And while I like the cleanliness of the every expressions I'm still
having trouble seeing why every should behave differently from
any, all. Maybe every isn't a junction? Maybe junctions in
general need to behave a little differently when being compared
against then they do now, so the need for every goes away?


Re: Tweaking junctions

2010-10-23 Thread Damian Conway
 In general I like where this is going but need a little hand holding
 here- I'm not an expert on junctions or anything perl6-

 So I'm going to go on to propose that we create a fifth class of
 Junction: the transjunction, with corresponding keyword Cevery.

 It seems that by these definitions every isn't quite a junction-

It's an unordered collection of values that can be used like a single
value, is parallelizable, and has an intrinsic associated operation.
That's pretty much a junction. The only difference is that the
associated operation is (in a sense) Cgrep, rather than C,
C||, C^^, or C!


 You'll need to specify but not necessarily in the same order if you
 want junctive autothreading to work on every as it does with other
 junctions.

You're quite right. I should have been more specific about that.
And, yes, I certainly do want to leave open the potential for parallel
evaluation.


 In which case it should probably be returning a junction
 and not an ordered list.

If you look at the implementation I appended, any comparison
on a transjunction returns a transjunction. But it turns out to be
much more useful if they also collapse to a list, which is why I
implemented them as a role added to arrays/lists.


 Which reminds me, .eigenvalues strictly speaking is a set and not a
 list.

Sure, but again, it's much more useful as a list. ;-)


 And while I like the cleanliness of the every expressions I'm still
 having trouble seeing why every should behave differently from
 any, all. Maybe every isn't a junction?

Maybe not, in the strictest sense. But it has many of the same characteristics
and is extremely useful in many of the same kinds of ways as a duck^Wjunction.


 Maybe junctions in general need to behave a little differently when
 being compared against then they do now, so the need for every
 goes away?

Interestingly, that was how they were originally defined (back when they
were called Quantum::Superpositions). Comparing a superposition
produced a superposition of just those values for which the comparison
was true.

But I agree with Larry's decision to make junctions behave normally wrt
comparisons. They're much easier to understand the way they are now.

I am merely trying to reintroduce the useful extra concept of a
collection of numbers that filters under comparisons. But if people
aren't comfortable, I'm happy to leave it as a module (especially since
it's already written).

I would hate this (very worthwhile) discussion to distract from the key
point of the original post: namely, that the private C!eigenstates is
misnamed, and a public C.eigenvalues is missing.

Damian


Re: Tweaking junctions

2010-10-22 Thread Dave Whipp

Damian Conway wrote:

I've been thinking about junctions, and I believe we may need a small
tweak to (at least) the jargon in one part of the specification.


When this issue has been raised in the past, the response has been that 
junctions are not really intended to be useful outside of the narrow 
purpose for which they were introduced.



Problem 2 could be solved by defining a new (and public!)
C.eigenstates method in the Junction class. [...]


I think that you're proposed solution is a bit too specific: it assumes 
that when you say eigenstates, what you really mean is the set of 
values that would compare equal to. I have no problem with that 
concept, expect that I think that it would be better realized as a 
meta-operator -- I previously proposed G[op] as that operator (G for 
grep) -- to reinforce the idea that you only get to peer into a junction 
if you state the operator.


 sub factors (Num $n) {
 ( $n/any(1..$n) ).eigenstates.grep({ $^q.Int == $q });
 }

could be:

sub factors (num $n) { ^$n G[==] $n/any(1..$n) }


if $passwd ~~ UNACCEPTABLE {
say Unacceptable password. Don't use any of these:;
say UNACCEPTABLE.eigenstates¬».fmt(\t%s\n);
}


Could be

  if $passwd ~~ UNACCEPTABLE {
  say Unacceptable password. Don't use any of these:;
  say (::Str G[eq] UNACCEPTABLE)».fmt(\t%s\n)
  }

And, of course:

  method eigenstates( Junction $v : ) {
::Any G=== $v
  }

Operations other than equality could be used:

say (^10 G[] one(3,7));
 3 4 5 6



I suggest a meta-op instead of simply using the grep method to 
strongly imply that the implementation would need to be analytic in nature.


Re: Tweaking junctions

2010-10-22 Thread Damian Conway
Dave Whipp wrote:

 When this issue has been raised in the past, the response has been that
 junctions are not really intended to be useful outside of the narrow purpose
 for which they were introduced.

Hmm. There are intentions, and then there are intentions. I know
what I intended when I invented the original idea, and it wasn't just the narrow
purpose for which they were added to Perl 6. :-)


 Problem 2 could be solved by defining a new (and public!)
 C.eigenstates method in the Junction class. [...]

 I think that you're proposed solution is a bit too specific:

That's because I didn't explain Part B of my nefarious plan! namely
that, if you'd only give me proper eigenstates, I'd give you an even
nicer alternative.

I actually think that the meta doesn't belong on the operator at all
(though I have no problem with that idea in itself).

Instead, I think the meta should be placed on the data (which, of
course, is what any(), all(), one(), and none() already do).

So I'm going to go on to propose that we create a fifth class of
Junction: the transjunction, with corresponding keyword Cevery.

Then we define:

every(@list)  comparision-op  value
every($junction) comparision-op  value

to mean repectively:

grep  * comparision-op value,  @list;
grep  * comparision-op value,  $junction.eigenstates;

as well as the reverses:

value comparision-op every(@list)
value comparision-op every($junction)

to mean respectively:

grep  value comparision-op *,  @list;
grep  value comparision-op *,  $junction.eigenstates;


So then we get:

 sub factors (Num $n) { ( $n/any(1..$n) ).eigenstates.grep({ $^q.Int == 
 $q }); }

 [which] could be:

 sub factors (num $n) { ^$n G[==] $n/any(1..$n) }

could instead be:

sub factors (Num $n) {
 every( $n/any(1..$n) ) ~~ { $^q.Int == $q });
 # Every quotient of N divided by any lesser integer, where
the quotient is also an integer
}


and:

say UNACCEPTABLE.eigenstates¬».fmt(\t%s\n);

 [which] could be

  say (::Str G[eq] UNACCEPTABLE)».fmt(\t%s\n)

could also be:

say (every(UNACCEPTABLE) ~~ ::Str)».fmt(\t%s\n)
# Everything unacceptable that's a string, formatted as follows...


 Operations other than equality could be used:

 say (^10 G[] one(3,7));
 3 4 5 6

which could also be:

say every(^10)  one(3,7);
# Every value up to 10 that's greater than 3 or 7 but not both

And so on:

say every(factor_of($x)  factor_of($y))  10;
# Every common factor of both X and Y that's greater than 10

say every(@coefficient) ~~ 0..1;
# Every coefficient in the range 0 to 1

say every(@string) ~~ /target/;
# Every string that matches the target pattern

I just think those all read much better than the (otherwise excellent)
meta-operator. In much the same way that the existing junctive types
read better than their functional or operator-oriented alternatives.

I'd like these in the core language (for performance and universal
accessibility), but if not, I already have a nearly-complete
implementation of a module implementing them, which runs successfully on
the current release of Rakudo*. I append said model for your amusement
(and suggestions!).

Damian

-cut--cut--cut--cut--cut--cut--cut--cut-

module Transjunctions;

# Add missing public method (and equivalent function) to junctions
#  Call them .eigenvalues(), so as not to clash with existing misnamed
!eigenstates()...
use MONKEY_TYPING;
augment class Junction {
method eigenvalues (Junction $j:) {
my @values = $j.eigenstates;
@values .= map({ $^val.?eigenstates // $^val }) while
@values.grep(Junction);
return uniq(@values).grep($j) does ::Transjunction;
}

sub eigenvalues (Junction $j) is export { $j.eigenvalues }
}


# Transjunctions are just lists that autofilter when matched...
role Transjunction {
method ACCEPTS (Mu $filter) { self.grep($filter) }
}


# Convenient functions to build transjunctions...
multi sub every (*...@list is copy) returns Transjunction is export {
return @list does Transjunction;
}

multi sub every (Junction $j) is export {
return eigenvalues($j) does Transjunction;
}


# Comparing against a transjunction filters it with the comparison
# Rakudo star seems to require we provide two versions, though
# I had expected the Mu version ought to handle both Junctions and Anys...
multi sub infix:«»  (Transjunction $list, Mu $n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«»  (Transjunction $list,$n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«»  (Transjunction $list, Mu $n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«»  (Transjunction $list,$n) is export
{ $list.grep( *   $n ) does Transjunction }
multi sub infix:«=» (Transjunction $list, Mu $n) is export
{ $list.grep( * = $n ) does

Tweaking junctions

2010-10-21 Thread Damian Conway
I've been thinking about junctions, and I believe we may need a small
tweak to (at least) the jargon in one part of the specification.

Specificially, in S32-setting-library_Containers.pod, we currently have:

=item !eigenstates

method !eigenstates (Junction $j: -- Parcel)

Returns an unordered list of the values that constitute the junction
(formerly called C.values). It flattens nested junctions of the
same type, so C(1|(2|3)).eigenstates returns an arbitrary
permutation of the list C1, 2, 3.

The problem is the *name* of that method. By definition, the eigenstates
of a junction are those non-superimposed values to which the junction's
superimposed values could actually collapse. Or, to put it another way,
those non-superimposed values that a junction would actually match.

That is, a C$value is an eigenstate of a C$junction if-and-only-if:

$value !~~ Junction$value ~~ $junction

But the C!eigenstates method (as currently defined) does not return
a list of such eigenstates. Instead it merely returns a partially-flattened
list of the raw internal values of the junction...which is not (usually) the
same thing at all.

That's because junctions often contain internal values to which *externally*
they cannot actually collapse...and hence cannot actually match.

Some examples, to illustrate the distinction:

Internal states   Actual eigenstates
Junction(what !eigenstates returns)   (what junction could match)
=   ===   ===
any(1,2,3)  1, 2, 3   1, 2, 3

all(1,2,3)  1, 2, 3   none

one(1,2,3)  1, 2, 3   1, 2, 3

none(1,2,3) 1, 2, 3   infinitely many

any(12, 23)   all(1,2), all(2,3)none

all(1|2, 2|3)   any(1,2), any(2,3)2

one(1|2, 23)   any(1,2), all(2,3)1, 2

one(1|2, 2|3)   any(1,2), any(2,3)1, 3


So the two problems are:

1.  $j!eigenstates doesn't return $j's eigenstates
(i.e. the method is misnamed)

2.  $j!eigenstates doesn't return $j's eigenstates
(i.e. there's no way to get a junction's actual eigenstates,
 which is a very useful thing to be able to do--see below)


Problem 1 could be solved by renaming the method C!eigenstates
to something like: C!internal-states. And, of course, renaming the
corresponding attribute in the Junction class from C$!eigenstates
to something like C$!internal-states.


Problem 2 could be solved by defining a new (and public!)
C.eigenstates method in the Junction class. This method
would be implemented as something like:

method eigenstates(Junction $j: -- List) is cached {

# No feasible way of representing the eigenstates of an injunction...
fail if $j!type ~~ JUNCTION_TYPE_NONE;

# Candidates for eigenstates are all the junction's internal values...
my @possible-eigenstates = $j!internal-states;

# Or, rather, candidates are all its *non-superimposed* internal values
# so we need to iteratively flatten any superimposed values...
@possible-eigenstates
.= map({$^value ~~ Junction ?? $^value!internal-states !! $^value})
while @possible-eigenstates.grep(Junction);

# Actual eigenvalues are those unique candidates
#   that successfully match the original junction...
return uniq(@possible-eigenstates).grep($j);
}

There is no need for this new C.eigenstates method to be private,
because it doesn't expose the internal data of its junction object,
but rather calculates a useful external property of that object.

Some examples of why that the actual eigenstates of a junction are useful
(note that these all assume the above (re)definition of C.eigenstates):

# Find the list of common elements in two lists...
sub intersection (@list1, @list2) {
(any(@list1)  any(@list2).eigenstates;
}


# Find the factors of a number...
sub factors (Num $n) {
( $n/any(1..$n) ).eigenstates.grep({ $^q.Int == $q });
}


# Check for an unacceptable password, and list all when warning...
constant UNACCEPTABLE = any  Godel Escher Bart etc... ;

if $passwd ~~ UNACCEPTABLE {
say Unacceptable password. Don't use any of these:;
say UNACCEPTABLE.eigenstates¬».fmt(\t%s\n);
}


If nothing else, we really do need to rename the current C!eigenstates method.

Damian


PS: I also note that the most recent release of Rakudo* defines the
C.eigenstates method as public, which is inconsistent with the
current specification. That probably needs to be fixed as well.


Assigning duplicate values to several hash keys using junctions?

2009-06-08 Thread Ville Koskinen
Hello all,

I was curious if this is possible in Perl 6:

%hash{ 'foo'  'bar' } = 'some value';
# %hash{'foo'} eq 'some value' and %hash{'bar'} eq 'some value'

or perhaps

%hash{ 'foo' | 'bar' } = 'some value';

In other words, is it possible to assign the same value to multiple hash
keys simultaneously using junctions (or some other new mechanism)? In
Perl 5, I would do

$hash{'foo'} = $hash{'bar'} = 'some value';

which gets tedious with more than one hash key. An alternative is always

@hash{qw(foo bar)} = ('some value') x 2;

which is probably

%hashfoo bar = ('some value') x 2;

in Perl 6, but you always need to take care to write the correct integer
in the list replication. The best way is, of course, (in Perl 5)

{
   my @keys = qw(foo bar);
   @ha...@keys} = ('some value') x @keys;
}

but then you need the @keys array, which needs to be defined if you are
dealing with literal values. Reading the synopses, one possibility seems
to be 

%hashfoo bar = 'some value';

using hyper operators, but is that really the best way?

Regards,
Ville Koskinen


Re: Assigning duplicate values to several hash keys using junctions?

2009-06-08 Thread Jon Lang
2009/6/8 Ville Koskinen vrk...@iki.fi:
 Hello all,

 I was curious if this is possible in Perl 6:

 %hash{ 'foo'  'bar' } = 'some value';
 # %hash{'foo'} eq 'some value' and %hash{'bar'} eq 'some value'

By autothreading, this would be equivalent to:

(%hash{'foo'}  %hash{'bar'}) = 'some value';

which in turn is the same as:

   (%hash{'foo'} = 'some value')  (%hash{'bar'} = 'some value');

So yes, this is possible.

-- 
Jonathan Dataweaver Lang


Re: Assigning duplicate values to several hash keys using junctions?

2009-06-08 Thread Larry Wall
On Mon, Jun 08, 2009 at 12:02:43PM +0100, Ville Koskinen wrote:
: An alternative is always
: 
: @hash{qw(foo bar)} = ('some value') x 2;
: 
: which is probably
: 
: %hashfoo bar = ('some value') x 2;
: 
: in Perl 6, but you always need to take care to write the correct integer
: in the list replication.

Two problems.  First, list replicaiton is xx rather than x, and second,
you *don't* have to write the integer, because you can use the
Whatever star:

%hashfoo bar = 'some value' xx *;

That makes an arbitrarily long list of strings.

: The best way is, of course, (in Perl 5)
: 
: {
:my @keys = qw(foo bar);
:@ha...@keys} = ('some value') x @keys;
: }
: 
: but then you need the @keys array, which needs to be defined if you are
: dealing with literal values.

Perl 6's new * term is useful in many such places where you just want
to say, I dunno, you figure it out.

: Reading the synopses, one possibility seems to be 
: 
: %hashfoo bar = 'some value';
: 
: using hyper operators, but is that really the best way?

If you'll define best way, I'll tell you if it is.  :)

The relative efficiency is going to be difficult to predict because
any of these could be poorly implemented and do too much busywork.
Apart from that, it's gonna come down primarily to what you think
is readable.

By the way, infix hypers want to go on both sides, like this:

%hashfoo bar »=» 'some value';

Larry


Re: junctions and conditionals

2009-04-03 Thread Miroslav Silovic

Dave Whipp wrote:
I'm thinking that the solution to this issue may be a little more 
radical than to-date: don't permit junctions to be stored in $ 
variables! Instead, require junctions to use a twiggle, to alert the 
reader that the surprises may be lurking.


my $x = 1|2; #error
my $|x = 1|2; # ok

Then you just need to invent some syntax to say that collapse is (or 
perhaps isn't) desired:


if [[ $|x  1 ]] { say $|x collapsed }

The most important thing that this does is that it leaves open the 
option to allow $ variables to hold junctions in some future version 
of Perl, without that future version being constrained by legacy 
semantics.




I'd second the twigil idea. Reason: I'd -really- like perl6 to be 
compilable into an efficient machine code without a JIT magic that we 
can currently only handwave about.


For that, I'd propose a rule of a thumb: ints are ints. Of course, 
floats and other unboxed types should also be just plain unboxed types, 
but I'd like the rule of a thumb to be short and to the point.


So,

int $x = 1|2;

should be an error.

Also,

int $x = 1 but not really a number;

should also be an error or at least a warning that mixin stripping and 
unboxing took place. If you want polymorphic here, use Ints. That'd also 
mean that


my @x of int;

can be implemented as a homogenous int vector, meaning -really- 
efficient and manipulable through the kind of code that modern CPUs are 
really good at (since as soon as you know you won't be lazy, you only 
need to be polymorphic about asking for the beginning of the in-memory 
buffer that can be manipulated directly. Even if that buffer doesn't 
contain all the elements, you can refill it as needed, and that could 
still be fast as long as the other side of the partially-lazy barrier 
also speaks int). Also, as far as I'm aware, there is no tracing VM that 
can create a homogenous arrays for you if you can't already do them.


From the above, the need for twigils in junctions should be apparent.

   Miro



Re: [Fwd: Re: junctions and conditionals]

2009-04-02 Thread Martin D Kealey
On Wed, 1 Apr 2009, Richard Hainsworth wrote:
 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

Yes -- and well put, thank-you.

The trick is that since conditionals generally force full or partial
resolution on junctions, that lifetime won't tend to be very long.

Re: Tsa's comment about junctions being value types. In principle I agree,
except that the value semantics are only within the eigenthreads; outside
that, they are collections of indeterminate state. Indeterminate states
aren't sufficiently value-like to justify constant folding.

-Martin


Re: simultaneous conditions in junctions

2009-04-02 Thread Martin D Kealey

On Wed, 1 Apr 2009, John Macdonald wrote:
 If I understand correctly, (which is by no means assured) a function
 call with a junction as an argument generally acts as if it were
 autothreaded.  So:

   $x = any(1,2,3);
   $y = f($x);

 should work like:

 $y = any( f(1), f(2), f(3) );

 Right?

In general yes.

However if f involves some kind of truth inversion then logically

f(any(@x)) == all(map.assuming(f).(@x))
and
f(all(@x)) == any(map.assuming(f).(@x))

I have in mind something like these in the standard preamble:

prefix:«!»(Bool)   does(junctive_inversion)
prefix:«not»(Bool) does(junctive_inversion)
infix:«ne»(String,String)  does(junctive_inversion)
infix:«!=»(Num,Num)does(junctive_inversion)
infix:«!==»(Object,Object) does(junctive_inversion)

(Excuse the rather lose syntax, but I hope you get the idea.)

-Martin


Re: junctions and conditionals

2009-04-02 Thread Jon Lang
Martin Kealey wrote:
 On Tue, 31 Mar 2009, Jon Lang wrote:
 Another issue: what happens if conditional code mutates a junction
 that it filtered?  For example:

     $x = any (-5 .. 5);
     if $x  0 { $x++ };

 At this point, which of the following does $x equal?

     any(-4 .. 6) # the original junction gets mutated
     any(-5 .. 0, 2 .. 6) # the filtered part of the original junction
 gets mutated; the rest is untouched
     any(2 .. 6) # the filtered part of the original junction gets
 mutated; the rest is lost

 I choose #3.

 Reality can only take one path through a conditional; which one depends
 on the one/any/all/none binding of the junction.

 Once you've passed the conditional, you have:

        one - single matching value (no longer a junction)
        any - filtered list
        all - original junction
        none - empty (*1)

I'm a bit worried about 'none', for reasons that I'll get to in a moment.

 The threading is an implementation detail; the important thing is a
 junction is collection of values and a smart way of rewriting
 expressions that contain them, with special treatment for comparison
 operators (or indeed anything that forces Boolean content):

        $x CMP all($y,$z)       $x CMP $y  $x CMP $z
        $x CMP one($y,$z)       $x CMP $y ^^ $x CMP $z  (*2)
        $x CMP none($y,$z)      all($x !CMP $y, $x !CMP $z)
        $x CMP any($y,$z)       $x !CMP none($y, $x)

        $x OP all($y,$z)        all( $x OP $y, $x OP $z)
        $x OP any($y,$z)        any( $x OP $y, $x OP $z)
        $x OP one($y,$z)        one( $x OP $y, $x OP $z)
        $x OP none($y,$z)       none($x OP $y, $x OP $z)

 -Martin

 (*1: An argument could be made that none should leave the junction alone,
 the same as all.)

 (*2: I would like to suggest that the semantics of one be changed to mean
 pick one (randomly) rather than exactly one. In this respect it
 would be the same as any except it wouldn't have the overhead of
 filtering *every* match, just at least one.)

A few thoughts here.  First: should autothreading be lazy or eager?
As things stand, it seems to be eager: the moment you pass a junction
into a routine that doesn't ask for a junction in its signature, you
autothread that routine.  This has the nice benefit of being easy to
implement (autothread if the parameter doesn't specify 'junction';
don't autothread if it does); but as has been mentioned before, making
life easy on the implementor isn't a primary design goal for Perl.  I
submit that autothreading should be lazy.

As I see it, there are currently three things that can be done with a junction:

  1. Nothing.  Using the junction as threads paradigm, you bundle
the threads together and route them through a given part of the
program as a single rope.

  2. Autothreading.  You feed each thread through individually, and
rebundle the results on the other side.

  3. Sieving.  You feed only some of the threads through a decision
point into its guarded region, and rebundle at the end of the guarded
region.

Option 3 raises some additional questions.  What do you rebundle at
the end of the guarded region?  Just the threads that were passed
through it, or all of the original threads?  And what happens if the
program flow gets rerouted inside the guarded region such that it
never comes out the other side?

If I say:

$x = any(-5 .. 5)
if $x  0 { $x++ }
if $x ~~ (-1 .. 1) { $x *= 2 }

What is $x just before and just after '$x++'?  What is $x just before
and just after 'if $x  0 { $x++ }'?  Ditto with '$x *= 2' and 'if $x
 0 { $x *= 2 }'?

If I say:

$x = any(-5 .. 5)
if $x  0 { return }
if $x ~~ (-1 .. 1) { doit($x) }

What junction should doit be receiving?

Second:

sub sayit (Str $s) { say $s }
sayit 'S' | 5;

What should happen?  Should the junction be autothreaded, and then one
of the threads fail due to a type mismatch?  Or does parameter-passing
count as a kind of decision-point, such that you only get the sayit
'S' thread?

And what happens with the following?

sayit none('S');

-- 
Jonathan Dataweaver Lang


Re: simultaneous conditions in junctions

2009-04-02 Thread Richard Hainsworth

Larry Wall wrote:

On Wed, Apr 01, 2009 at 08:40:12AM -0700, Dave Whipp wrote:
  
That said, the semantics of a chained relop really should work correctly  
for this. If you only reference a junction once in an expression, then  
it should behave as such: {abc} !=== {ab  bc}.



Yes, that is the intent.  I consider a chained 1  $x  2 to be a
single function from the standpoint of autothreading, something like

chained(1, infix:«», $x, infix:«», 2);

and the semantics would fall out of that naturally, more or less.

Something similar could also work for the blocks of conditionals
if we were to treat the conditional as a function that autothreads
consistently over both its condition and its blocks; this implies the
junction autothreader must be given enough access to the scope of the
block in question to temporarily override the value of $x within the
block to its autothreaded value somehow.  The tricky bit is that
autothreading is setting up extra scopes around variant captures
without explicit blocks.  That alone is reason enough to keep
the mechanism all internal.
  

Do I understand correctly from this that
my $x = 1|5; say ?(2  $x  $4) ; # False
my $x = 1|3|5; say ?(2  $x  $4); # True

If so, then the current implementation of rakudo is generating an error, 
viz.,

$ perl6
 my $x=1|5; say ?( 2  $x  4)
1

May be something extra needs to be added to the specs?

If we do give access to universe of values the junction is interested
in, it should probably just be via a coercion to Set.
This would give the necessary extra syntax to ensure that the programmer 
knows what s/he is doing. It means that junctions could be threshed and 
sieved when desired.

  There would have
to be some caveats about using that as the universe of values, however,
since none() junctions define a set outside of the eigenstates.
  
Interesting. Do I understand this correctly: If the junction is finite, 
then none() defines an infinite set, and vice versa.
But then if perl6 is lazy, an infinite set would also be possible 
With access being lazily evaluated. Just as 0 .. inf is lazily evaluated?

For that reason I'd still prefer people to track their universe of
values outside the junctions rather than rely on junctions for that.

And of course, a Set in list context is its members, so any(%set) isn't
a problem going the other direction.

Larry
  


simultaneous conditions in junctions

2009-04-01 Thread Richard Hainsworth
Thinking about Jon Lang's -1|+1 example in another way, I wondered about 
simultaneous conditions.


Consider

$x = any (1,2,5,6)

How do we compose a conditional that asks if any of this set of 
eigenstates are simultaneously both  2 and  5?

Clearly the desired answer for $x is False, but

my $x = any(1,2,5,6); say ?( 2  $x  5); # true

Is there some combination of any/all that will achieve this?

Here it would seem that we would want to have some sieving, so that 
eigenstates that are true for one test can be given to another test.




Re: simultaneous conditions in junctions

2009-04-01 Thread Carl Mäsak
Richard ():
 Consider

 $x = any (1,2,5,6)

 How do we compose a conditional that asks if any of this set of eigenstates
 are simultaneously both  2 and  5?
 Clearly the desired answer for $x is False, but

 my $x = any(1,2,5,6); say ?( 2  $x  5); # true

 Is there some combination of any/all that will achieve this?

my @x = 1, 2, 5, 6; say ?(first { 2  $_  5 }, @x); # false

Problem solved. It doesn't involve the cool junctions technology, but
it's not much longer, and perhaps slightly more understandable.

// Carl


[Fwd: Re: junctions and conditionals]

2009-04-01 Thread Richard Hainsworth

This email was mistakenly not sent to the p6l list.

Jon writes:

On Wed, Apr 1, 2009 at 12:54 AM, Richard Hainsworth
rich...@rusrating.ru wrote:

Jon Lang wrote:


In Junction Algebra, Martin Kealey wrote:



On Mon, 30 Mar 2009, Mark J. Reed wrote:



  ( $a = any(-1,+1) = $b ) ==



( $a = any(-1,+1)  any(-1,+1) = $b )(*A)



Clearly, the RHS is true for $a == $b == 0, but I'm not sure the LHS
shouldn't also be.  Isn't it just syntactic sugar for the RHS?



I suspect not. Rather I think that

  $a = any(-1,+1) = $b

corresponds to

  $tmp = any(-1,+1);
  $a = $tmp = $b

and thence to

  $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.


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.




Using a junction implies the extraction of the eigenstates. That is being
frowned upon - I understand


I've been doing my utmost to avoid making said implication.


The possible solution to both of these: junctions collapse when they
hit conditional statements - but only within the conditioned scope.
So: within the code block for the if $x  0 statement above, $x only
equals +1, since -1 didn't pass the test.


This is the sieving functionality. Since perl6 is being written explicitly
to avoid sieving out eigenstates, this will not happen.


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.


Thus, say $x is the same
as say 1.  In the case of the range test, the code on the RHS of the
 only executes if the code on the LHS evaluated to true; therefore,
when evaluating the RHS, $tmp doesn't include any of the
possibilities that would have failed on the LHS.  That means that:

   0 = -1 | +1 = 0



which is true, because using standard chaining semantics we have
0 = -1|1 and -1|1 = 0
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.


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.


Perhaps instead of 0 = any(-1,1) = 0, the programmer might want 0 =
all(-1,1) = 0, which is false.


You're assuming that the programmer gets to choose which junction he's
sticking in the middle of the comparison chain.


...becomes:

   0 = -1 | +1  +1 = 0

...which, obviously, is false.



The question really is what is the desired meaning of this conditional.


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.

--
Jonathan Dataweaver Lang



Re: simultaneous conditions in junctions

2009-04-01 Thread Jon Lang
On Wed, Apr 1, 2009 at 12:58 AM, Richard Hainsworth
rich...@rusrating.ru wrote:
 Thinking about Jon Lang's -1|+1 example in another way, I wondered about
 simultaneous conditions.

 Consider

 $x = any (1,2,5,6)

 How do we compose a conditional that asks if any of this set of eigenstates
 are simultaneously both  2 and  5?
 Clearly the desired answer for $x is False, but

 my $x = any(1,2,5,6); say ?( 2  $x  5); # true

 Is there some combination of any/all that will achieve this?

As Carl indicated, there are other ways to do this.  For instance, s/
2  $x  5 / $x ~~ 2 ^..^ 5 /.  But as I indicated in a recent email,
part of my concern is that those two expressions _ought to be_
equivalent: changing the junction, or making do without one as Carl
proposes, doesn't fix this lack of equivalence.

As for Carl's proposed alternative: no, it isn't _much_ longer (but it
_is_ longer), and _perhaps_ it's _slightly_ more understandable - or
perhaps not.  Other than making the implementors' lives harder, what's
wrong with trying to find a way to get Jonathan's example to work the
way people expect it to?

I don't understand this aversion to everything remotely hinting of
eigenstates/eigenthreads/threshing/whatever.

-- 
Jonathan Dataweaver Lang


Re: [Fwd: Re: junctions and conditionals]

2009-04-01 Thread Henry Baragar
On Wednesday, April 01 2009 07:38 am, Richard Hainsworth wrote:
 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.

When you say DWIM, I take it you mean that there is an assumption that $x is a 
point in a field (http://en.wikipedia.org/wiki/Field_theory_(mathematics)).  
As you have illustrated, junctions do no form a field.

You would run into the similar problems if $x was a point in a ring 
(http://en.wikipedia.org/wiki/Ring_(mathematics)).   Consider the ring of 
integers modulo 8:
my Ring8 $x = 5 + 3;# evaulates to 0
say OMG, its 0! unless $x;# prints the message 
which does not DWIM if I am expecting $x to be part of a field.

Maybe the problem is that junctions are too easy to create, which is causing 
people to confuse the mathematical structure of the space created by using 
a junction with that of the structure of the space of the underlying 
(non-junctioned) object.

Regards,
Henry


Re: simultaneous conditions in junctions

2009-04-01 Thread Mark J. Reed
The idea is that junctions should usually be invisible to the code,
and autothreading handles them behind the scenes.  Once you start
using the eigenstates as a collection, you're breaking the model and
not gaining anything over just using a regular collection type.
But the behind the scenes model fails when a junction passes
through a condition into guarded code that assumes the condition is
true, unless the eigenstates inside the guard are restricted to those
for which the condition is true.

Consider:

my $x = 2|0;
my $y = $x ?? 1/$x !! 0;

The expected result is presumably $y == 0|.5, but if the $x in the
denominator isn't restricted to the eigenstates that pass the
conditional, you get a divide by zero in one of the autothreads.

The code needs to behave as if each eigenstate is treated
independently by a separate thread, and only combined back into a
junction at the end of each autothreaded block, even if the
implementation doesn't actually do it that way.  We can't just test a
junction using its junctive semantics and fall through with the
junction intact.

To go back to the Blackjack example: for junctions to apply, code
written with the assumption that each hand's sum is a simple number
should work when they're actually junctions.  But that's not the case
because the end goal is to pick a single winner, not a junction of
possible winners depending on how you assign values to the Aces.
There are specific rules for the selection of Ace values that don't
necessarily follow junctive semantics, and just letting things thread
through will not yield the right answer in all cases.

(Yes, for those keeping score at home, I changed my mind about the
applicability of junctions to that problem...)

On 4/1/09, Jon Lang datawea...@gmail.com wrote:
 On Wed, Apr 1, 2009 at 12:58 AM, Richard Hainsworth
 rich...@rusrating.ru wrote:
 Thinking about Jon Lang's -1|+1 example in another way, I wondered about
 simultaneous conditions.

 Consider

 $x = any (1,2,5,6)

 How do we compose a conditional that asks if any of this set of
 eigenstates
 are simultaneously both  2 and  5?
 Clearly the desired answer for $x is False, but

 my $x = any(1,2,5,6); say ?( 2  $x  5); # true

 Is there some combination of any/all that will achieve this?

 As Carl indicated, there are other ways to do this.  For instance, s/
 2  $x  5 / $x ~~ 2 ^..^ 5 /.  But as I indicated in a recent email,
 part of my concern is that those two expressions _ought to be_
 equivalent: changing the junction, or making do without one as Carl
 proposes, doesn't fix this lack of equivalence.

 As for Carl's proposed alternative: no, it isn't _much_ longer (but it
 _is_ longer), and _perhaps_ it's _slightly_ more understandable - or
 perhaps not.  Other than making the implementors' lives harder, what's
 wrong with trying to find a way to get Jonathan's example to work the
 way people expect it to?

 I don't understand this aversion to everything remotely hinting of
 eigenstates/eigenthreads/threshing/whatever.

 --
 Jonathan Dataweaver Lang


-- 
Sent from my mobile device

Mark J. Reed markjr...@gmail.com


Re: simultaneous conditions in junctions

2009-04-01 Thread John Macdonald
On Wed, Apr 01, 2009 at 09:44:43AM -0400, Mark J. Reed wrote:
 The idea is that junctions should usually be invisible to the code,
 and autothreading handles them behind the scenes.  [ ... ]

If I understand correctly, (which is by no means assured) a function
call with a junction as an argument generally acts as if it were
autothreaded.  So:

$x = any(1,2,3);
$y = f($x);

should work like:

$y = any( f(1), f(2), f(3) );

Right?

sub f($x) {
return $x  1.5  $x ?? $x :: undef;
}

$y = f($x);
$z = $x  1.5  $x ?? $x :: undef;

Unless autothreading is also implied by conditionals, $y
and $z would have significantly different results; $y ===
any(undef,undef,undef) while $z === any(1,2,3).  But, if
autothreading *is* implied by conditionals, where do the
threads get joined?  I have a feeling that the autothreading
has to happen essentially at the point of the creation of the
junction to avoid getting a result from a junction that none
of the joined quantities is capable of justifying (such as
the one described ealier of (-4|4) matching the criteria to be
in the range 0..1).  I suspect that juctions will be perl6's
action-at-a-distance hazard.  (With quantum entanglement,
you get action-at-a-distance effects in the real world.
When we import them into a computer language, the resulting
action-at-a-distance should come as no surprise - except for
its inherent surprise/hazard nature.)  Now, if it is acceptable
for -4|4 to return true for 0 = $x = 1 when tested directly
in an expression, but to return false if it is tested in a
subroutine, then perl6 junctions are not really modelling
quantum superpositions and I, at least, will need to find a
different metaphor for what they actually do do (and for what
they can be used for and when).


Re: simultaneous conditions in junctions

2009-04-01 Thread Dave Whipp

Richard Hainsworth wrote:
Thinking about Jon Lang's -1|+1 example in another way, I wondered about 
simultaneous conditions.


Consider

$x = any (1,2,5,6)

How do we compose a conditional that asks if any of this set of 
eigenstates are simultaneously both  2 and  5?

Clearly the desired answer for $x is False, but

my $x = any(1,2,5,6); say ?( 2  $x  5); # true

Is there some combination of any/all that will achieve this?

Here it would seem that we would want to have some sieving, so that 
eigenstates that are true for one test can be given to another test.




One answer is to use grep:

  $x = any (1,2,5,6);
  say ?( (2^..^5).grep: { $_ == $x } ); # False


This isn't, of course, quite what you asked for, because the semantics 
of relops are continuous. So you'd want something like:


  $x = any (1,2, 2.5, 5,6);
  say ?( (2^..^5 :real).grep: { $_ == $x } ); # False

(or whatever the syntax for a continuous range is). That might take a 
while to complete, hence my desire for an analytic grep




That said, the semantics of a chained relop really should work correctly 
for this. If you only reference a junction once in an expression, then 
it should behave as such: {abc} !=== {ab  bc}.


Re: junctions and conditionals

2009-04-01 Thread TSa

HaloO,

Jon Lang wrote:

Another issue: what happens if conditional code mutates a junction
that it filtered?  For example:

$x = any (-5 .. 5);
if $x  0 { $x++ };

At this point, which of the following does $x equal?

any(-4 .. 6) # the original junction gets mutated
any(-5 .. 0, 2 .. 6) # the filtered part of the original junction
gets mutated; the rest is untouched
any(2 .. 6) # the filtered part of the original junction gets
mutated; the rest is lost


This is an example why the controlled block should not be
auto-threaded. That is the assembly point of the resulting
junction any(0,0,0,0,0,1,1,1,1,1) is before the block. Thus
I'm opting for any(-4..6).


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


Re: [Fwd: Re: junctions and conditionals]

2009-04-01 Thread TSa

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

Re: junctions and conditionals

2009-04-01 Thread Dave Whipp

Jon Lang wrote:
[proposal that conditional statements should collapse junctions]


$x = +1 | -1;
if $x  0 { say $x is positive. }
else { say $x is negative. }

I suspect that both codeblocks would be executed; but within the first
block, $x == +1, and within the second codeblock, $x == -1.


The problem I see with this (other than implementation issues) is that 
it would lead to unintuitive behavior in some cases:


my $x = one(10,20);
if $x  15 {
  # here, $x collapsed to 20
  if $x  5 { say $x  5 } else { say not $x  5 }
}
if $x  5 { say $x  5 } else { say not $x  5 }

Some people might be surprised if the two tests of $x  5 result in 
two different results.


I don't think that there is any single semantics that won't cause 
surprises (unintuitive behavior) in some cases. So I'd vote for going 
with simple semantics that are easy to explain -- that is, don't attempt 
implicit junctional collapse. Provide operators to collapse when needed, 
but don't attempt to be too clever.


Re: simultaneous conditions in junctions

2009-04-01 Thread TSa

HaloO,

John Macdonald wrote:

Unless autothreading is also implied by conditionals, $y
and $z would have significantly different results; $y ===
any(undef,undef,undef) while $z === any(1,2,3).


This is why I'm opting for statical analysis of auto-threaded
conditionals.



 But, if
autothreading *is* implied by conditionals, where do the
threads get joined?


Right after the conditional, of course. From there it could
be necessary to branch into both blocks however if you have
a result of any(0,1) and an else block. ?? !! essentially
behaves like an if else. Question is how this applies to
user defined control structures.



 I have a feeling that the autothreading
has to happen essentially at the point of the creation of the
junction to avoid getting a result from a junction that none
of the joined quantities is capable of justifying (such as
the one described ealier of (-4|4) matching the criteria to be
in the range 0..1).  I suspect that juctions will be perl6's
action-at-a-distance hazard.  (With quantum entanglement,
you get action-at-a-distance effects in the real world.


Quantum entanglement is no action at a distance because
you can't transfer anything with the collapse. The local
appearance is that of a normal quantum measurement. Only
if you communicate information by traditional means you
can compare *measurements*. The common misconception of
Quantum Mechanics is that it is about small things whereas
a two photons system can span galaxies.



When we import them into a computer language, the resulting
action-at-a-distance should come as no surprise - except for
its inherent surprise/hazard nature.)  Now, if it is acceptable
for -4|4 to return true for 0 = $x = 1 when tested directly
in an expression, but to return false if it is tested in a
subroutine, then perl6 junctions are not really modelling
quantum superpositions


I agree. We should make sure that junctions model quantum
computations.

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


Re: junctions and conditionals

2009-04-01 Thread Mark J. Reed
On Wed, Apr 1, 2009 at 11:49 AM, Dave Whipp d...@dave.whipp.name wrote:

 The problem I see with this (other than implementation issues) is that it
 would lead to unintuitive behavior in some cases:

 my $x = one(10,20);
 if $x  15 {
  # here, $x collapsed to 20
  if $x  5 { say $x  5 } else { say not $x  5 }
 }
 if $x  5 { say $x  5 } else { say not $x  5 }

 Some people might be surprised if the two tests of $x  5 result in two
 different results.


That's surprising, yes, but I'd say the surprise comes from the fact that
it's a one() junction, which has extra weirdness on top of the general
junctional weirdnesses.

So yes, if we collapse the junction, $x is both   5 and not  5 according
to the output.  If we *don't* collapse, $x will consistently fail the $x  5
test - but then you have a value that is somehow both greater than 15 and
not greater than 5, which I would still call surprising.

I don't think that there is any single semantics that won't cause surprises
 (unintuitive behavior) in some cases.


Probably true.


 So I'd vote for going with simple semantics that are easy to explain --
 that is, don't attempt implicit junctional collapse. Provide operators to
 collapse when needed, but don't attempt to be too clever.


While it's easier to find clever programmers than to write clever software,
the gains from the latter are significant, as Larry's work pre- and
post-Perl has repeatedly demonstrated. When a language implementation
provides a feature like junctions that is arguably too clever by half to
start with, I'd rather there be a commensurate amount of cleverness in the
support of that feature.

Basically, I want the specified behavior to make sense as much as possible,
and for it to be easy to explain the places where it doesn't seem to make
sense.  Even if it means we don't get that behavior in 6.0.0.

-- 
Mark J. Reed markjr...@gmail.com


Re: simultaneous conditions in junctions

2009-04-01 Thread Larry Wall
On Wed, Apr 01, 2009 at 08:40:12AM -0700, Dave Whipp wrote:
 That said, the semantics of a chained relop really should work correctly  
 for this. If you only reference a junction once in an expression, then  
 it should behave as such: {abc} !=== {ab  bc}.

Yes, that is the intent.  I consider a chained 1  $x  2 to be a
single function from the standpoint of autothreading, something like

chained(1, infix:«», $x, infix:«», 2);

and the semantics would fall out of that naturally, more or less.

Something similar could also work for the blocks of conditionals
if we were to treat the conditional as a function that autothreads
consistently over both its condition and its blocks; this implies the
junction autothreader must be given enough access to the scope of the
block in question to temporarily override the value of $x within the
block to its autothreaded value somehow.  The tricky bit is that
autothreading is setting up extra scopes around variant captures
without explicit blocks.  That alone is reason enough to keep
the mechanism all internal.

If we do give access to universe of values the junction is interested
in, it should probably just be via a coercion to Set.  There would have
to be some caveats about using that as the universe of values, however,
since none() junctions define a set outside of the eigenstates.
For that reason I'd still prefer people to track their universe of
values outside the junctions rather than rely on junctions for that.

And of course, a Set in list context is its members, so any(%set) isn't
a problem going the other direction.

Larry


Re: junctions and conditionals

2009-04-01 Thread Dave Whipp

Mark J. Reed wrote:

[I] wrote:

So I'd vote for going with simple semantics that are easy to explain --
that is, don't attempt implicit junctional collapse. Provide operators to
collapse when needed, but don't attempt to be too clever.



While it's easier to find clever programmers than to write clever software,
the gains from the latter are significant, as Larry's work pre- and
post-Perl has repeatedly demonstrated. When a language implementation
provides a feature like junctions that is arguably too clever by half to
start with, I'd rather there be a commensurate amount of cleverness in the
support of that feature.

Basically, I want the specified behavior to make sense as much as possible,
and for it to be easy to explain the places where it doesn't seem to make
sense.  Even if it means we don't get that behavior in 6.0.0.


I'm thinking that the solution to this issue may be a little more 
radical than to-date: don't permit junctions to be stored in $ 
variables! Instead, require junctions to use a twiggle, to alert the 
reader that the surprises may be lurking.


my $x = 1|2; #error
my $|x = 1|2; # ok

Then you just need to invent some syntax to say that collapse is (or 
perhaps isn't) desired:


if [[ $|x  1 ]] { say $|x collapsed }

The most important thing that this does is that it leaves open the 
option to allow $ variables to hold junctions in some future version 
of Perl, without that future version being constrained by legacy semantics.


Re: junctions and conditionals

2009-04-01 Thread Martin Kealey
On Tue, 31 Mar 2009, Jon Lang wrote:
 Another issue: what happens if conditional code mutates a junction
 that it filtered?  For example:

 $x = any (-5 .. 5);
 if $x  0 { $x++ };

 At this point, which of the following does $x equal?

 any(-4 .. 6) # the original junction gets mutated
 any(-5 .. 0, 2 .. 6) # the filtered part of the original junction
 gets mutated; the rest is untouched
 any(2 .. 6) # the filtered part of the original junction gets
 mutated; the rest is lost

I choose #3.

Reality can only take one path through a conditional; which one depends
on the one/any/all/none binding of the junction.

Once you've passed the conditional, you have:

one - single matching value (no longer a junction)
any - filtered list
all - original junction
none - empty (*1)

The threading is an implementation detail; the important thing is a
junction is collection of values and a smart way of rewriting
expressions that contain them, with special treatment for comparison
operators (or indeed anything that forces Boolean content):

$x CMP all($y,$z)   $x CMP $y  $x CMP $z
$x CMP one($y,$z)   $x CMP $y ^^ $x CMP $z  (*2)
$x CMP none($y,$z)  all($x !CMP $y, $x !CMP $z)
$x CMP any($y,$z)   $x !CMP none($y, $x)

$x OP all($y,$z)all( $x OP $y, $x OP $z)
$x OP any($y,$z)any( $x OP $y, $x OP $z)
$x OP one($y,$z)one( $x OP $y, $x OP $z)
$x OP none($y,$z)   none($x OP $y, $x OP $z)

-Martin

(*1: An argument could be made that none should leave the junction alone,
the same as all.)

(*2: I would like to suggest that the semantics of one be changed to mean
pick one (randomly) rather than exactly one. In this respect it
would be the same as any except it wouldn't have the overhead of
filtering *every* match, just at least one.)



junctions and conditionals

2009-03-31 Thread Jon Lang
In Junction Algebra, Martin Kealey wrote:
 On Mon, 30 Mar 2009, Mark J. Reed wrote:
         ( $a = any(-1,+1) = $b ) == ( $a = any(-1,+1)  any(-1,+1) = 
  $b )

 Clearly, the RHS is true for $a == $b == 0, but I'm not sure the LHS
 shouldn't also be.  Isn't it just syntactic sugar for the RHS?

 I suspect not. Rather I think that

        $a = any(-1,+1) = $b

 corresponds to

        $tmp = any(-1,+1);
        $a = $tmp = $b

 and thence to

        $tmp = any(-1,+1);
        $a = $tmp  $tmp = $b

 The more I think about this, the more I come to the conclusion that a
 junction should appear to have a uniform (single) value in each
 eigenthread.

Ugh.  Let me float another problem, and a possible solution to both,
that doesn't require persistent threading environments:

$x = -1 | +1;
if $x  0 { say $x }

As I understand junctions right now, the result of this code is identical to:

   say -1 | +1;

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.

The possible solution to both of these: junctions collapse when they
hit conditional statements - but only within the conditioned scope.
So: within the code block for the if $x  0 statement above, $x only
equals +1, since -1 didn't pass the test.  Thus, say $x is the same
as say 1.  In the case of the range test, the code on the RHS of the
 only executes if the code on the LHS evaluated to true; therefore,
when evaluating the RHS, $tmp doesn't include any of the
possibilities that would have failed on the LHS.  That means that:

0 = -1 | +1 = 0

...becomes:

0 = -1 | +1  +1 = 0

...which, obviously, is false.

Extending this further:

$x = +1 | -1;
if $x  0 { say $x is positive. }
else { say $x is negative. }

I suspect that both codeblocks would be executed; but within the first
block, $x == +1, and within the second codeblock, $x == -1.

$x = +1 | -1;
say $x  0 ?? $x + 2 :: $x * 2;

In this case, $x is +1 when evaluating $x + 2, and it is -1 when
evaluating $x * 2.  After this expression is fully evaluated, they
get recombined into a single junction: +3 | -2.

This last one might be easier to manage simply by having $x autothread
through the ?? :: operator, since you need to be able to reassemble
a junction on the other end.

-- 
Jonathan Dataweaver Lang


Re: junctions and conditionals

2009-03-31 Thread Jon Lang
I've been having some second thoughts concerning this.  Here's where I
stand on it now:

In Perl 6, you have the following decision points, where code may or
may not be executed depending on a condition:
if/unless/while/until/loop/when statements; if/unless/while/until
statement modifiers; short-circuit operators; the trinary conditional
operator.  When you apply a junction to a decision point, only one of
the possible paths will be taken; and the any/all/one/none nature of
the junction will determine which one.  (Without this, there would be
no reason to have a distinction between any/all/one/none.)  However, I
stand by my proposal that after passing one of these decision points,
and until you get back to code that would have been reached regardless
of the decision point, every junction that was involved in the
decision point should be limited such that it acts as if only those
possibilities within it that would have passed the decision point
exist.

With unless, while, until, and loop, the associated block is
the conditional block where the junction gets filtered.  With if,
the main block likewise filters the junctions; but the else block
also provides junction filtering, but in a way that's complementary to
what the main block does.

With short-circuit operators, the RHS counts as a block that
provides junction filtering based on what it would take for the LHS to
avoid tripping the short-circuit behavior.  Similarly, ?? :: treats
the expression following the ?? as a junction-filtering block and
the expression following the :: as a complementary junction-filtering
block, in direct analogy to if/else, above.

Finally, there's the when statement: as with if, etc., the block
that follows the when statement filters junctions according to the
match criterion.  However, when is a bit more complicated in terms
of getting it to DWIM w.r.t. junctions.  Because of the way that
when works conceptually, I'd recommend that for the rest of the
block containing the when statement, it should provide the same sort
of complementary filtering that an else block does for an if
statement.  That is:

given $x {
when $a { ... }
when $b { ... }
when *
}

...should not be thought of as being equivalent to:

given $x {
if $_ ~~ $a { ...; break }
if $_ ~~ $b { ...; break }
if $_ ~~ * {...; break }
}

...but rather:

given $x {
if $_ ~~ $a { ... }
else {
if $_ ~~ $b { ... }
else {
if $_ ~~ * { ... }
}
}
}

--

Another issue: what happens if conditional code mutates a junction
that it filtered?  For example:

$x = any (-5 .. 5);
if $x  0 { $x++ };

At this point, which of the following does $x equal?

any(-4 .. 6) # the original junction gets mutated
any(-5 .. 0, 2 .. 6) # the filtered part of the original junction
gets mutated; the rest is untouched
any(2 .. 6) # the filtered part of the original junction gets
mutated; the rest is lost

--
Jonathan Dataweaver Lang

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-30 Thread Daniel Ruoso
Em Dom, 2009-03-29 às 22:57 -0700, Mark Lentczner escreveu:
 What I see here is that there is a tendency to want to think about,  
 and operate on, the eigenstates as a Set, but this seems to destroy  
 the single value impersonation of the Junction.
 Further, if one ever calls .!eigenstates() on a Junction, then you  
 have really bollox'd your code up, as then this code fails if the  
 value you thought was a Junction happens to be, actually, just a  
 single value!  (Unless .!eigenstates() is defined on Object, and  
 returns a Set of self...)

++

This is the most important semantic deadlock, thanks for putting it so
clearly.

 I think what is needed is a single value threshing function, which  
 can be applied to, well, single values.  Such a function would take a  
 value and a predicate, and if the predicate applied to the value is  
 true, returns the value, else it returns... nothing. If such a  
 function were applied to a Junction, then the result would be a  
 Junction of just those those eigenstates that passed this function.   
 The nothings would not end up contributing to the Junction.

Well, that can be thought as grep. 

my @i = 1|11, 9, 1|11;
my @j = 6,9,6;
my $a = [+] @i;
my $b = [+] @j;
my $va = $a.grep: * = 21;
my $vb = $b.grep: * = 21;
if ($va  $vb) {
   if ($va  $vb) {
  # a wins
   } elsif ($vb  $va) {
  # b wins
   } else {
  # draw
   }
}

If we have grep as a method in Any, the call to grep will autothread,
returning a junction of the values, so, as $a is any(11, 21, 31), $va
would be any(11,21,()), which should collapse as expected.

 Now, I'm not sure I know how to return nothing in Perl6, but I'll  
 guess that undef can serve the purpose, since I can't think of a  
 useful use of undef as part of a Junction.

Well, you return nothing simply by calling return; it will produce an
empty capture, which could be seen simply as ().

daniel



Re: On Junctions

2009-03-30 Thread Jon Lang
On Sun, Mar 29, 2009 at 10:57 PM, Mark Lentczner ma...@glyphic.com wrote:
 What I see here is that there is a tendency to want to think about, and
 operate on, the eigenstates as a Set, but this seems to destroy the single
 value impersonation of the Junction.

In my case, this tendency comes more from a desire to be able to
reverse the creation of a junction: you create a (singular) junction
from a (plural) list ('1|3|5' === 'any 1, 3, 5'); so I naturally want
to be able to (more or less) reverse this process and create a
(plural) Set from a (singular) junction.

 Further, if one ever calls .!eigenstates() on a Junction, then you have
 really bollox'd your code up, as then this code fails if the value you
 thought was a Junction happens to be, actually, just a single value!
  (Unless .!eigenstates() is defined on Object, and returns a Set of self...)

Which is why I'd _want_ eigenstates to be callable on an Object as
described - and, in general, _any other_ function that operates
directly on junctions should be able to accept Objects as well,
treating the Object as a one-eigenstate junction.

Otherwise, the moment you write a function that passes a junction as a
parameter, your code will break if you ever try to pass an Object in
instead.  And the only other ways to avoid that would be: 1. to
provide a means of testing whether or not something is a junction, or
2. to forbid anyone from ever using junction in a signature.

 I think what is needed is a single value threshing function, which can be
 applied to, well, single values.  Such a function would take a value and a
 predicate, and if the predicate applied to the value is true, returns the
 value, else it returns... nothing. If such a function were applied to a
 Junction, then the result would be a Junction of just those those
 eigenstates that passed this function.  The nothings would not end up
 contributing to the Junction.

...that could work.  The only catch is that if you ever want to get a
list of the cases that passed so that you can operate on them
individually, you'd still need a means of extracting the eigenstates
from the junction.

 Now, I'm not sure I know how to return nothing in Perl6, but I'll guess
 that undef can serve the purpose, since I can't think of a useful use of
 undef as part of a Junction.

As Daniel indicated, returning an empty list should work.

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-29 Thread Moritz Lenz
Jon Lang wrote:
 I stand corrected.  That said: with the eigenstates method now
 private, it is now quite difficult to get a list of the eigenstates of
 the above expression.

I thought about that a bit, and I think eigenstates are not hard to
extract (which somehow makes the privateness of .eigstates a bit
absurd), simply by autothreading:

sub e(Object $j) {
  my @states;
  - Any $x { @states.push($x) }.($j);
  return @states;
}

Cheers,
Moritz


Re: On Sets (Was: Re: On Junctions)

2009-03-29 Thread John Macdonald
On Sat, Mar 28, 2009 at 10:39:01AM -0300, Daniel Ruoso wrote:
 That happens because $pa and $pb are a singular value, and that's how
 junctions work... The blackjack program is an example for sets, not
 junctions.
 
 Now, what are junctions good for? They're good for situation where it's
 collapsed nearby, which means, it is used in boolean context soon
 enough. Or where you know it's not going to cause the confusion as in
 the above code snippet.

Unfortunately, it is extremely common to follow up a boolean is this
true with either if so, how and/or if not, why not.  A boolean test
is almost always the first step toward dealing with the consequences,
and that almost always requires knowing not only what the result of the
boolean test were, but which factors caused it to have that result.

The canonical example of quantum computing is using it to factor huge
numbers to break an encryption system.  There you divide the huge number
by the superposition of all of the possible factors, and then take the
eigenstate of the factors that divide evenly to eliminate all of the
huge pile of potential factors that did not divide evenly.  Without
being able to take the eigenstate, the boolean answer yes, any(1..n-1)
divides n is of very little value.


Re: On Sets (Was: Re: On Junctions)

2009-03-29 Thread Jon Lang
On Sun, Mar 29, 2009 at 1:18 PM, John Macdonald j...@perlwolf.com wrote:
 On Sat, Mar 28, 2009 at 10:39:01AM -0300, Daniel Ruoso wrote:
 That happens because $pa and $pb are a singular value, and that's how
 junctions work... The blackjack program is an example for sets, not
 junctions.

 Now, what are junctions good for? They're good for situation where it's
 collapsed nearby, which means, it is used in boolean context soon
 enough. Or where you know it's not going to cause the confusion as in
 the above code snippet.

 Unfortunately, it is extremely common to follow up a boolean is this
 true with either if so, how and/or if not, why not.  A boolean test
 is almost always the first step toward dealing with the consequences,
 and that almost always requires knowing not only what the result of the
 boolean test were, but which factors caused it to have that result.

True point.  Along these lines, I'd like to see at least one
threshing function that separates a junction's eigenstates that
passed a boolean test from those that didn't.  I can see several
possible semantics for such:

  1. It returns a list of the eigenstates that passed the test.

  2. It returns a junction composed of only those parts of the
junction which passed the test.

  3. It returns a two-item list: the wheat and the chaff.  The form
that the items take would conform to one of the first two options.

The G[op] proposal could be thought of as one approach to the first
option.  Note also that this option can be turned into a generic list
all of the eigenstates function by choosing a test that every
possible eigenstate is guaranteed to pass; as such, it would be a very
small step from this sort of threshing function to a public
.eigenstates method - e.g., $j.eigenstates :where { ... } (to add
optional threshing capabilities to a list of eigenstates function)
or * G~~ $j (to use a thresher to retrieve all of the eigenstates).

The infix:where (junction, Code -- junction) proposal that I made
earlier is an example of the second option.  This option has the
advantage that it preserves as much of the junction's internal
structure (e.g., composite junctions) as possible, in case said
structure may prove useful later on.  (I'm a big fan of not throwing
anything away until you're sure that you don't need it anymore.)  The
downside is that if you want a list of the eigenstates that passed the
test, this is only an intermediate step to getting it: you still have
to figure out how to extract a list of eigenstates from the threshed
junction.

The third option has the benefit of letting you handle if so  if
not without having to thresh twice, once for the wheat and again for
the chaff.  OTOH, it's bound to be more complicated to work with, and
is overkill if you only care about one of the outcomes.  I have no
syntax proposals at this time.

Note further that these aren't necessarily mutually exclusive options:
TIMTOWTDI.  I prefer the ones that use some form of where; but
that's just because those approaches feel intuitive to me.

 The canonical example of quantum computing is using it to factor huge
 numbers to break an encryption system.  There you divide the huge number
 by the superposition of all of the possible factors, and then take the
 eigenstate of the factors that divide evenly to eliminate all of the
 huge pile of potential factors that did not divide evenly.  Without
 being able to take the eigenstate, the boolean answer yes, any(1..n-1)
 divides n is of very little value.

Right.  Something like:

any(2 ..^ $n).eigenstates :where($n mod $_ == 0)

or:

( any(2 ..^ $n) where { $n mod $_ == 0 } ).eigenstates

...might be ways to get a list of the factors of $n.  (I'm not sure
how this would be done with junctions and the proposed grep
metaoperator - although I _can_ see how to do it with _just_ the
metaoperator, or with just a grep method.  But that's list
manipulation, not junctive processing.)  Of course, evaluating this
code could be a massive headache without a quantum processor.

I'm sure that one _could_ come up with a Set-based approach to doing
this; it might even be fairly easy to do.  But again, TIMTOWTDI.  Perl
has never been about trying to come up with an ideal approach and
then forcing everyone to use it - that would be LISP, among others.
Telling people that they must use Sets instead of junctions in cases
such as this runs counter to the spirit of Perl.

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-29 Thread Mark Lentczner
What I see here is that there is a tendency to want to think about,  
and operate on, the eigenstates as a Set, but this seems to destroy  
the single value impersonation of the Junction.


Further, if one ever calls .!eigenstates() on a Junction, then you  
have really bollox'd your code up, as then this code fails if the  
value you thought was a Junction happens to be, actually, just a  
single value!  (Unless .!eigenstates() is defined on Object, and  
returns a Set of self...)


I think what is needed is a single value threshing function, which  
can be applied to, well, single values.  Such a function would take a  
value and a predicate, and if the predicate applied to the value is  
true, returns the value, else it returns... nothing. If such a  
function were applied to a Junction, then the result would be a  
Junction of just those those eigenstates that passed this function.   
The nothings would not end up contributing to the Junction.


Now, I'm not sure I know how to return nothing in Perl6, but I'll  
guess that undef can serve the purpose, since I can't think of a  
useful use of undef as part of a Junction.


sub suchthat(Any $v, predicate) { predicate($v) ?? $v !! undef }

So now:

$a = 1|2|3|4|5
say suchthat($a, odd)
 1|3|5

$b = 12345
say suchthat($a, odd)
 135

And in the poker example:

@p = 1|11, 2, 1|11;
@d = 1|11, 3, 1|11;

$pv = suchthat([+] @p, {$_ = 21})
$dv = suchthat([+] @d, {$_ = 21})

if $pv and (!$dv or $pv  $dv) { say 'p wins!' };

- MtnViewMark

Mark Lentczner
http://www.ozonehouse.com/mark/
m...@glyphic.com





Re: On Junctions

2009-03-28 Thread Damian Conway
 I stand corrected. That said: with the eigenstates method now private,
 it is now quite difficult to get a list of the eigenstates of the
 above expression.

Yes, that's a concern. Most of the interesting junction-based algorithms
I've developed in the past rely on two facilities: the ability to
extract eigenstates, and the ability to thresh a junction: to
determine which eigenstates caused a boolean expression involving the
junction to be true.

However, I suspect that if these two capabilities prove to be
all(not easy, very useful) in Perl 6, there will soon be a module
that facilitates them. ;-)

Damian


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Richard Hainsworth

Daniel Ruoso wrote:

The thing is that junctions are so cool that people like to use it for
more things than it's really usefull (overseeing that junctions are too
much powerfull for that uses, meaning it will lead to unexpected
behaviors at some point).
  

What are the general boundaries for junctions?

We know that engineering type problems should be solved using floating 
point variables rather than integers (although it is probable that an 
integer solution probably would be possible - it would be excessively 
complicated).


Perhaps, it might help to see some more examples of how junctions should 
be used?


Regards,
Richard


Re: On Junctions

2009-03-28 Thread Daniel Ruoso
Em Sáb, 2009-03-28 às 16:17 +1100, Damian Conway escreveu:
 Nested heterogeneous junctions are extremely useful. For example, the
 common factors of two numbers ($x and $y) are the eigenstates of:
 all( any( factors($x) ), any( factors($y) ) )

I think that's the exact case where we should be using sets instead...

  my $common_factors = factors($x) ∩ factors($y)

Assuming we have...

  multi infix:∩(List @a, List @b -- Set) {...}
  multi infix:∩(Set @a, Set @b -- Set) {...}
  ... and variants ...

But the semantics of sets are still somewhat blurry... there are some
possibilities:

  1) Sets are in the same level as junctions, but have no collapsing and
 allow you to get its values. The problem is if it autothreads on 
 method calls or not... It also makes $a  $b confuse...

  2) Set ~~ Any, and all the inteligence is made implementing multis, 
 it has the disadvantage that new operators will need to have 
 explicit implementations in order to get Set DWIMmery...

I have been unsure about that, but lately I'm mostly thinking option 2
is the sanest, which means we only get as much DWIMmery as explicitly
implemented (which may or may not be a good idea).

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Daniel Ruoso
Em Sáb, 2009-03-28 às 13:36 +0300, Richard Hainsworth escreveu:
 Daniel Ruoso wrote:
  The thing is that junctions are so cool that people like to use it for
  more things than it's really usefull (overseeing that junctions are too
  much powerfull for that uses, meaning it will lead to unexpected
  behaviors at some point).   
 What are the general boundaries for junctions?

Junctions are superposition of values with a given collapsing type.

The most important aspect of junctions is that they are a singular
value, which means that they are transparent to the code using it. You
always use it as a singular value, and that's what keep its semantics
sane.

The boundary is where you try to use a junction as a plural value, and
that's where the semantics get weird...

 Perhaps, it might help to see some more examples of how junctions should 
 be used?

They should be used as a singular value... which means that the
blackjack example is only a good example for junctions, as far as to
know if the user has busted.

my @hand = 1|11, 9, 1|11;
my $sum = [+] @hand;
if ($sum = 21) {
   # valid game
} else {
   # busted!
}

The semantic is sane that way because it doesn't make a difference if
there is a junction or not...

my @hand = 6, 9, 6;
my $sum = [+] @hand;
if ($sum = 21) {
   # valid game
} else {
   # busted!
}

But even to compare two hands it gets weird...

my @a = 1|11, 9, 1|11;
my @b = 6,9,6;
my $pa = [+] @a;
my $pb = [+] @b;
if ($pa = 21  $pb = 21) {
   if ($pa  $pb) {
# B0RK3D
   }
}

That happens because $pa and $pb are a singular value, and that's how
junctions work... The blackjack program is an example for sets, not
junctions.

Now, what are junctions good for? They're good for situation where it's
collapsed nearby, which means, it is used in boolean context soon
enough. Or where you know it's not going to cause the confusion as in
the above code snippet.

Sets can provide the cool DWIMmery junction provides for the blackjack
case and still provide sane semantics for you to get its compound
values.

daniel



Re: On Junctions

2009-03-28 Thread Patrick R. Michaud
On Fri, Mar 27, 2009 at 05:49:02PM -0400, Henry Baragar wrote:
 I believe that there are hands where $p = 15|26 which would not beat a  
 hand where $d = 17.

 I believe that the correct way to calculate the value of the hand is:

my $p = ([+] @p).map{.eigenstates}.grep{$_  21}.max;

Since the result of [+] is a scalar we don't need to 'map' it. 
Assuming that .eigenstates exists it would then be

my $p = ([+] @p).eigenstates.grep({ $_  21 }).max

Pm


Re: On Junctions

2009-03-28 Thread Jon Lang
Daniel Ruoso wrote:
 But the semantics of sets are still somewhat blurry... there are some
 possibilities:

  1) Sets are in the same level as junctions, but have no collapsing and
     allow you to get its values. The problem is if it autothreads on
     method calls or not... It also makes $a  $b confuse...

  2) Set ~~ Any, and all the inteligence is made implementing multis,
     it has the disadvantage that new operators will need to have
     explicit implementations in order to get Set DWIMmery...

 I have been unsure about that, but lately I'm mostly thinking option 2
 is the sanest, which means we only get as much DWIMmery as explicitly
 implemented (which may or may not be a good idea).

My understanding is that Set operates on the same level as Hash and
List - indeed, a Set could be thought of as a Hash that only cares
about the keys but not the values, and has a few additional methods
(i.e., the set operations).

That is, a junction is an item with an indeterminate value; but a Set
is a collection of values in the same way that a hash is.  And the
proper sigil for a Set is %, not $.

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread TSa (Thomas Sandlaß)
HaloO,

On Friday, 27. March 2009 12:57:49 Daniel Ruoso wrote:
 1 - multi infix:+(Set $set, Num $a)
 This would return another set, with each value of $set summed with $a.

I think that this mixed case should numify the set to
the number of elements to comply with array semantics.
infix:+ should remain a numeric operator and numify
other operant types. This operator orientation is a
strong feature of Perl 6 and should not be diluted by
overloads with non-numeric meanings.


 2 - multi infix:+(Set $a, Set $b)
 This would return another set, with $a.values X+ $b.values, already
 removing duplicated values, as expected from a set.

Even the homogeneous case should adhere to numeric semantics.
Set operations are with parens. So disjoint union creation
is (+). We could try to get a meta parens so that (X+) is
conceivably auto-generated. OTOH it collides with (+) visually.


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


Re: On Junctions

2009-03-28 Thread Henry Baragar



Patrick R. Michaud wrote:

On Fri, Mar 27, 2009 at 05:49:02PM -0400, Henry Baragar wrote:
  
I believe that there are hands where $p = 15|26 which would not beat a  
hand where $d = 17.


I believe that the correct way to calculate the value of the hand is:

   my $p = ([+] @p).map{.eigenstates}.grep{$_  21}.max;



Since the result of [+] is a scalar we don't need to 'map' it. 
Assuming that .eigenstates exists it would then be


my $p = ([+] @p).eigenstates.grep({ $_  21 }).max
  
Argh... the multiple personalities of the junction caused me to forget 
that there is only one scalar!   HB

Pm
  




Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Jon Lang
On Sat, Mar 28, 2009 at 6:39 AM, Daniel Ruoso dan...@ruoso.com wrote:
 Em Sáb, 2009-03-28 às 13:36 +0300, Richard Hainsworth escreveu:
 Daniel Ruoso wrote:
  The thing is that junctions are so cool that people like to use it for
  more things than it's really usefull (overseeing that junctions are too
  much powerfull for that uses, meaning it will lead to unexpected
  behaviors at some point).
 What are the general boundaries for junctions?

 Junctions are superposition of values with a given collapsing type.

 The most important aspect of junctions is that they are a singular
 value, which means that they are transparent to the code using it. You
 always use it as a singular value, and that's what keep its semantics
 sane.

Closely related to this is that junctions autothread.  If you type in
foo($a | $b), it will be processed exactly as if you had typed
foo($a) | foo($b) - that is, it will call foo twice, once for $a and
once for $b, and it won't care which order it uses.  And this is true
whether or not you know that a junction is involved.  Given 'foo($j)',
foo will be called once if $j isn't a junction, and will be called
multiple times if $j is a junction.

If you were dealing with a Set instead, you'd need to make use of
'map' and/or hyperoperators to achieve a similar result.

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Jon Lang
Thomas Sandlaß wrote:
 Set operations are with parens.

Which Synopsis is this in?

-- 
Jonathan Dataweaver Lang


Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Henry Baragar



Daniel Ruoso wrote:


But even to compare two hands it gets weird...

my @a = 1|11, 9, 1|11;
my @b = 6,9,6;
my $pa = [+] @a;
my $pb = [+] @b;
if ($pa = 21  $pb = 21) {
   if ($pa  $pb) {
# B0RK3D
   }
}

That happens because $pa and $pb are a singular value, and that's how
junctions work... The blackjack program is an example for sets, not
junctions.
  
The blackjack program is an excellent example for junctions (and not so 
good for sets, IMHO).  The problem in the example above is that the 
calculation of the value of a hand was not completed.  The complete 
calculation is as follows:


   my $pa = ([+] @a).eigenstates.grep{$_ 21}.max

If the result is undef, then the @a hand is a bust, and comparing $pa to 
a similarly calculated $pb is sane.


Henry

daniel

  




Re: On Sets (Was: Re: On Junctions)

2009-03-28 Thread Jon Lang
Henry Baragar wrote:
 The blackjack program is an excellent example for junctions (and not so good
 for sets, IMHO).  The problem in the example above is that the calculation
 of the value of a hand was not completed.  The complete calculation is as
 follows:

   my $pa = ([+] @a).eigenstates.grep{$_ 21}.max

Per the recent change to the synopses, eigenstates is now a private
method, rendering the above code invalid.

-- 
Jonathan Dataweaver Lang


On Junctions

2009-03-27 Thread Richard Hainsworth
The following arose out of a discussion on #perl6. Junctions are new and 
different from anything I have encountered, but I cant get rid of the 
feeling that there needs to be some more flexibility in their use to 
make them a common programming tool.


Background: Imagine a hand of cards. Cards may be Ace, Two, Three. Ace 
having either the values 1 or 11, depending on context, the other cards 
their face value. Sums of a hand over 21 are invalid.

Hands with multiple junctions become interesting, eg.,
p: Ace, Two, Ace
d: Ace, Three, Ace

Given that Ace has a value of 1 or 11 depending on context, it would 
seem natural to use a junction. Hence the two hands can be expressed as:

@p = 1|11, 2, 1|11;
@d = 1|11, 3, 1|11;

If we use [+] to add these, we get
$p = [+] @p; say $p.perl; # any(any(4,14),any(14,24))
$d = [+] @d; say $d.perl; #any(any(5,15),any(15,25))

Since the values of 24  25 are greater than 21, they must be eliminated 
from consideration.

What we want is for hand @d to beat hand @p because 15  14

On #perl6, rouso, masak and moritz_ explained that I am incorrectly 
thinking about junctions as sets and that for this task I should be 
using another perl idiom, namely lists. Something like:

moritz_ rakudo: ([1,11], 3, [1,11]).reduce({@($^a) X+ @($^b)})
p6eval  rakudo bb22e0: RESULT«[5, 15, 15, 25]»

Then the out-of-limit values (in the above case 25) can be stripped off 
using grep, viz.,

# here we have ([1,11],3,[1,11]) instead of (1|11, 3, 1|11)
my @dlist = grep { $_  21 } ([1,11], 3, [1,11]).reduce({@($^a) X+ @($^b)});

Then the two lists (do the same for @p) can be compared by a junction 
comparison of the form

if any(@plist)  all(@dlist) { say 'p wins' };

The problem is not just that [+] @p produces a junction with undesired 
(21) eigenstates, but that the [+] @d produces a junction of the form

any(any(5,15),any(15,25)) which should collapse to any(5,15,25)
whereas we want a junction of the form
all(5,15,25)

After the #perl6 conversation, I thought some more. A junction is a neat 
way of expressing the hand, but the junction needs to be converted to a 
list to do some processing, and then the lists are compared using junctions.


I think (I might be wrong) that the conversion from a junction to a list 
is specified by the .eigenstates method, but it doesn't seem to 
completely flatten a junction yet - it produces the 
any(any(4,14),any(14,24)) output shown above.


So my questions to the language list are:

a) Am I trying to fit a square peg in a round hole by applying junctions 
to this sort of problem? If so, would it be possible to explain what the 
limits are to the junction approach, or another way of expressing this 
question: what sort of problems should junctions be applied to?


b) Why would it be wrong to have a method for eliminating eigenstates 
from a junction? (The answer to this might naturally arise out of the 
answer to a). However, ...


In a wider context, I would conjecture that some algorithms to which 
junctions could be applied would be optimised if some states could be 
eliminated, a bit like tree-pruning optimisations that eliminate paths 
which can never produce a correct answer. Consequently, providing a 
filtering method would increase the usefulness of the junction as a 
programming tool. Perhaps


$new-junction = $old-junction.grep({ $_ = 21 }); # not sure if the 
parens are needed here


c) On junction algebra, am I wrong or is always true that a junction of 
the form
any('x','y','z', any('foo','bar'), 1, 2, 3) should collapse to 
any('x','y','z','foo','bar',1,2,3)


In other words, if an 'any' junction is contained in an outer 'any', the 
inner 'any' can be factored out?

This would eliminate the nested junctions produced by .eigenstates

d) Am I right in thinking this is also true for nested 'all' junctions? viz.
all(1,2,3,all('foo', 'bar')) collapses to all(1,2,3,'foo','bar')

e) Conjecture: This true of all junction types, eg.,
junc(..., junc(...)) == junc(..., ...)

f) Would it be possible to have a means to coerce an 'any' junction into 
an 'all' junction or vice versa? eg.
my $old-junction = 1|2|3; my $new-junction = all{$old-junction}; say 
$old-junction.perl

# all(1,2,3)
Using () creates a new junction all(any(1,2,3))
{} are undefined for junctions.

If my suggestions prove acceptable, then for my problem I would have:
# @p  @d get defined as arrays of junctions, eg.

my @p=1|11,2,1|11;
my @d=1|11,3,1|11;

#later
my $p = ([+] @p).grep { $_  21 };
my $d = ([+] @d).grep { $_  21 };
if $p  all{$d} { say 'p wins' } else { say 'd wins' };

Richard (finanalyst)



On Sets (Was: Re: On Junctions)

2009-03-27 Thread Daniel Ruoso
Em Sex, 2009-03-27 às 13:36 +0300, Richard Hainsworth escreveu:
 On #perl6, rouso, masak and moritz_ explained that I am incorrectly 
 thinking about junctions as sets and that for this task I should be 
 using another perl idiom, namely lists.

Sorry for not taking each individual point on your mail, but I think
this basically narrows down to the fact that we need some more
definitions of what kinds of things we would do with sets.

The thing is that junctions are so cool that people like to use it for
more things than it's really usefull (overseeing that junctions are too
much powerfull for that uses, meaning it will lead to unexpected
behaviors at some point).

So I get that we do need some cool support for sets as well, I mean...
no collapsing, no autothreading... but maybe some specific behaviors...

taking the blackjack example...

# using the set function as illustration only...
my @hand = set(1,11),3,set(1,11);
my $sum = [+] @hand;

This operation could use some magic so $sum could become

set(5,15,25)

Where it doesn't autothread, nor collapses... but it still provides the
DWIMmery people like so much in junctions...

So... which magic happened here?

1 - multi infix:+(Set $set, Num $a)
This would return another set, with each value of $set summed with $a.

2 - multi infix:+(Set $a, Set $b)
This would return another set, with $a.values X+ $b.values, already
removing duplicated values, as expected from a set.

So... what do you think?

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Daniel Ruoso
Em Sex, 2009-03-27 às 08:57 -0300, Daniel Ruoso escreveu:
 So I get that we do need some cool support for sets as well, I mean...
 no collapsing, no autothreading... but maybe some specific behaviors...

As an aditional idea...

multi infix:⋃(Set $a, Set $b) {...}
multi infix:⋂(Set $a, Set $b) {...}
...as well as the rest of the set theory...

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Mark J. Reed
From a high-level perspective, the blackjack example seems perfect for
junctions.  An Ace isn't a set of values - its one or the other at a
time.  It seems to me if you can't make it work with junctions - f you
have to use sets instead - then there's something wrong with the
implementation of junctions.



On 3/27/09, Daniel Ruoso dan...@ruoso.com wrote:
 Em Sex, 2009-03-27 às 08:57 -0300, Daniel Ruoso escreveu:
 So I get that we do need some cool support for sets as well, I mean...
 no collapsing, no autothreading... but maybe some specific behaviors...

 As an aditional idea...

 multi infix:⋃(Set $a, Set $b) {...}
 multi infix:⋂(Set $a, Set $b) {...}
 ...as well as the rest of the set theory...

 daniel



-- 
Sent from my mobile device

Mark J. Reed markjr...@gmail.com


Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Daniel Ruoso
Em Sex, 2009-03-27 às 09:17 -0400, Mark J. Reed escreveu:
 From a high-level perspective, the blackjack example seems perfect for
 junctions.  An Ace isn't a set of values - its one or the other at a
 time.  It seems to me if you can't make it work with junctions - f you
 have to use sets instead - then there's something wrong with the
 implementation of junctions.

It would be a junction if the only question was is it bigger than
21?...

but that is not the case, it looks more like...

Given S as the set of possible sums,
Given V as a subset of S where  21
Given I as a subset of S where  21
If V is empty, Define X as the minimum value of I
Else, Define X as the maximum value in V

Which really looks like set operations...

daniel



Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Moritz Lenz
Mark J. Reed wrote:
 From a high-level perspective, the blackjack example seems perfect for
 junctions.  An Ace isn't a set of values - its one or the other at a
 time.  It seems to me if you can't make it work with junctions - f you
 have to use sets instead - then there's something wrong with the
 implementation of junctions.

That seems as naiive as saying regular expressions are for parsing
text, and if you can't parse XML with regular expressions, there's
something wrong with them .

Leaving aside that Perl 6 regexes do parse XML ;-), we could ask
ourselves why junctions aren't suited. The answer is that an any()
junction represents just what it says - a conjunction of *any* values,
not some of the any values. The example would perfectly work if there
was nothing to filter out. You'd need 'some-of-any' junction here, which
we don't support.

Cheers,
Moritz

-- 
Moritz Lenz
http://perlgeek.de/ |  http://perl-6.de/ | http://sudokugarden.de/


Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Mark J. Reed
On Fri, Mar 27, 2009 at 10:27 AM, Moritz Lenz
ml...@physik.uni-wuerzburg.de wrote:
 Mark J. Reed wrote:
 From a high-level perspective, the blackjack example seems perfect for
 junctions.  An Ace isn't a set of values - its one or the other at a
 time.  It seems to me if you can't make it work with junctions - f you
 have to use sets instead - then there's something wrong with the
 implementation of junctions.

 That seems as naiive as saying regular expressions are for parsing
 text, and if you can't parse XML with regular expressions, there's
 something wrong with them .

Well, I was being intentionally naive.  As I said, looking down from
above.  In thinking about examples for explaining junctions, this one
seems a natural fit.

 Leaving aside that Perl 6 regexes do parse XML ;-)

So do Perl 5 ones - since they're not true formal regexes, but have
more power to e.g. match balanced tags.  Plus of course you wouldn't
normally try to write one regex to match an XML document; there'd be
wrapper logic.

Now if you actually parse XML that way, you're being quite silly.
It's far from the best approach.   But while maybe junctions aren't
the best approach to the Blackjack problem, either, it seems less
clear to me.  Maybe that's just because I have less experience with
junctions.

 The answer is that an any()  junction represents just what it says - a 
 conjunction of *any*
 values,not some of the any values. The example would perfectly work if there
 was nothing to filter out. You'd need 'some-of-any' junction here, which
 we don't support.

So at the moment you have to explicitly extract the eigenstates you're
interested in, and then construct new junctions from them. Something
like this:

some($d)  21  some($p)  21  any(grep { $_  21 }
$d.eigenstates})  all(grep { $_  21 } $p.eigenstates)

But it still seems that junctions let you do this more cleanly than
sets.  Or maybe P6 Sets are more powerful than I think?  Given two
junctions $d and $p, just adding $d + $p gives you all the possible
sums of the eigenstates.  Given two sets D and P, is there an equally
simple op to generate { d + p : d ∈ D, p ∈ } ?

-- 
Mark J. Reed markjr...@gmail.com


Re: On Sets (Was: Re: On Junctions)

2009-03-27 Thread Mark J. Reed
On Fri, Mar 27, 2009 at 11:45 AM, Mark J. Reed markjr...@gmail.com wrote:
 Given two
 junctions $d and $p, just adding $d + $p gives you all the possible
 sums of the eigenstates.  Given two sets D and P, is there an equally
 simple op to generate { d + p : d ∈ D, p ∈ } ?

Dropped a P there - should be { d + p : d ∈ D, p ∈ P }

-- 
Mark J. Reed markjr...@gmail.com


Re: On Junctions

2009-03-27 Thread Dave Whipp

Richard Hainsworth wrote:
The following arose out of a discussion on #perl6. Junctions are new and 
different from anything I have encountered, but I cant get rid of the 
feeling that there needs to be some more flexibility in their use to 
make them a common programming tool.


I strongly agree with you, but Larry has repeatedly said that he wants 
to view Junctions as lexical sugar rather than as a powerful programming 
tool. So I'm thinking that we'll need to experiment with modules before 
anything gets admitted to the core language.



If my suggestions prove acceptable, then for my problem I would have:
# @p  @d get defined as arrays of junctions, eg.

my @p=1|11,2,1|11;
my @d=1|11,3,1|11;

#later
my $p = ([+] @p).grep { $_  21 };
my $d = ([+] @d).grep { $_  21 };
if $p  all{$d} { say 'p wins' } else { say 'd wins' };


I think that the all{..} notation is a little too subtle, and somewhat 
clumsy (what if there are one or none junctions in $d? do you want 
to splat them all?).


The way I'd view this (before optimization) is:

my $p = (reverse 1..21).first: { $_ == [+] @p };
my $d = (reverse 1..21).first: { $_ == [+] @d };

if! $p{ say player bust }
elsif ! $d{ say dealer bust }
elsif $p  $d { say player wins }
else  { say dealer wins }

If this is the structure of the problem, the question then becomes how 
to move from this brute force implementation to something more elegant 
(analytical).


I discuss this on http://dave.whipp.name/sw/perl6/perl6_xmas_2008.html. 
I've revised my ideas a little since then (by proposing a more general 
grep metaoperator G[op] that has applicability beyond junctions) but 
the basic concepts mesh with yours, I think.


Re: On Junctions

2009-03-27 Thread Jon Lang
On Fri, Mar 27, 2009 at 10:39 AM, Dave Whipp d...@dave.whipp.name wrote:
 Richard Hainsworth wrote:

 The following arose out of a discussion on #perl6. Junctions are new and
 different from anything I have encountered, but I cant get rid of the
 feeling that there needs to be some more flexibility in their use to make
 them a common programming tool.

 I strongly agree with you, but Larry has repeatedly said that he wants to
 view Junctions as lexical sugar rather than as a powerful programming tool.
 So I'm thinking that we'll need to experiment with modules before anything
 gets admitted to the core language.

Maybe you could have something like a filter function that takes a
junction and a test condition and returns a junction of those
eigenstates from the original one that passed the test.  You could
then handle the Blackjack problem by saying something to the effect
of:

   $p = [+] @p;
   $d = [+] @d;
if $p = 21 { # Could the total be 21 or less?
$p where= { $_ = 21 } #[ infix:where filters the junction
according to the given criteria. ]
if $p  $d { say you won! }
} else { say you went over. }

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-27 Thread Henry Baragar



Richard Hainsworth wrote:
The following arose out of a discussion on #perl6. Junctions are new 
and different from anything I have encountered, but I cant get rid of 
the feeling that there needs to be some more flexibility in their use 
to make them a common programming tool.


Background: Imagine a hand of cards. Cards may be Ace, Two, Three. Ace 
having either the values 1 or 11, depending on context, the other 
cards their face value. Sums of a hand over 21 are invalid.

Hands with multiple junctions become interesting, eg.,
p: Ace, Two, Ace
d: Ace, Three, Ace

Given that Ace has a value of 1 or 11 depending on context, it would 
seem natural to use a junction. Hence the two hands can be expressed as:

@p = 1|11, 2, 1|11;
@d = 1|11, 3, 1|11;

If we use [+] to add these, we get
$p = [+] @p; say $p.perl; # any(any(4,14),any(14,24))
$d = [+] @d; say $d.perl; #any(any(5,15),any(15,25))

Since the values of 24  25 are greater than 21, they must be 
eliminated from consideration.

What we want is for hand @d to beat hand @p because 15  14

On #perl6, rouso, masak and moritz_ explained that I am incorrectly 
thinking about junctions as sets and that for this task I should be 
using another perl idiom, namely lists. Something like:

moritz_ rakudo: ([1,11], 3, [1,11]).reduce({@($^a) X+ @($^b)})
p6eval  rakudo bb22e0: RESULT«[5, 15, 15, 25]»

Then the out-of-limit values (in the above case 25) can be stripped 
off using grep, viz.,

# here we have ([1,11],3,[1,11]) instead of (1|11, 3, 1|11)
my @dlist = grep { $_  21 } ([1,11], 3, [1,11]).reduce({@($^a) X+ 
@($^b)});


Then the two lists (do the same for @p) can be compared by a junction 
comparison of the form

if any(@plist)  all(@dlist) { say 'p wins' };

The problem is not just that [+] @p produces a junction with undesired 
(21) eigenstates, but that the [+] @d produces a junction of the form

any(any(5,15),any(15,25)) which should collapse to any(5,15,25)
whereas we want a junction of the form
all(5,15,25)

After the #perl6 conversation, I thought some more. A junction is a 
neat way of expressing the hand, but the junction needs to be 
converted to a list to do some processing, and then the lists are 
compared using junctions.


I think (I might be wrong) that the conversion from a junction to a 
list is specified by the .eigenstates method, but it doesn't seem to 
completely flatten a junction yet - it produces the 
any(any(4,14),any(14,24)) output shown above.


So my questions to the language list are:

a) Am I trying to fit a square peg in a round hole by applying 
junctions to this sort of problem? If so, would it be possible to 
explain what the limits are to the junction approach, or another way 
of expressing this question: what sort of problems should junctions be 
applied to?


b) Why would it be wrong to have a method for eliminating 
eigenstates from a junction? (The answer to this might naturally arise 
out of the answer to a). However, ...


In a wider context, I would conjecture that some algorithms to which 
junctions could be applied would be optimised if some states could be 
eliminated, a bit like tree-pruning optimisations that eliminate paths 
which can never produce a correct answer. Consequently, providing a 
filtering method would increase the usefulness of the junction as a 
programming tool. Perhaps


$new-junction = $old-junction.grep({ $_ = 21 }); # not sure if the 
parens are needed here


c) On junction algebra, am I wrong or is always true that a junction 
of the form
any('x','y','z', any('foo','bar'), 1, 2, 3) should collapse to 
any('x','y','z','foo','bar',1,2,3)


In other words, if an 'any' junction is contained in an outer 'any', 
the inner 'any' can be factored out?

This would eliminate the nested junctions produced by .eigenstates

d) Am I right in thinking this is also true for nested 'all' 
junctions? viz.

all(1,2,3,all('foo', 'bar')) collapses to all(1,2,3,'foo','bar')

e) Conjecture: This true of all junction types, eg.,
junc(..., junc(...)) == junc(..., ...)

f) Would it be possible to have a means to coerce an 'any' junction 
into an 'all' junction or vice versa? eg.
my $old-junction = 1|2|3; my $new-junction = all{$old-junction}; say 
$old-junction.perl

# all(1,2,3)
Using () creates a new junction all(any(1,2,3))
{} are undefined for junctions.

If my suggestions prove acceptable, then for my problem I would have:
# @p  @d get defined as arrays of junctions, eg.

my @p=1|11,2,1|11;
my @d=1|11,3,1|11;

#later
my $p = ([+] @p).grep { $_  21 };
my $d = ([+] @d).grep { $_  21 };
if $p  all{$d} { say 'p wins' } else { say 'd wins' };

I believe that there are hands where $p = 15|26 which would not beat a 
hand where $d = 17.


I believe that the correct way to calculate the value of the hand is:

   my $p = ([+] @p).map{.eigenstates}.grep{$_  21}.max;

which is exactly how I do it when I am playing Blackjack.

Put another way, the value of a blackjack hand is deterministic and 
sane, and you must get rid

Re: On Junctions

2009-03-27 Thread Dave Whipp
[I’d been planning to put this suggestion on hold until the spec is 
sufficiently complete for me to attempt to implement it as a module. But 
people are discussing this again, so maybe it's not just me. I apologize 
if I appear to be beating a dead horse...]


Jon Lang wrote:


Maybe you could have something like a filter function


yes, but


that takes a
junction and a test condition and returns a junction of those
eigenstates from the original one that passed the test. 


But why is this a useful thing to do? I think that you're proposing, for 
compound junctions:


ok any( 1|2, 12, 5|15, 515 ) where { $_  10 }
   === any( 1|2, 12, 5|15 )

To me, it still feels like you're thinking of a junction as a set of 
values, and inventing an operator specifically for the purpose of 
messing with those values. I do not see values of a junction as a 
meaningful user-level concept. I prefer to turn the problem around, and 
suggest a different operator, motivated by a different issue, and then 
apply that operator to junctions.



Consider this statement:

say (0..Inf).grep: { $_  10 };

I would expect it to take infinite time to complete (or else fail 
quickly). It would be wrong to expect perl to figure out the correct 
answer analytically, because that is impossible in the general case of 
an arbitrary code block. So I instead propose an operator-based grep:


say 0..inf G[] 10;
 [0..9]

This “grep metaoperator” can be expected to analytically determine the 
result (of grepping an infinite list) in finite time. It might also be 
used to avoid curlies for simple greps:


say @lines G~~ /foo/;

The operator exists to filter infinite lists in finite time. But it also 
solves the junction problem:


say (-Inf .. Inf) G== 3|4;
 [3,4]

say ^Int G== 3|4; ## assuming ^Int means “any Int value”
 [3,4]

$score = [+] 1|11, 1|11, 1+11, 1+11, 4;
say max( 1..21 G== $score ) // bust;
 18


Re: On Junctions

2009-03-27 Thread Jon Lang
Dave Whipp wrote:
 [I’d been planning to put this suggestion on hold until the spec is
 sufficiently complete for me to attempt to implement it as a module. But
 people are discussing this again, so maybe it's not just me. I apologize if
 I appear to be beating a dead horse...]

 Jon Lang wrote:

 Maybe you could have something like a filter function

 yes, but

 that takes a
 junction and a test condition and returns a junction of those
 eigenstates from the original one that passed the test.

 But why is this a useful thing to do? I think that you're proposing, for
 compound junctions:

 ok any( 1|2, 12, 5|15, 515 ) where { $_  10 }
   === any( 1|2, 12, 5|15 )

...not really, no.  The way I was looking at it, the above expression
is ultimately a junction of the values 1, 2, 5, and 15; no matter how
compounded the junction is, these would be its eigenstates.  Since 15
would fail the test, anything having to do with it would be filtered
out.  Exactly how that would work with a compound junction, I'm not
sure; as I said, I was thinking of the eigenstates as ordinary items,
not nested junctions.  But yes, I _was_ suggesting something that
transforms one junction into another.

That said, I'm also leery of compound junctions.  Please tell me the
difference between:

any( 1|2 )

...and:

any( 1, 2 )

If there is no difference, then:

 any( 1|2, 12, 5|15, 515 ) eqv any( 1, 2, 12, 5, 15, 515 )

For that matter, I'm not seeing a difference between:

any( 12 ) # any of all of (1, 2)

...and:

any( 1, 2 ) # any of (1, 2)

If I'm not mistaken on these matters, that means that:

any( 1|2, 12, 5|15, 515 ) eqv any(1, 2, 5, 15)

And I expect that similar rules hold for other compound junctions.  In
short, I won't be surprised if all compound junctions can flatten into
equivalent simple junctions.

 To me, it still feels like you're thinking of a junction as a set of values,
 and inventing an operator specifically for the purpose of messing with those
 values. I do not see values of a junction as a meaningful user-level
 concept.

I'm pretty sure that Larry agrees with you here, seeing as how his
latest revision concerning junctions makes direct access to a
junction's eigenstates very difficult to arrange.

 I prefer to turn the problem around, and suggest a different
 operator, motivated by a different issue, and then apply that operator to
 junctions.

 Consider this statement:

    say (0..Inf).grep: { $_  10 };

 I would expect it to take infinite time to complete (or else fail quickly).
 It would be wrong to expect perl to figure out the correct answer
 analytically, because that is impossible in the general case of an arbitrary
 code block. So I instead propose an operator-based grep:

    say 0..inf G[] 10;
     [0..9]

 This “grep metaoperator” can be expected to analytically determine the
 result (of grepping an infinite list) in finite time.

 It might also be used
 to avoid curlies for simple greps:

    say @lines G~~ /foo/;

 The operator exists to filter infinite lists in finite time. But it also
 solves the junction problem:

    say (-Inf .. Inf) G== 3|4;
     [3,4]

And how would it handle a compound junction (assuming they exist)?  That is:

say (-Inf .. Inf) G== any(1|2, 12, 5|15, 515);
 ???

    $score = [+] 1|11, 1|11, 1+11, 1+11, 4;

I assume you meant:

$score = [+] 1|11, 1|11, 4;

    say max( 1..21 G== $score ) // bust;
     18

...and the answer to that would be 16, right?

-- 
Jonathan Dataweaver Lang


Re: On Junctions

2009-03-27 Thread Damian Conway
Jon Lang wrote:

 For that matter, I'm not seeing a difference between:

any( 12 ) # any of all of (1, 2)

 ...and:

any( 1, 2 ) # any of (1, 2)

Those two are very different.

 any(1,2) == 2  is true

 any(12) == 2  is false


Nested heterogeneous junctions are extremely useful. For example, the
common factors of two numbers ($x and $y) are the eigenstates of:

all( any( factors($x) ), any( factors($y) ) )


 If I'm not mistaken on these matters, that means that:

any( 1|2, 12, 5|15, 515 ) eqv any(1, 2, 5, 15)

No. They have equivalent eigenstates, but they are not themselves equivalent.
For example, any( 1|2, 12, 5|15, 515 ) compares == to 12;
whereas any(1, 2, 5, 15) doesn't.


 And I expect that similar rules hold for other compound junctions.  In
 short, I won't be surprised if all compound junctions can flatten into
 equivalent simple junctions.

In general, they can't; not without changing their meaning.

Damian


Re: On Junctions

2009-03-27 Thread Jon Lang
Damian Conway wrote:
 Jon Lang wrote:

 For that matter, I'm not seeing a difference between:

    any( 12 ) # any of all of (1, 2)

 ...and:

    any( 1, 2 ) # any of (1, 2)

 Those two are very different.

     any(1,2) == 2  is true

     any(12) == 2  is false


 Nested heterogeneous junctions are extremely useful. For example, the
 common factors of two numbers ($x and $y) are the eigenstates of:

    all( any( factors($x) ), any( factors($y) ) )

I stand corrected.  That said: with the eigenstates method now
private, it is now quite difficult to get a list of the eigenstates of
the above expression.

-- 
Jonathan Dataweaver Lang


Re: .perl and other methods on Junctions?

2008-11-08 Thread Patrick R. Michaud
On Wed, Nov 05, 2008 at 11:28:00AM -0800, Larry Wall wrote:
 But it seems to me that if stringification of a junction returns a
 correct .perlish syntax, it's probably better to just let that happen
 lazily, on the assumption someone might want .perl to autothread for
 some reason, perhaps because .perl performs some kind of useful
 canonicalization prior to comparison.
 
 So I think the actual choice is driven by the fact that Str(Junction)
 is defined to work like you'd expect .perl to do if .perl did it,
 which it doesn't...

This all works for me, thanks for the clarification!

Pm


Re: .perl and other methods on Junctions?

2008-11-05 Thread Larry Wall
On Tue, Nov 04, 2008 at 01:33:09PM -0600, Patrick R. Michaud wrote:
: Consider the code:
: 
: my $x = 3 | 'foo';
: my $y = $x.perl;
: 
: 
: Does $y end up as a junction of strings or as a single string?

I think it may not actually matter much, if subsequent stringification
of the junction produces a result with correct Perl syntax.

: Asking more directly, does .perl autothread over a Junction?
: If .perl does not autothread, then is there some way of knowing
: which methods autothread and which do not?

I think it would depend entirely on whether the Junction class defined
method .perl, or relied on the authothreading implementation triggered
by Object recognizing that it was handed a Junction.

But it seems to me that if stringification of a junction returns a
correct .perlish syntax, it's probably better to just let that happen
lazily, on the assumption someone might want .perl to autothread for
some reason, perhaps because .perl performs some kind of useful
canonicalization prior to comparison.

So I think the actual choice is driven by the fact that Str(Junction)
is defined to work like you'd expect .perl to do if .perl did it,
which it doesn't...

: (The question of method autothreading over junctions came up at
: the OSCON 2008 hackathon, but I don't know that it was ever
: resolved.  If it was and I've just forgotten or overlooked the
: resolution,  I'll be happy to have it pointed out to me.)

Well, at the time we thought there might need to be some kind of
VAR-like JUNCTION macro to give access to the Junction object, but
if the decision is just based on whether Junction defines the method
or not, that's not really necessary.

And with this semantics, it's also no problem going the other way.
If method .junk is defined in Junction, you can still force it to
autothread by saying $junction.Object::junk().

Larry


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-27 Thread Moritz Lenz
Patrick R. Michaud wrote:
 On Mon, Aug 25, 2008 at 12:15:05AM +0200, Moritz Lenz wrote:
 Larry Wall wrote:
  I think it would be best if all boolean contexts collapse consistently,
  and I would consider all of those to be boolean contexts.  More
  precisely,  and || are boolean on the left, but not on the right.
 
 Very good.
 As a follow-up for the testers: should ok() expect an Object as its
 first argument? If so we could say
 
 ok 1|2, 'Junction 1|2 is true in boolean context';
 
 Keeping with my general philosophy that I'd like to keep
 the requirements needed to run Test.pm (and the test suite)
 as simple as possible, I'd prefer to not require type checking
 within Test.pm in order for it to work right.

 Beyond that, if we're testing a Junction in boolean
 context, I think I would prefer to make that an explicit
 part of the test itself:
 
 ok ?(1|2), 'Junction 1|2 is true in boolean context';

I re-wrote the tests to use that kind of syntax, and add it to the
official tests:
http://svn.pugscode.org/pugs/t/spec/S03-junctions/boolean-context.t

My next step will be to fudge it for rakudo.

Cheers,
Moritz


-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-24 Thread Moritz Lenz
Moritz Lenz wrote:
 Tests 34 to 36 were a bit overcritical:
 
 (0|undef  say not ok 34) || say not ok 34;
 (0undef  say not ok 35) || say not ok 35;
 (0^undef  say not ok 36) || say not ok 36;
 
 but are easily corrected. The rest seem fine to me.

Easier said than done.
Question to p6l: do  and || autothread? Or do they collapse the
junction prior to evaluation? (I hope the latter, since I think it's
more dwimmy).

Also do prefix:? and prefix:! collapse the junction?

Cheers,
Moritz

-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-24 Thread Larry Wall
On Sun, Aug 24, 2008 at 09:22:25PM +0200, Moritz Lenz wrote:
: Moritz Lenz wrote:
:  Tests 34 to 36 were a bit overcritical:
:  
:  (0|undef  say not ok 34) || say not ok 34;
:  (0undef  say not ok 35) || say not ok 35;
:  (0^undef  say not ok 36) || say not ok 36;
:  
:  but are easily corrected. The rest seem fine to me.
: 
: Easier said than done.
: Question to p6l: do  and || autothread? Or do they collapse the
: junction prior to evaluation? (I hope the latter, since I think it's
: more dwimmy).
: 
: Also do prefix:? and prefix:! collapse the junction?

I think it would be best if all boolean contexts collapse consistently,
and I would consider all of those to be boolean contexts.  More
precisely,  and || are boolean on the left, but not on the right.

Interestingly, ? and ?| collapse both sides because they coerce both
sides to boolean.  Either that, or we make neither side collapse,
if someone can come up with a use case for junctional booleans,
though I suspect the same purpose can be served by + and +| if you're
careful only to feed it 1 or 0.  So probably conceptual consistency
is better here.

Larry


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-24 Thread Patrick R. Michaud
On Sun, Aug 24, 2008 at 03:00:54PM -0700, Larry Wall wrote:
 : Question to p6l: do  and || autothread? Or do they collapse the
 : junction prior to evaluation? (I hope the latter, since I think it's
 : more dwimmy).
 : 
 : Also do prefix:? and prefix:! collapse the junction?
 
 I think it would be best if all boolean contexts collapse consistently,
 and I would consider all of those to be boolean contexts.  More
 precisely,  and || are boolean on the left, but not on the right.

Yay!  

I'm assuming the same holds true for the conditional expression
in C?? !!.

Thanks,

Pm


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-24 Thread Moritz Lenz
Larry Wall wrote:
 On Sun, Aug 24, 2008 at 09:22:25PM +0200, Moritz Lenz wrote:
 : Moritz Lenz wrote:
 :  Tests 34 to 36 were a bit overcritical:
 :  
 :  (0|undef  say not ok 34) || say not ok 34;
 :  (0undef  say not ok 35) || say not ok 35;
 :  (0^undef  say not ok 36) || say not ok 36;
 :  
 :  but are easily corrected. The rest seem fine to me.
 : 
 : Easier said than done.
 : Question to p6l: do  and || autothread? Or do they collapse the
 : junction prior to evaluation? (I hope the latter, since I think it's
 : more dwimmy).
 : 
 : Also do prefix:? and prefix:! collapse the junction?
 
 I think it would be best if all boolean contexts collapse consistently,
 and I would consider all of those to be boolean contexts.  More
 precisely,  and || are boolean on the left, but not on the right.

Very good.
As a follow-up for the testers: should ok() expect an Object as its
first argument? If so we could say

ok 1|2, 'Junction 1|2 is true in boolean context';

(Which has the nice side effect of not confusing fudge because more
tests are executed than expected).

Moritz


-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-24 Thread Larry Wall
On Sun, Aug 24, 2008 at 05:05:46PM -0500, Patrick R. Michaud wrote:
: On Sun, Aug 24, 2008 at 03:00:54PM -0700, Larry Wall wrote:
:  : Question to p6l: do  and || autothread? Or do they collapse the
:  : junction prior to evaluation? (I hope the latter, since I think it's
:  : more dwimmy).
:  : 
:  : Also do prefix:? and prefix:! collapse the junction?
:  
:  I think it would be best if all boolean contexts collapse consistently,
:  and I would consider all of those to be boolean contexts.  More
:  precisely,  and || are boolean on the left, but not on the right.
: 
: Yay!  
: 
: I'm assuming the same holds true for the conditional expression
: in C?? !!.

Indeed.

Larry


Re: [perl #58302] [BUG] binary junctions of undefs in boolean context fails (21/37)

2008-08-24 Thread Patrick R. Michaud
On Mon, Aug 25, 2008 at 12:15:05AM +0200, Moritz Lenz wrote:
 Larry Wall wrote:
  I think it would be best if all boolean contexts collapse consistently,
  and I would consider all of those to be boolean contexts.  More
  precisely,  and || are boolean on the left, but not on the right.
 
 Very good.
 As a follow-up for the testers: should ok() expect an Object as its
 first argument? If so we could say
 
 ok 1|2, 'Junction 1|2 is true in boolean context';

Keeping with my general philosophy that I'd like to keep
the requirements needed to run Test.pm (and the test suite)
as simple as possible, I'd prefer to not require type checking
within Test.pm in order for it to work right.

Beyond that, if we're testing a Junction in boolean
context, I think I would prefer to make that an explicit
part of the test itself:

ok ?(1|2), 'Junction 1|2 is true in boolean context';

Pm


Building Junctions from Junctions

2008-06-23 Thread Ovid
Hi all,

I use Perl6::Junction in Perl 5 and recently the author implemented the
values method on junctions.  I needed this because I sometimes find
that I need to do something conceptually similar to this:

  my $number = any( 0 .. 19 );
  while ($number-values) {
my $rand int(rand(20));
if ( $number == $random_number ) {

  # handle some task and discard the number
  $number = any( grep { $_ != $rand } $number-values );
}
  }

In other words, sometimes I have code which receives a junction and
needs to provide a new junction based on the values of the old
junction, but with some values removed.

How do I do that in Perl 6?  I can't see that in the docs.  Clearly we
don't this to be done destructively as I suspect this will break
autothreading, but building new junctions based on old junctions seems
reasonable.

Cheers,
Ovid

--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Personal blog- http://publius-ovidius.livejournal.com/
Tech blog- http://use.perl.org/~Ovid/journal/
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6 
Official Parrot Wiki - http://www.perlfoundation.org/parrot


Re: Building Junctions from Junctions

2008-06-23 Thread Jon Lang
I'd say that this ought to be implemented using :v (as in, 'values';
cf. :k, :kv, and :p for lists and hashes): this should let you look at
the values within the Junction as if they were merely a list of
values, at which point you can construct a new Junction from them.

-- 
Jonathan Dataweaver Lang


Re: Junctions as arguments (Pugs bug)

2006-12-20 Thread Jonathan Rockway
Ovid wrote:
(reversed the message a bit)
   is 'b', any('a' .. 'h'), 'junctions should work';

This looks like a Test bug; it's doing something like:

   is 'b', 'a' # not ok
   is 'b', 'b' # ok
   is 'b', 'c' # not ok
   ...

If you write:

   ok 'b' === any('a'..'h')

The result is one passing test.


 That outputs something like the following on my system (Version: 6.2.13
 (r14927))

   any(VInt 1,VInt 2,VInt 3,VInt 4)
   any(VRef Scalar:0x2aa80e0)

My question is, what is the expected output of say-ing a junction?
Should say (1|2|3) randomly print 1, 2, or 3?  Should say (123)
say 1, then say 2, then say 3?

I can understand it going either way (although I'd lean towards what
Ovid is expecting), but it would be good to hear what others think
before tests are committed.


-- 
package JAPH;use Catalyst qw/-Debug/;($;=JAPH)-config(name = do {
$,.=reverse qw[Jonathan tsu rehton lre rekca Rockway][$_].[split //,
;$;]-[$_].q; ;for 1..4;$,=~s;^.;;;$,});$;-setup;


Re: Junctions as arguments (Pugs bug)

2006-12-20 Thread Larry Wall
On Wed, Dec 20, 2006 at 10:26:41AM -0600, Jonathan Rockway wrote:
: Ovid wrote:
: (reversed the message a bit)
:is 'b', any('a' .. 'h'), 'junctions should work';
: 
: This looks like a Test bug; it's doing something like:
: 
:is 'b', 'a' # not ok
:is 'b', 'b' # ok
:is 'b', 'c' # not ok
:...
: 
: If you write:
: 
:ok 'b' === any('a'..'h')
: 
: The result is one passing test.
: 
: 
:  That outputs something like the following on my system (Version: 6.2.13
:  (r14927))
: 
:any(VInt 1,VInt 2,VInt 3,VInt 4)
:any(VRef Scalar:0x2aa80e0)
: 
: My question is, what is the expected output of say-ing a junction?
: Should say (1|2|3) randomly print 1, 2, or 3?  Should say (123)
: say 1, then say 2, then say 3?
: 
: I can understand it going either way (although I'd lean towards what
: Ovid is expecting), but it would be good to hear what others think
: before tests are committed.

What you're seeing is standard autothreading behavior, which is
described in S09, Junctions.  To avoid autothreading, a routine must
declare itself prepared to handle junctions with an appropriate type
signature, and I'm not sure we want to complicate Test to that extent,
since it makes it harder to port.

Larry


Do junctions support determining interesections of lists

2006-04-04 Thread Joshua Gatcomb
Almost a year ago (2005-04-27), I wrote the list asking a question about
junctions.
Specifically, the ability to find the intersection, union, etc of a list.

my $matches = any( @x_chars ) eq any( @y_chars );
my $match = $matches.pick;

all( any() eq any() );

Patrick Michaud offered an infix myeq to let the problem be solved in user
space
as junctions at that time did not support what I wanted to do.

Today I examined the Synopses and found a couple of intriguing things:

In Synopsis 3:

A junction is a single value that is equivalent to multiple values.

And then later on...

Junctions are specifically unordered. So if you say

for all(@foo) {...}

it indicates to the compiler that there is no coupling between loop
iterations and they can be run in any order or even in parallel.

This implies to me that it is possible to get the values out of a junction
without calling a .values method if used in list context.

From Synopsis 12:

To hyperoperate over the values of a junction you have to explicitly pull
out the values:

$junction.values».meth(@args);

This implies to me that you can still get at the values by explicitly using
.values.

From Synopsis 9:

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.

Ok, so what about a context expecting a junction of values as I think all(
any() eq any() ) is expecting?

My question today is 2 fold.

1.  Where in the synopses would I find the various methods that can be
performed on a junction?
A.  .values
B.  .pick
C.  ???

2.  Do the junctions of today support finding the union, intersection, etc
without creating your own infix operator?


Cheers,
Joshua Gatcomb
a.k.a. Limbic~Region


Re: Do junctions support determining interesections of lists

2006-04-04 Thread Larry Wall
On Tue, Apr 04, 2006 at 09:16:23AM -0400, Joshua Gatcomb wrote:
: Almost a year ago (2005-04-27), I wrote the list asking a question about
: junctions.
: Specifically, the ability to find the intersection, union, etc of a list.

Junctions are not intended for that use.  We have Sets for that now.
Junctions are specifically intended to be sets with lazy booleans
properties, and those lazy boolean properties interfere with ordinary
set semantics.

: my $matches = any( @x_chars ) eq any( @y_chars );
: my $match = $matches.pick;
: 
: all( any() eq any() );

Junctions use sets to do their calculations, and you can pull out the
set that a particular junction is using, but junctions are primarily
intended to tell you whether, not what.  And a junction is specifcally
not a set, but a set of sets.

: Patrick Michaud offered an infix myeq to let the problem be solved in user
: space
: as junctions at that time did not support what I wanted to do.
: 
: Today I examined the Synopses and found a couple of intriguing things:
: 
: In Synopsis 3:
: 
: A junction is a single value that is equivalent to multiple values.
: 
: And then later on...
: 
: Junctions are specifically unordered. So if you say
: 
: for all(@foo) {...}
: 
: it indicates to the compiler that there is no coupling between loop
: iterations and they can be run in any order or even in parallel.
: 
: This implies to me that it is possible to get the values out of a junction
: without calling a .values method if used in list context.

That is not what is intended there.  I believe that particular for
is autothreading, not extracting the values.  Admittedly the text is not
clearly written.  To each iteration it appears that there is only one
loop value, not a list.  For autothreading in general, if the compiler
is able to falsify any of the variants, it doesn't need to run that
particular autothread at all, even if it would produce side effects.

: From Synopsis 12:
: 
: To hyperoperate over the values of a junction you have to explicitly pull
: out the values:
: 
: $junction.values».meth(@args);
: 
: This implies to me that you can still get at the values by explicitly using
: .values.

Yes, but you're really extracting the internal set of the junction
while throwing away the extra information that makes the junction
not a set.  If you want to extract the set from a junction, you can
probably just use a coercion

$set = $junction as Set;

And in fact, merely using one of the set operators probably coerces its
arguments to sets, so you can probably say things like

any(@foo) (+) any(@bar)

which won't be treated any differently from

@foo (+) @bar

I expect the compiler could just optimize away any() there as noise,
and maybe all() too.  Probably one() or none() though, since one() is
perhaps really a set of sets, while none() is a universal negative, which
is difficult to find the enumaration of.

But in particular, we'd like to be able to talk about sets of types
as Dog|Cat and have the internals autocoerce to Sets of type signatures
where junctions make little sense.

: From Synopsis 9:
: 
: 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.
: 
: Ok, so what about a context expecting a junction of values as I think all(
: any() eq any() ) is expecting?

I don't think you can do simple set theory that way.  Better to use
explicit sets.  The junctional stuff is really about sets of sets,
and we'd be better off keeping a clean separation.  Consider that
the set of sets:

one(@foo)

is a proper subset of the

any(@foo)

set of sets.  Junctions are just convenient way to represent simple
sets of sets with a single set plus an extra dab of info.

: My question today is 2 fold.
: 
: 1.  Where in the synopses would I find the various methods that can be
: performed on a junction?
: A.  .values
: B.  .pick
: C.  ???

I think .values and .pick are probably just Set operations, and if they
work on junctions, it'd be by autocoercion.

: 2.  Do the junctions of today support finding the union, intersection, etc
: without creating your own infix operator?

The cabal already decided once (in Portland, I believe) to include the
standard set operators and a Set type, as well as ASCII representations
like (*) and (+) for the set ops so we don't force anyone to use
Unicode prematurely.  Unfortunately these have not found their way
into the synopses yet, as far as I know.

Sorry if this is a bit meandering--jet lag is interfering
constructively with my native dimwit...

Larry


Re: Do junctions support determining interesections of lists

2006-04-04 Thread Larry Wall
On the other hand, if junctions really are sets of sets, then maybe it's
a mistake to autocoerce junctions to sets by swiping their internal set
of values.  Arguably any(1,2,3) should coerce not to

(1,2,3)

but to

(
(1),
(2),
(3),
(1,2),
(1,3),
(2,3),
(1,2,3),
)

Larry


  1   2   3   >