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 

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 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 of 

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


Re: Do junctions support determining interesections of lists

2006-04-04 Thread Joshua Gatcomb
On 4/4/06, Larry Wall [EMAIL PROTECTED] wrote:

 On Tue, Apr 04, 2006 at 09:16:23AM -0400, Joshua Gatcomb wrote:



Junctions are not intended for that use.  We have Sets for that now.


Ok.  So this will work out of the box if you use the right tool.  Cool.

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.


Fair enough.  For the benefit of everyone following along at home - which of
the Synopses should we be following to see how Sets fit into Perl6?

Sorry if this is a bit meandering--jet lag is interfering
 constructively with my native dimwit...


No apology necessary.  I don't understand everything but I don't need to.  I
am happy trusting that smarter people than me are working on the problem.


Larry


Joshua Gatcomb
a.k.a. L~R


Re: Do junctions support determining interesections of lists

2006-04-04 Thread Luke Palmer
On 4/4/06, Larry Wall [EMAIL PROTECTED] wrote:
 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),
 )

I don't follow.  Why is that the representation of any(1,2,3)?  Is
this a disjunctive normal form; i.e. is 2  any(1,2,3) equivalent to
the test:

 2  1
  || 2  2
  || 2  3
  || 2  1  2  2
  || ...

Or did you have something else in mind?

Luke


Re: Do junctions support determining interesections of lists

2006-04-04 Thread Flavio S. Glock
2006/4/4, Luke Palmer [EMAIL PROTECTED]:
 I don't follow.  Why is that the representation of any(1,2,3)?  Is
 this a disjunctive normal form; i.e. is 2  any(1,2,3) equivalent to
 the test:

  2  1
   || 2  2
   || 2  3
   || 2  1  2  2
   || ...

  2  1
| 2  2
| 2  3

which ends up being the same thing after simplification

- Flavio S. Glock


Re: Reductions, junctions, hashslices, and cribbage scoring

2005-05-26 Thread John Williams
On Wed, 25 May 2005, Rob Kinyon wrote:

 (This post references the discussion at
 http://www.perlmonks.org/?node_id=458728, particularly dragonchild's
 response at the bottom.)

 For those who don't know, cribbage is a game where each player has
 access to 4 cards, plus a community card. Various card combinations
 score points. The one in question is when cards add up to 15. If you
 have a group of cards that add up to 15, you receive 2 points. This is
 for every group, so if you have a ten and 2 fives, you get 4 points.
 Two tens and two fives is 8 points. Face cards are worth 10 and aces
 are 1, for these purposes.

 I proposed the following:

 # Fifteens
 $score += 2 * all( 15 == [EMAIL PROTECTED] any( 0 .. 4 ) } );

 * Is this syntax legal?

I think so.

 * Does it do what I want it to do?

Definitely not.  It looks like you are thinking of junctions in terms of
arrays, instead of scalar quantum superpositions.

   any( 0 .. 4 )

This returns a scalar junction of the five values (0,1,2,3,4).
What you want is clearly all possible subsets of 0..4.  You probably
should write a coroutine to generate a lazy list of them.

   @hand{ $junction }

returns a scalar junction of the five cards in the hand.  Junctions
auto-thread through operators, including postcircumfixes.

   [+] $junction

returns $junction, since [+] $scalar == $scalar.  The individual values
auto-thread through.

   15 == $junction

This returns a junction of booleans.  Knowing the possible values of
@hand, all of them are false.

   all( $junction )

I'm not real good with nested junctions...

   2 * $junction

This returns another junction, with all elements doubled.  (still zeros)
You obviously want 2 * junction.elems, but I'm not sure if junctions
support that method.

   $score += $junction

Again this will make $score a junction of values.  It will not add each of
the junction values to $score.  You probably want something like
C $score += $junction.values  but that is another indication
that you should be using arrays instead of junctions.  And I'm not sure
about the object interface to junctions anyway.

 * Is there another way?

Assuming you write the subset coroutine above, how about

  $score +=
  ( subsets(0..4) == map { 2 * (15 == [+] @[EMAIL PROTECTED]) } == [+] )


~ John Williams




Re: Reductions, junctions, hashslices, and cribbage scoring

2005-05-26 Thread Rob Kinyon
 Assuming you write the subset coroutine above, how about
 
   $score +=
   ( subsets(0..4) == map { 2 * (15 == [+] @[EMAIL PROTECTED]) } == [+] )

Working on it last night and this morning, I ended up with the
following, very similar rewrite.

sub gen_idx_powerset (Int $size is copy) returns Array {
   my @c = ([]);
   for 0 .. $size-1 - $i {
   push @c, (map { [EMAIL PROTECTED], $i] }, @c);
   }
   return @c;
}

# Fifteens
$score += 2 * grep {
   15 == [+]( @[EMAIL PROTECTED].val )
}, gen_idx_powerset( [EMAIL PROTECTED] );

(Also available at http://www.perlmonks.org/?node_id=460666)

(I had an error in my original posting. @hand is an AoH. My original
should have hypered to .val like my second one does.)

Question: Is it possible using hypers and the like to replace the
gen_idx_powerset() sub with an inline expression? I'm not worried
about maintainability - I wanna see what the new ops can do!

Thanks,
Rob


Re: Calling junctions of closures

2005-04-25 Thread Thomas Sandlaß
Brad Bowman wrote:
 my $a = rand();   # runtime variable
 my $result = one(any( sub { $a+1}, sub { $a-1} ),sub { $a+3 }).();
 say $result.perl;
If $a was 0.5 I'd guess 
  $result = one(any(1.5, 0.5), 3.5) 
is this the case?
IIRC the .perl method produces a string from which an equal value
can be recreated, so e.g. $result == eval( $result.perl ). This forces
a once through evaluation of the junction. So, yes I think your result
is one of the possible 4. The other three are the two numbers in the any()
swapped and the number and the any() of the one() swapped.
OTOH, the junctions will be stored before the .perl call as e.g.
one(any(Ref of Sub, Ref of Sub), Ref of Sub) with the three subs
beeing mutually different. The .perl method might then just be
propagated down to give e.g. 'sub { $a + 1 }' and not call the subs.
But I've no idea how a closed over value is printed. So it could
also be 'sub { \0.5 + 1 }' or 'sub { $Full::Path::To::a + 1 }'.
This is coupled with the questions how references work and how they
are printed.
What I don't like of the Junctive Debates is that many people think about
junctions as specific forms of list. And I haven't managed to understand
the relation between MMD and the code warping needed to get autothreaded
junctions.
--
TSa (Thomas Sandlaß)



Re: Calling junctions of closures

2005-04-20 Thread Thomas Sandlaß
Brad Bowman wrote:
Assuming this is allowed, what will the .() calls below return?
Does the result depend on the calling context?
...
 one(any(@subs),sub { ... }).();
Starting to argument from the statement that junctions are values
the above plays in the league of 3.() which might not have observeable
side effects other then busying the compiler for a while. Actually
it could be optimised away :)

I'd guess the rule is call 'em all and return a similarly
structured junction.  How far off the mark am I?
Unless you ask a question nothing is called. So at least you need
something like if one(...) {...}. Then the call order is undefined
and might stop after the first success. Knowing about the constness
of the return values of the subs referred to from the junction, and
knowing that none of their values is false, these cases might be
optimized towards the front when this stops the influx of further
interrogation by the if. The reverse might apply for interrogation
by unless---but that's up to the oracle :)
--
TSa (Thomas Sandlaß)



Re: Q: Junctions send+more=money

2005-02-26 Thread Rod Adams
Markus Laire wrote:
I have two questions about this example code
(taken from http://svn.openfoundry.org/pugs/examples/sendmoremoney.p6)
I have a few issues with this code. Or at least observations of how it 
differs from the classic SEND + MORE = MONEY problem. see below.


#!perl6
use v6;
my $s; my $e; my $n; my $d; my $m; my $o; my $r;
my $y;
$s = any(0..10)  none(0);
$e = any(0..10);
$n = any(0..10);
$d = any(0..10);
$m = any(0..10)  none(0);
$o = any(0..10);
$r = any(0..10);
$n = any(0..10);
$y = any(0..10);

I think these should be any(0..9).
Indeed they should. I will assume they are written as such in my 
discussion below.


my $send := construct($s,$e,$n,$d);
my $more := construct($m,$o,$r,$e);
my $money := construct($m,$o,$n,$e,$y);
if ($send + $more == $money) {
say  send = $send;
say +more = $more;
say -
say money = $money;
}
sub foldl(Code op, Any $initial, [EMAIL PROTECTED]) returns Any {
if ([EMAIL PROTECTED] == 0) {
 return $initial;
} else {
 return op(shift @values, ?SUB(op, $initial, @values));
}
}
sub add(Int $x, Int $y) returns Int {
return $x + $y;
}
sub construct([EMAIL PROTECTED]) returns Junction {
return foldl( sub ($x, $y) { $x * 10 + $y}, 0, @values);
}

How would the if (...) {...} work if there were more than one possible 
match to this equation?
As written, this generates a rather large number of solutions. I do not 
see any test to make sure that the individual letters are different. Nor 
is there any check to see if all the e's assume the same value.

So what you reach the:
   if ($send + $more == $money) {...}
stage is $send being something equivalent to  any(..)  
none(..0999), only no where near as simplified. Similar values can 
be found in $more and $money. Therefore, you're asking something like: 
Are there any two numbers between 1000 and  that together total 
between 1..9? The answer is yes, and then you get an error as 
you attempt to print a raw junction, if you're lucky, or 9000 send 
lines, followed by 9000 more lines, followed by 9 money lines.

Junctions are _not_ the same as unbound variables in Prolog. They do not 
widdle away inconsistent values as those inconsistencies are found. 
Most of them (all except all()) do not have to use the same value each 
time they are evaluated.

If I'm wrong about this interpretation of this code, I apologize. But it 
certainly fits my understanding of junctions, which has grown by leaps 
and bounds over the last few weeks.

HTH,
-- Rod Adams



Re: More junctions

2002-11-16 Thread Damian Conway
Deborah Ariel Pickett wrote:


Luke wrote:



   $foo = 1 | 2 | 4
   print $foo;
   # Foo is now just one of (1, 2, 4); i.e. not a junction


Just a sanity check, but is this kind of behaviour something we still
want from junctions?

Perhaps the above should just print JUNCTION(0x1234) or something,
like the other built-in types do.


But in Perl 6, they *don't*. The serialize somehow (probably by calling
their C.serialize method).

And I suspect that junctiosn serialize as follows:

	* Disjunctions (Canys) serialize to their eigenstates.

	* Conjunctions (Calls) and abjunctions (Cones)
	  with exactly one eigenstate serialize to that.

	* Every other junction serializes to some representation of
  its junctive type and internal states (e.g. all(1,2),
	  none('Crosby', 'Stills', 'Nash', 'Young'), etc.)

Damian




Re: More junctions

2002-11-16 Thread Damian Conway
Luke Palmer wrote:


sub foo($x) {
if ($x != 4) {
	print Not four\n;
}
if ($x == 4) {
print Four\n;
}
}
sub oof($x) {
if ($x != 4) {
print Not four\n;
}
else {
print Four\n;
}
}

If given 3 | 4, foo would print Not Four\nFour\n, while oof would
print Not four\n.


Maybe not. We're still pondering the interactions of subroutines and
junctive arguments. There are two possibilities (naturally ;-):

	1. Passing a junction as a subroutine argument calls the
   subroutine (in parallel, perhaps in separate threads)
	   with each value of the junction, then juncts the results
	   (in which case both Cfoo and Coof print both strings).
	
	2. Junctions are just passed in as any other scalar argument.
	   (in which case what Luke suggested is correct).

The reason that 1) might be a better semantics is that it makes
something like:

	sub longest_common_substr($a, $b) {
		my $substrs_a = substr $a, any(0,$a.end), any(0,$a.length);
		my $substrs_b = substr $a, any(0,$a.end), any(0,$a.length);
		my $common = $substrs_a == $substrs_b;
		return $common = any($common.states);
	}

work correctly.

That is, we generally want Cf($a|$b|$c) to produce Cf($a)|f($b)|f($c).

In those cases where the junction *should* be passed into the subroutine
(primarilyboolean predicates, I suspect), that would have to be marked
explicitly:

	sub even ($x is junctive) {	# Allow Ceven to work on junctions too
		return $x % 2 == 0;
	}

Note that Ceven would work for regular scalars too, since they can be
considered a degenerate case of a disjunction (or of a conjunction or
abjunction, for that matter).




I don't know how much this would come up in practice, but I do see it
as an issue.  The question is:  are junctions more useful if they do
or don't collapse upon examination?


I'm fairly solidly convinced that it's better if they don't.

Damian




Re: More junctions

2002-11-16 Thread Damian Conway
Brent Dax wrote:


More simply, !($x == 4) is no longer exactly equivalent to ($x != 4).


Correct. Junctive algebra and logic is slightly different. yet another
reason not to allow junctions to seep into subroutines by default.



Actually, this suggests to me a flaw in the != operator, not a flaw in
junctions.  We should probably make != exactly equivalent to the
negation of ==; this implies that when != gets a junction the type of
junction is reversed (any becomes all, all becomes any).  

I don't think so. I think it's important to preserve the useful
intuitive distinction between:

	if $moe|$larry|$curly == $hurt {...} # i.e. any of them hurt

and:

	if $moe|$larry|$curly != $hurt {...} # at least one not hurt


and also between:

	if $moe$larry$curly == $hurt {...} # all hurt

and:

	if $moe$larry$curly != $hurt {...} # none hurt


Damian




Re: More junctions

2002-11-15 Thread Piers Cawley
Damian Conway [EMAIL PROTECTED] writes:

 Luke Palmer asked:

 When junctions collapse,

 Sigh, not another one of those dreadful reality TV shows:

   When animals attack
   When drivers collide
   When junctions collapse

 Next we'll get:

   When mailing lists explode
   When threads perpetuate
   When Piers summarize
   When Larrys make puns
   
 ;-)

Designing programming languages for prisoners the Conway?

Not exactly short and snappy, but the best I could do at short notice.

-- 
Piers

   It is a truth universally acknowledged that a language in
possession of a rich syntax must be in need of a rewrite.
 -- Jane Austen?



Re: More junctions

2002-11-14 Thread Damian Conway
Luke Palmer asked:


When junctions collapse,


Sigh, not another one of those dreadful reality TV shows:

	When animals attack
	When drivers collide
	When junctions collapse

Next we'll get:

	When mailing lists explode
	When threads perpetuate
	When Piers summarize
	When Larrys make puns
	
;-)



is that reflected back in the original junction,


No.



as it should be (QM-wise)?


Except, of course, junctions aren't QM (hence the name change).
They're inspired by, but not slavishly constrained by, the laws of Physics. ;-)



$foo = 1 | 2 | 4
print $foo;
# Foo is now just one of (1, 2, 4); i.e. not a junction


Nope. $foo is still a conjunction.

BTW, it's likely that printing $foo *won't* just randomly select one state;
that it will call $foo.serialize and print whatever string that (standard)
method returns. To get the select one at random behaviour, you need'll:

	print $foo.pick;



If so, what is perl going to do about the computationally expensive
entanglement thingy?


Nothing. Unless Alex ports his Quantum::Entanglement module.



$x = 0 | 1;
$y = 0 | 1;
$z = $x * $y; 

print $z; # 0 with 0.75 probability and 1 with 0.25

No. This probably just prints 0 1.



# If 0 was printed, then $x | $y == 0
# If 1 was printed, then $x  $y == 1


BTW, isn't that a seductive notation. ;-)



Here, are $x and $y collapsed yet, or are they still in an entangled
superposition?


Neither. They're still two completely independent junctions.

Damian




Re: More junctions

2002-11-13 Thread Deborah Ariel Pickett
Luke wrote:
 When junctions collapse, is that reflected back in the original
 junction, as it should be (QM-wise)?
 
 $foo = 1 | 2 | 4
 print $foo;
 # Foo is now just one of (1, 2, 4); i.e. not a junction
 [...]

Just a sanity check, but is this kind of behaviour something we still
want from junctions?  If we're trying to get away from the whole
Quantum Superposition name, why do we want to still have an implicit
collapse on $foo when it's used in certain contexts?  To collapse like
this doesn't make sense unless you're still thinking in quantum terms.

Perhaps the above should just print JUNCTION(0x1234) or something, like
the other built-in types do.  If you really want to collapse the
superposition, use an explicit collapse($foo) or observe($foo) or
pick($foo) or whatever you want to call it.

Just a thought from someone vaguely in the Cozens Camp.

-- 
Debbie Pickett http://www.csse.monash.edu.au/~debbiep [EMAIL PROTECTED]
 The city lights shine seaward, swirling in a trance, her eyes upon the water
   alone in her last dance. - _Oh Life (There Must be More)_, Alan Parsons



Re: More junctions

2002-11-13 Thread Smylers
Deborah Ariel Pickett wrote:

 Luke wrote:

  $foo = 1 | 2 | 4
  print $foo;
  # Foo is now just one of (1, 2, 4); i.e. not a junction
 
 Just a sanity check, but is this kind of behaviour something we still
 want from junctions?
 
 Perhaps the above should just print JUNCTION(0x1234) or something,
 like the other built-in types do.  If you really want to collapse the
 superposition, use an explicit collapse($foo) or observe($foo) or
 pick($foo) or whatever you want to call it.

That sounds the least scary behaviour: it may not do anything
particularly useful by default but at least it's obvious what's
happened.  Having Cpick() Huffman-encoded to nothing at all sounds
unnecessary for those that need it.

 Just a thought from someone vaguely in the Cozens Camp.

That, however, does sound scary -- I didn't know Simon had gone into the
holiday resort market.  Is The Cozens Camp anything like Butlins?

Smylers



Re: More junctions

2002-11-13 Thread Luke Palmer
 Mailing-List: contact [EMAIL PROTECTED]; run by ezmlm
 From: Deborah Ariel Pickett [EMAIL PROTECTED]
 Date: Thu, 14 Nov 2002 09:05:16 +1100 (EST)
 Cc: [EMAIL PROTECTED]
 X-SMTPD: qpsmtpd/0.12, http://develooper.com/code/qpsmtpd/
 
 Luke wrote:
  When junctions collapse, is that reflected back in the original
  junction, as it should be (QM-wise)?
  
  $foo = 1 | 2 | 4
  print $foo;
  # Foo is now just one of (1, 2, 4); i.e. not a junction
  [...]
 
 Just a sanity check, but is this kind of behaviour something we still
 want from junctions?  If we're trying to get away from the whole
 Quantum Superposition name, why do we want to still have an implicit
 collapse on $foo when it's used in certain contexts?  To collapse like
 this doesn't make sense unless you're still thinking in quantum terms.
 
 Perhaps the above should just print JUNCTION(0x1234) or something, like
 the other built-in types do.  If you really want to collapse the
 superposition, use an explicit collapse($foo) or observe($foo) or
 pick($foo) or whatever you want to call it.

You want these two subs to behave differently, then?

sub foo($x) {
if ($x != 4) {
print Not four\n;
}
if ($x == 4) {
print Four\n;
}
}
sub oof($x) {
if ($x != 4) {
print Not four\n;
}
else {
print Four\n;
}
}

If given 3 | 4, foo would print Not Four\nFour\n, while oof would
print Not four\n.

It seems that collapsation on examination is somewhat essential to
logical flow, when substituting a junction for a solid value.  A piece
of code could certainly be ready for junctions (using Cgrep and
Cstates), but if not, very obscure bugs could surface (like this
one) when a junction is trying to behave like a real value.

I don't know how much this would come up in practice, but I do see it
as an issue.  The question is:  are junctions more useful if they do
or don't collapse upon examination?

Luke