Re: Junction Values

2005-02-20 Thread Nigel Sandever
On Sat, 19 Feb 2005 18:42:36 +1100, [EMAIL PROTECTED] (Damian Conway) wrote:

 the Awesome Power of Junctions:

As I tried to express elsehwere, this what I'm looking for. 

Instinctively, and for a long time since I first came across Q::S, I thought 
that the killer app of Junctions is there somewhere, I'm just not seeing it 
yet.

I'd really like to see some practical demonstrations of the Awesome Power. 

Something that goes beyond producing a boolean result from a set of values that 
could equally be done using hyperoperators?

Njs.




Re: Junction Values

2005-02-20 Thread Damian Conway
Rod Adams asked:
 This sound reasonable enough?
Frankly, no. ;-)
Sorry, but your latest proposal sounds complex, multiply special-cased, and 
way too much of an imposition on the programmer (which is specifically what 
junctions are supposed to avoid).

I'm going to continue to strongly recommend that we stick with junctions that 
are simply another (fully assignable) kind of scalar value, and which always 
autothread in any scalar context that isn't explicitly typed CJunction.

To protect the innocent (or the timorous) I'm also going to recommend a Cno 
autothreading pragma, which will prevent non-explicit junctions from 
autothreading.

And that's all I'm going to recommend.
Then, if you don't want implicit autothreading, you can turn it off 
completely: Cno autothreading.

And if you want explicit (non-auto)threading, you can use an explicit 
junction, even under Cno autothreading:

is_prime( any($x) )
And everywhere else, junctions will just Do The Right Thing, even to the point 
of ensuring that any side-effects on your unordered data are appropriately 
non-orderly. ;-)

I truly appreciate the thought and effort that all of you--especially Rod and 
Patrick--have put into this discussion, but I'm afraid I have to bow out of it 
now.

Damian
PS: FWIW, I'd have absolutely no objection to us adding a fifth core
junctive type (perhaps CAdjunction, perhaps just CSet ;-) that
has *no* associated predicate, but which implements full set semantics:
 my $x = set(1..3);
 my $y = set(1,3,5,7,9);
 my $n = 2;
 $x | $y  # set(1,2,3,5,7,9)
 $x  $y  # set(1,3)
 $x - $y  # set(2)
 !$x  # set(none(2));-)
 $x  $y  # $x is a proper subset of $y
 $x = $y # $x is a subset of $y
 $x == $y # $x is the set $y
 $x ~~ $y # $x is the set $y
 $n  $y  # $n is an element of $y
 $n ~~ $y # $n is an element of $y
 set()# empty set
 $x.values# list of elements of set $x
 $x.powerset  # power set of $x
 $x x $y  # cross product of $x and $y
 # etc., etc.


Re: Junction Values

2005-02-20 Thread Rod Adams
Nigel Sandever wrote:
On Sat, 19 Feb 2005 18:42:36 +1100, [EMAIL PROTECTED] (Damian Conway) wrote:
The Awesome Power of Junctions:
   

As I tried to express elsehwere, this what I'm looking for. 

Instinctively, and for a long time since I first came across Q::S, I thought 
that the killer app of Junctions is there somewhere, I'm just not seeing it 
yet.

I'd really like to see some practical demonstrations of the Awesome Power. 

Something that goes beyond producing a boolean result from a set of values that 
could equally be done using hyperoperators?
 

Well, that was one of my stumbling blocks early on. They don't really 
give you the power to do anything you couldn't previously do. They just 
make certain things a lot easier to do.

But I'll take a whack at giving you something non-trivial to do without 
junctions:

   $re1 = /^ -[x]* x -[x]* $/; # match a string with exactly one 
'x' in it.
   $re2 = /^ -[y]* y -[y]* $/; #  ditto 'y'
   $re3 = /^ -[z]* z -[z]* $/; #  ditto 'z'

   $re4 = all($re1, $re2, $re3);  # matches if x,y,  z all appear 
exactly once, in any order.
   $re5 = one($re1, $re2, $re3);  # matches if there is exactly one x, 
y, or z
   $re6 = any($re1, $re2, $re3);  # matches if there is at least one of 
x,y,z that appears exactly once.
   $re7 = none($re1, $re2, $re3); # matches if there are 0 or 2+ of 
each of x,y,z.

And all seven of these can be used as any stored RE can:
   if $x ~~ $re6 {...};
   given $x {
  when $re5 {...}
  when 'santa' {...}
  when ($re1 | $re3)  $re3 {...}
   }
Looking at the junctioned RE's:
#6 would is straight forward to do as a single RE in this case, and in 
the general case.
#5 would be fairly trivial to in this case, but not in the general case.
#4 is possible with a lot of zero-length look aheads and look-behinds, 
but very ugly.
#7 I have no idea how to attack as a single RE in anything close to 
approaching elegance.

So what have we gained here? The ability to join several RE's together, 
into something that still acts like a single RE. Show me the equivalent 
code without junctions, and then we'll compare the power of junctions.

btw, the examples above assume the ability to store a junction. So you 
either have to 'use junctions;', or convince Larry to rescind that 
restriction.

HTH.
-- Rod Adams



Re: Junction Values

2005-02-20 Thread Rod Adams
Eirik Berg Hanssen wrote:
Rod Adams [EMAIL PROTECTED] writes:
 

   $re1 = /^ -[x]* x -[x]* $/; # match a string with exactly one
'x' in it.
   $re2 = /^ -[y]* y -[y]* $/; #  ditto 'y'
   $re3 = /^ -[z]* z -[z]* $/; #  ditto 'z'
   

   $re7 = none($re1, $re2, $re3); # matches if there are 0 or 2+ of
each of x,y,z.
   

#7 I have no idea how to attack as a single RE in anything close to
approaching elegance.
   

 Depending on your idea of elegance ... anchored zero-width negative
lookahead:
$re7 = qr/^ (?!= $re1 | $re2 | $re3 ) /x;
 Oh right.  Perl6.  Well, if I understand $re1 correctly, I think
this is what it will look like:
$re7 = /^ !before $re1 | $re2 | $re3  /;
 

That doesn't quite do it, but something along those lines is possible. 
You'd have to make sure the look ahead/behinds match to the end of the 
string, not just some substring. And then you'd have to put in something 
to actually match the string. So possible, but not straightforward in 
the least.

 I still want junctions, but I also still am not quite sure how they
will behave.  For instance, I wonder how this would autothread or not:
my sub f (Int $x) {
 if $x {
   return 0, 1, $x;
 }
 else {
   return 0, 1;
 }
}
my $j = 0 | 7;
my @a = (1, f($j), 0);
 - How many elements are there in @a?  3? 5? 4|5?
 - What is @a[-1]?  0?  any(0)?  0|undef?
 - What is @a[4]?  undef?  0|undef?  0?
 Naïvely, I would expect that setting of @a be equivalent to this:
my @a = (1, ([0,1]|[0,1,7]), 0);
 And so from the callers perspective, f, which usually returns two
or three values, suddenly returns a single (junctive) value.  New
semantics for f, courtesy of autothreading.  I expect this is too
naïve.  But what am I missing?
 

I believe you are correct in your analysis.
It's also something that I will cover as soon as I have time to write 
down the revelation I had about junctions laying in bed last night. 
(Don't cringe everyone. I actually figured out why Damian insists on 
implicit threading. And I agree with him. Now I want to clamp a 
completely different kind of restriction on Junctions.)

I might be able to find time for it late tonight. Might take a few days.
-- Rod Adams


Re: Junction Values

2005-02-20 Thread Nicholas Clark
On Sun, Feb 20, 2005 at 07:41:16PM +1100, Damian Conway wrote:

Given this:

  my $x = set(1..3);
  my $y = set(1,3,5,7,9);
  my $n = 2;
 
  $x | $y  # set(1,2,3,5,7,9)
  $x  $y  # set(1,3)
  $x - $y  # set(2)
  !$x  # set(none(2));-)

I don't understand this last line, even given the context of the preceding
three. Why is it none of 2, rather than none of something else?

Nicholas Clark


Re: Junction Values

2005-02-20 Thread Eirik Berg Hanssen
Rod Adams [EMAIL PROTECTED] writes:

 Eirik Berg Hanssen wrote:

Rod Adams [EMAIL PROTECTED] writes:



$re1 = /^ -[x]* x -[x]* $/; # match a string with exactly one
'x' in it.
$re2 = /^ -[y]* y -[y]* $/; #  ditto 'y'
$re3 = /^ -[z]* z -[z]* $/; #  ditto 'z'


$re7 = none($re1, $re2, $re3); # matches if there are 0 or 2+ of
each of x,y,z.


#7 I have no idea how to attack as a single RE in anything close to
approaching elegance.



  Depending on your idea of elegance ... anchored zero-width negative
lookahead:

$re7 = qr/^ (?!= $re1 | $re2 | $re3 ) /x;

  Whoops.  For ?!=, read ?!.

  Now imagine the quality of my Perl6 code ...

  Oh right.  Perl6.  Well, if I understand $re1 correctly, I think
this is what it will look like:

$re7 = /^ !before $re1 | $re2 | $re3  /;


 That doesn't quite do it, but something along those lines is
 possible. You'd have to make sure the look ahead/behinds match to the
 end of the string, not just some substring. And then you'd have to put
 in something to actually match the string. So possible, but not
 straightforward in the least.

  $re1, $re2, and $re3 are already anchored: Covered.

  And it will match the empty string at pos()==0, given that the
assertion is satisfied.  This of course differs from a junction of
three match objects, each matching the whole string at pos()=0, but
that difference is in part to be expected (the point of the exercise
was to avoid a junction), and in part trivial to fix: just add .*.
In the general case, it will be more complex, yes, but so will the
match object returned by the junctive rule.

  Well, enough pattern matching.  Junctions on the agenda, now!  ;-)


Eirik
-- 
So this is the Sword of Immortality?  Huh?
 What's it doin' in a CRYPT?!
   --- John S. Novak, III, quoting an unnamed player


Re: Junction Values

2005-02-20 Thread Uri Guttman
 NC == Nicholas Clark [EMAIL PROTECTED] writes:

  NC On Sun, Feb 20, 2005 at 07:41:16PM +1100, Damian Conway wrote:
  NC Given this:

   my $x = set(1..3);
   my $y = set(1,3,5,7,9);
   my $n = 2;
   
   $x | $y  # set(1,2,3,5,7,9)
   $x  $y  # set(1,3)
   $x - $y  # set(2)
   !$x  # set(none(2));-)

  NC I don't understand this last line, even given the context of the
  NC preceding three. Why is it none of 2, rather than none of
  NC something else?

my guess is a typo and $x should be $n.

uri

-- 
Uri Guttman  --  [EMAIL PROTECTED]   http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs    http://jobs.perl.org


Re: Junction Values

2005-02-20 Thread Damian Conway
Nicholas Clark wrote:
On Sun, Feb 20, 2005 at 07:41:16PM +1100, Damian Conway wrote:
Given this:

my $x = set(1..3);
my $y = set(1,3,5,7,9);
my $n = 2;
$x | $y  # set(1,2,3,5,7,9)
$x  $y  # set(1,3)
$x - $y  # set(2)
!$x  # set(none(2));-)

I don't understand this last line, even given the context of the preceding
three. Why is it none of 2, rather than none of something else?
ESTUPIDDAMIAN.
Should, of course be:
   !$x  # set(none(1..3));-)
Damian
PS: This is also a demonstration of the awesome power of junctions: that we
can specify the complement of a set without knowing its universal set!


Re: Junction Values

2005-02-20 Thread Eirik Berg Hanssen
Eirik Berg Hanssen [EMAIL PROTECTED] writes:

 Rod Adams [EMAIL PROTECTED] writes:

 Eirik Berg Hanssen wrote:

Rod Adams [EMAIL PROTECTED] writes:

$re1 = /^ -[x]* x -[x]* $/; # match a string with exactly one
'x' in it.
$re2 = /^ -[y]* y -[y]* $/; #  ditto 'y'
$re3 = /^ -[z]* z -[z]* $/; #  ditto 'z'

$re7 = none($re1, $re2, $re3); # matches if there are 0 or 2+ of
each of x,y,z.


$re7 = /^ !before $re1 | $re2 | $re3  /;


 That doesn't quite do it, but something along those lines is
 possible. You'd have to make sure the look ahead/behinds match to the
 end of the string, not just some substring. And then you'd have to put
 in something to actually match the string. So possible, but not
 straightforward in the least.

   $re1, $re2, and $re3 are already anchored: Covered.

   And it will match the empty string at pos()==0, given that the
 assertion is satisfied.  This of course differs from a junction of
 three match objects, each matching the whole string at pos()=0,

  Whoops again: That would be a junction of three match objects,
_none_ of which are successful.  When the assertion is not satisfied,
however, you will be able to inspect the match object junction's
states to see how many of the $re\d matched, and in the general case,
how they matched.  But on the whole, I now get the impression that
these match object junctions (or at least match object injunctions)
would rarely be used outside boolean context.


Eirik
-- 
For every complex problem, there is a solution that is simple, neat, and wrong.
-- H. L. Mencken
A good plan today is better than a perfect plan tomorrow.
-- Patton


Re: Junction Values

2005-02-20 Thread Patrick R. Michaud
On Sun, Feb 20, 2005 at 10:46:15PM +0100, Eirik Berg Hanssen wrote:
 Eirik Berg Hanssen [EMAIL PROTECTED] writes:
  Rod Adams [EMAIL PROTECTED] writes:
 $re1 = /^ -[x]* x -[x]* $/; # match a string with exactly one 'x'
 $re2 = /^ -[y]* y -[y]* $/; #  ditto 'y'
 $re3 = /^ -[z]* z -[z]* $/; #  ditto 'z'
 
 $re7 = none($re1, $re2, $re3); # matches if there are 0 or 2+ of
 each of x,y,z.
 
 $re7 = /^ !before $re1 | $re2 | $re3  /;

 [...lots of discussion about whether the above works or not...]

I think it may be even simpler than the above, no lookaheads required:

$re7 = / !$re1  !$re2  !$re3 /;

Pm


Re: Junction Values

2005-02-20 Thread Matt Fowles
Damian~


On Mon, 21 Feb 2005 08:29:40 +1100, Damian Conway [EMAIL PROTECTED] wrote:
 Nicholas Clark wrote:
 
  On Sun, Feb 20, 2005 at 07:41:16PM +1100, Damian Conway wrote:
 
  Given this:
 
 
  my $x = set(1..3);
  my $y = set(1,3,5,7,9);
  my $n = 2;
 
  $x | $y  # set(1,2,3,5,7,9)
  $x  $y  # set(1,3)
  $x - $y  # set(2)
  !$x  # set(none(2));-)
 
 
  I don't understand this last line, even given the context of the preceding
  three. Why is it none of 2, rather than none of something else?
 
 ESTUPIDDAMIAN.
 
 Should, of course be:
 
 !$x  # set(none(1..3));-)
 
 Damian
 
 PS: This is also a demonstration of the awesome power of junctions: that we
  can specify the complement of a set without knowing its universal set!

Or one more thing to drive the mathematicians into a rage...

Matt
-- 
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-???


Re: Junction Values

2005-02-19 Thread Autrijus Tang
On Fri, Feb 18, 2005 at 11:31:54PM -0800, Brent 'Dax' Royal-Gordon wrote:
 Junctions are intended to ultimately be used in boolean tests.  That's
 why the values of the junction have an any/all/one/none relationship. 
 The proper data structure here is an array.  (Actually, ironically
 enough, it's probably a set, not an array.)

It's one set for any()/all()/one() and two sets for none().  Of course,
if something (eg. functions) cannot be tested for equality, then we'll
have to assume them to be unique from each other anyway, in which case
junctions do act as arrays.

 [1] Note, however, that this needs to be done carefully.  For example,
 while it doesn't really make sense for the string arguments of a call
 to Cprint to be junctions, the object argument is another matter
 entirely:
 #!/usr/bin/perl6
 # naive tee
 $OUT=$OUT  open( $_) for @ARGS;
 print or die Can't write to $!.filename: $! for *$IN;# Or
 however it's done this week

I think it's an unary = this week, according to S04:

print for =*$IN;

Thanks,
/Autrijus/


pgpGifnGif84A.pgp
Description: PGP signature


Re: Junction Values

2005-02-19 Thread Damian Conway
Hmm. On rereading my last message, I feel that it comes across as angry, 
and critical of this entire discussion or perhaps of particular participants.

That was certainly not my intent and I apologize if that's how it appeared. I 
genuinely respect the contributions of every person on this list, and even 
when (as now) I strenuously disagree with the ideas expressed, I know that 
those contributions are sincere and offered with the best interests of Perl at 
heart.

I still stand by every point I made in that last message, but I'm sorry that I 
let my frustrations leak into the discussion.

Damian


Re: Junction Values

2005-02-19 Thread Rod Adams
Brent 'Dax' Royal-Gordon wrote:
Rod Adams [EMAIL PROTECTED] wrote:
 

The caller is not in a position to know if the callee is internally
structured in such a way that passing in a raw junction makes sense.
 

Sure
they are. It's called reading the documentation. If it doesn't say it can
handle junctions, it probably can't.
   

I don't want to have to stop in the middle of a hundred-line function
to think, Does Store::Market.get act sanely when I give it a
junction?  Do I need to explode it manually, or will it handle the
junction nicely on its own? 

You call functions where you don't know what data types they are 
expecting? That's... surprising.
Even in a loosely typed world like Perl, knowing what a sub or method is 
expecting to be fed seems like a good idea to me. I see checking for 
accepting junctions as input as being on the same level as Does it want 
a list or an arrayref here?.

When I'm writing my own insanely large functions, I'm constantly hitting 
the docs to see the nuances about the method calls I'm not already 
intimately familiar with. And if I'm going to attempt to use a function 
in a new way (like feeding it a Junction), I recheck the docs to make 
sure I'm not setting myself up for trouble down the road.

Your mileage may vary.
-- Rod Adams.
(PS - This should not be construed to be an attack on you or your 
programming style. It is not. Though I've never seen you in action, I 
have every reason to believe you are a fully competent developer. It is 
simply a response to your statement above, explaining why I thought the 
attitude expressed there represented a weak argument.)




Re: Junction Values

2005-02-19 Thread Rod Adams
Damian Conway wrote:
Rod Adams wrote:
All I want now is for autothreading to be explicit.

It already *is*.
The only way that:
is_prime($x)
can ever autothread is if $x holds a junction. But that can now only 
happen if there's an explicit Cuse junctions in scope where $x was 
assigned to (or the explicit use of some other module that also 
activates Cuse junctions). So $x having a junction must be a known 
possibility at that point.

Of course, literal junctions *will* autothread in all circumstances:
is_prime(any(6,7,8))
is_prime(6|7|8)
I had not caught the difference between:
   use junctions;
   $x = 6|7|8;
   if is_prime($x) {...}
and
   if is_prime(6|7|8) {...}
before. Is this new, or yet another important detail I missed along the 
way? Or is this a side effect of not being able to store a Junction, and 
can go away if C use Junctions  is turned on?

But they're both explicit too: you're explicitly using junction 
constructors, so the autothreading can hardly come as a surprise.
*If* we are guaranteed than an explicitly created junctions will always 
autothread, I'll agree with this.

I will, however, question if this is optimal. Compare two simple cases: 
C $x == any(4,5,6)  and C $x  all(4,5,6) . Both of them are prime 
candidates to some optimizations, but the optimizations are likely 
rather different. If we pass the junction into the operator, then it can 
perform some custom tailored code, to make things much more efficient, 
instead of relying on a more generalized junction optimizer to handle 
things.

What this also means is that if you wish to pass an anonymous junction, 
you can't. You have to do something like:

{
   use junctions;
   some_func(my $x = any(4|5|6));
}
Which just seems silly.
And if:
is_prime($x)
does happen to autothread when you weren't expecting it to, then one 
of two things will happen. Either the subroutine will be 'pure' in 
which case there's no problem in autothreading it; or else the 
subroutine will have side effects, in which case you'll get an 
explicit warning when the autothreading occurs.
I addressed earlier concept of how does perl know when there are side 
effects, particularly with the execution path can weave to parts written 
in pure-parrot. In particular, if the  Patrick responded by implying 
that there was no such side effect protection. see:

http://www.nntp.perl.org/group/perl.perl6.language/19210 (my post)
http://www.nntp.perl.org/group/perl.perl6.language/19212 (Patrick's 
response)

I see your statements on the subject, and Patrick's to be at odds. But 
then again, it might be that I've misread something again, though I'm 
doing my best to avoid it now.

I request some clarification on this. If nothing else, to make sure you 
and Patrick have the same understanding of what's happening.

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

Personally, I think it's completely fascist to require a Cuse 
junctions pragma in order for junctions to even be stored in 
variables. It's as bizarre as requiring Cuse strings or Cuse 
references or Cuse undef or Cuse infinities would be. Yes, it 
*is* possible to get unexpected behaviour from passing a junction 
where it isn't expected, but it's already possible to get unexpected 
behaviour by passing a string or an undef or a reference or an object 
where it isn't expected. Junctions are nothing new in that respect.
I had it in my head that if I were to get my »Junction« explicit 
threading idea, I was going to follow up by saying the block against 
storing junctions was a case of diminishing returns at that point, and 
should probably go away. I appreciate the stop-gap measure that it was, 
but I'd prefer to solve the real problem at hand.

 Ironically, by using the Awesome Power of Junctions:
I hope I never gave the impression that I felt Junctions were not 
powerful... That was not the case. If anything, I was arguing that they 
were *too* powerful... But in the end, I realized it's just the implicit 
autothreading I didn't like.

Look, I do understand the arguments in the other direction. I've 
understood them for the past five years that I've been developing the 
concept of superpositional data-types. I've thought them through 
numerous times myself, and in the end: I just don't buy them.

The whole point of junctions is to make the threading of operations on 
datasets both automatic and implicit; to make it Do The Right Thing 
without the hassles of explicit threading. If you don't want that, 
that's fine: just don't use junctions. Use arrays and hyperoperators 
instead. And we'll happily give you a Cno junctions pragma so you 
can be emphatic about not wanting them.
I can certainly understand the hassles of explicit threading if one is 
thinking:

   $y = func(any(3|4|5));
has to be explicitly written as:
   $y = any(any(3|4|5).values().map(func($_)));
or some such, but is it 

Re: Junction Values

2005-02-19 Thread Rod Adams
Damian Conway wrote:
Hmm. On rereading my last message, I feel that it comes across as 
angry, and critical of this entire discussion or perhaps of particular 
participants.

That was certainly not my intent and I apologize if that's how it 
appeared. I genuinely respect the contributions of every person on 
this list, and even when (as now) I strenuously disagree with the 
ideas expressed, I know that those contributions are sincere and 
offered with the best interests of Perl at heart.

I still stand by every point I made in that last message, but I'm 
sorry that I let my frustrations leak into the discussion.

Damian

Well, I for one, never took any offense to any of the responses sent my 
way. And I appreciate the patience it's likely taken to not just 
completely Warnock me.

However, I also realize that I might have stepped on some toes of the 
course of this long discussion. Which was never my intention, and I'll 
apologize to any who feel I've slighted them in the process.

I do believe everyone on this list shares the same goals of making Perl 
6 the possible language that it can be. However, opinions will vary as 
to what that actually means. Being a group of people that can by and 
large be described as having a fairly large egos, these differences of 
opinion can become rather passionate. And passion leads to some pretty 
extreme responses.

It certainly hasn't helped matters that the exact nature of my proposal 
has changed in some fairly drastic ways on a regular basis, as I came to 
a better understanding of what Junctions were, and how they were being 
implemented. I apologize for any confusion this may have caused, but I 
do think the resulting discussions have shed some new insights on 
Junctions, Sets, what it means to have a sigil, why junctions can't just 
be another class, and several other topics. Poor Mr. Fowles is likely 
having nightmares figuring out how to summarize all of this.

Positions I still stand by:
- Sets belong in the language, and need more support. This can likely be 
done at the module level, but I'd like them better incorporated, 
preferably with their own sigil. However, I believe they can peacefully 
coexist with Junctions, and one concept does not need to crowd out the 
other.

- Implicit autothreading is a Bad Thing, and should not happen. This is 
almost entirely due to the side effects such behavior can generate. To 
keep the power of junctions viable, explicit threading should be 
trivially easy, but it should be explicit, none the less.

-- Rod Adams



Re: Junction Values

2005-02-19 Thread Patrick R. Michaud
On Sat, Feb 19, 2005 at 02:40:00PM -0600, Rod Adams wrote:
 Damian Conway wrote:
 
 Of course, literal junctions *will* autothread in all circumstances:
 
 is_prime(any(6,7,8))
 is_prime(6|7|8)
 
 I had not caught the difference between:
 
use junctions;
$x = 6|7|8;
if is_prime($x) {...}
 
 and
 
if is_prime(6|7|8) {...}
 
 before. Is this new, or yet another important detail I missed along the 
 way? Or is this a side effect of not being able to store a Junction, and 
 can go away if C use Junctions  is turned on?

It's a side effect of not being able to store a junction.

 I will, however, question if this is optimal. Compare two simple cases: 
 C $x == any(4,5,6)  and C $x  all(4,5,6) . Both of them are prime 
 candidates to some optimizations, but the optimizations are likely 
 rather different. If we pass the junction into the operator, then it can 
 perform some custom tailored code, to make things much more efficient, 
 instead of relying on a more generalized junction optimizer to handle 
 things.

There's nothing to *prevent* us from passing a junction into a routine
that perform custom tailored code for the junction--it's just not 
the default.  If infix:«» wants to optimize for junctions, we define
it with something like

multi sub *infix:«»(Junction $x, Junction $y) returns bit { ... }

and it can then optimize appropriately.  Autothreading routines 
by default occurs only when the junction arguments are bound to scalar 
parameters that are inconsistent with the Junction type (S09).

 And if:
 is_prime($x)
 does happen to autothread when you weren't expecting it to, then one 
 of two things will happen. Either the subroutine will be 'pure' in 
 which case there's no problem in autothreading it; or else the 
 subroutine will have side effects, in which case you'll get an 
 explicit warning when the autothreading occurs.
 
 I addressed earlier concept of how does perl know when there are side 
 effects, particularly with the execution path can weave to parts written 
 in pure-parrot. In particular, if the  Patrick responded by implying 
 that there was no such side effect protection. see:
 
 http://www.nntp.perl.org/group/perl.perl6.language/19210 (my post)
 http://www.nntp.perl.org/group/perl.perl6.language/19212 (Patrick's 
 response)
 
 I see your statements on the subject, and Patrick's to be at odds. But 
 then again, it might be that I've misread something again, though I'm 
 doing my best to avoid it now.

AFAICT there aren't any conflicts between my and Damian's statements.
The example given in the 19210 post supposed that a Junction would
get passed to a pure Parrot function, but didn't actually provide
code to demonstrate that.  Any pure Parrot routine declared as
accepting scalars inconsistent with Junctions would be autothreaded 
the same as any other routine.  

Assuming that a Junction *is* passed to a pure Parrot routine 
(e.g., via a list or other data structure), and assuming that 
Parrot is not itself supporting autothreading, then it's fairly 
straightforward to define the Junction type such that requests 
to stringify, numify, or otherwise access/evaluate the Junction 
as a non-Junctional value will throw an exception.

 All of this knowledge, which comes almost innately during the 
 process of writing code, can become almost Halting Problem hard 
 for the compiler or runtime to figure out.

So far I haven't seen anything about Junctions that requires an 
awful lot of knowledge, guessing, or exhaustive evaluation on 
the part of the compiler/runtime system.  They will likely need 
to do a bit of checking of the arguments to decide when to 
autothread a call, but they're going to be doing other sorts 
of argument checking anyway, and the additional checking to be 
performed is fairly shallow -- just testing each argument 
for isa(Junction) or its equivalent.  (We don't have to perform
deep inspection of arrays or the like.)

Pm


Re: Junction Values

2005-02-19 Thread Damian Conway
Rod Adams wrote:
I had not caught the difference between:
   use junctions;
   $x = 6|7|8;
   if is_prime($x) {...}
and
   if is_prime(6|7|8) {...}
There isn't one.
Is this new, or yet another important detail I missed along the way?
 Or is this a side effect of not being able to store a Junction, and can go 
away
 if C use Junctions  is turned on?

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


I will, however, question if this is optimal. Compare two simple cases: 
 C $x == any(4,5,6)  and C $x  all(4,5,6) . Both of them are prime
 candidates to some optimizations, but the optimizations are likely rather 
different.
 If we pass the junction into the operator, then it can perform some custom 
tailored code,
 to make things much more efficient, instead of relying on a more 
generalized junction
optimizer to handle things.
Sure. That's why we have the ability to specify subroutines where junctive 
args are *not* autothreaded, by typing the corresponding parameter as taking a 
junction:

multi sub infix:«==» (YourType $x, Junction $y) is symmetrical {...}
multi sub infix:«»  (YourType $x, Junction $y) is symmetrical {...}
These two multisubs can optimize for junctive arguments to their hearts' 
content.

I addressed earlier concept of how does perl know when there are side effects, 
 particularly with the execution path can weave to parts written in 
pure-parrot.
 In particular, if the  Patrick responded by implying that there was no such 
side
 effect protection. see:
http://www.nntp.perl.org/group/perl.perl6.language/19210 (my post)
http://www.nntp.perl.org/group/perl.perl6.language/19212 (Patrick's response)
I don't see that Patrick's response implies that at all. In fact, I think his 
statement that:

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


If nothing else, to make sure you and Patrick have the same understanding of what's happening.
I'm sure we will.

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

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

If you want explicit threading (I refuse to call it autothreading; if it has 
to be manually specified, it certainly isn't auto) then use arrays instead, 
and thread your subroutines and operators over them using the explicit 
hyperoperator notation (see example below).


But bowdlerizing the concept of junctions isn't the answer.
I'm no longer doing that.
Or at least, I'm no doing anything anywhere close to as extreme as some 
of my other ideas over the last week or two. Which I can see perfectly 
well, in retrospect, how you felt I was gutting the power away from 
junctions, and how frustrating that must have been for you.
Thank-you for understanding that.

But I still don't like implicit autothreading, and likely never will. I 
don't know how to explain it, but it just feels very wrong. It's down 
there with using typeglobs to pass filehandles, which is thankfully 
history.
I understand your qualms, even if you can't nail down the exactly reasons for 
them.

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

I appreciate that some people will not like the potential autothreading of:
if is_prime($x) {...}  # Might possibly autothread
but I think it's sufficient to give those people:
# At the top of the program...
no junctions;
# and then...
if is_prime($x) {...}  # Can't possibly autothread
As for explicit threading: hey, you've already got it. Just use an array 
instead of a junction, and only allow explicit junctives. Either:

# At the top of the program...
no junctions 'assignment'; # Junctive constants okay
# and then...
if is_prime(any(@x)) {...} # Explicitly threaded
or, even more 

Set sigils (was: Re: Junction Values)

2005-02-19 Thread Ashley Winters
On Sat, 19 Feb 2005 15:20:59 -0600, Rod Adams [EMAIL PROTECTED] wrote:
 Positions I still stand by:
 
 - Sets belong in the language, and need more support. This can likely be
 done at the module level, but I'd like them better incorporated,
 preferably with their own sigil. However, I believe they can peacefully
 coexist with Junctions, and one concept does not need to crowd out the
 other.

Instead of primary sigils, what about secondary sigils on an array to
mark it as an unordered set?

@|foo = any
@foo = all
@^foo = one   # can arrays be curried arguments? hmm
@!foo = none

After all, why should scalars get all the good secondary sigils? :)

Ashley Winters


Re: Junction Values

2005-02-19 Thread Patrick R. Michaud
On Sat, Feb 19, 2005 at 02:40:00PM -0600, Rod Adams wrote:
 I addressed earlier concept of how does perl know when there are side 
 effects, particularly with the execution path can weave to parts written 
 in pure-parrot. Patrick responded by implying 
 that there was no such side effect protection. 

I should've included this in my previous post...and write it now
simply to promote clarity/completeness:

My response in #19212 was intended to show that the side-effect 
problems being described don't exist, and therefore there isn't 
any need for side-effect protections such as the ones being 
proposed.  I didn't mean to imply that they would be needed but
not available.

Pm


Re: Junction Values

2005-02-19 Thread Patrick R. Michaud
 However, I also realize that I might have stepped on some toes of the 
 course of this long discussion. Which was never my intention, and I'll 
 apologize to any who feel I've slighted them in the process.

Personally, I've found the thread to be incredibly useful in 
(1) understanding Junctions, and (2) getting a handle on the
various ways in which they can be implemented.  So it's been
worthwhile for me.  And no offenses have been intended or taken.

Pm


Re: Junction Values

2005-02-19 Thread Matt Fowles
Rod~


On Sat, 19 Feb 2005 15:20:59 -0600, Rod Adams [EMAIL PROTECTED] wrote:
 Poor Mr. Fowles is likely having nightmares figuring out how to summarize all 
 of this.

Not really nightmares, more sleepless nights twitching in fear...  But
I did skip writing it this week as this thread is the only one of
great length and I was hoping to wait for it to resolve...  Which it
sounds like it is doing :-)

Matt
-- 
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-???


Re: Junction Values

2005-02-19 Thread Rod Adams
Damian Conway wrote:
Rod Adams wrote:
Is this new, or yet another important detail I missed along the way? 
Or is this a side effect of not being able to store a Junction, and 
can go away if C use Junctions  is turned on?

Yes, it's a side-effect of the new default prohibition on junction 
assignments (though I'm still working hard to convince everyone that 
that prohibition cripples junctions and that having to use junctions 
before you can assign a basic Perl 6 scalar datatype to a variable is 
an abomination).
FWIW, I agree with you that having something half enabled by default 
make little sense. But I'll accept it as a stop gap until I get my 
explicit threading.

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

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

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


I will, however, question if this is optimal. Compare two simple cases: 
 C $x == any(4,5,6)  and C $x  all(4,5,6) . Both of them are prime
 candidates to some optimizations, but the optimizations are likely 
rather different.
 If we pass the junction into the operator, then it can perform some 
custom tailored code,
 to make things much more efficient, instead of relying on a more 
generalized junction

optimizer to handle things.

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

multi sub infix:«==» (YourType $x, Junction $y) is symmetrical {...}
multi sub infix:«»  (YourType $x, Junction $y) is symmetrical {...}
These two multisubs can optimize for junctive arguments to their 
hearts' content.
I guess I misunderstood your statement of literal junctions *will* 
autothread in all circumstances to mean _all_ circumstances, not just 
ones where the callee didn't explicitly say they could accept them, or 
if the current use junctions; status is in alignment with the moon, or 
other such things.

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

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

Well, the ultimate answer is that both Dan and Patrick (and others)
will negotiate the exact interface when we get to that point, and
that we don't seem to be too concerned about it at the moment.
(It could just be that we're both burying our heads in the sand
hoping it'll be magically solved by the other.  :-)
   
However, in working out these examples I'm fairly comfortable that
it can be made to work at the Perl 6 compiler level if need be,
although it will probably be a lot more efficient if we can find a
way to do it within Parrot.
seems to confirm that detecting and reporting autothreaded 
side-effects is entirely possible.
Let me attempt to clarify the discrepancy as I see it.
I'll take Damian's recent comment of:  And if C is_prime($x)  does 
happen to autothread when you weren't expecting it to, then one of two 
things will happen. Either the subroutine will be 'pure' in which case 
there's no problem in autothreading it; or else the subroutine will have 
side effects, in which case you'll get an explicit warning when the 
autothreading occurs. 

and my 19210 code of:
   $x = 3|4;
   $y = fun($x);
   sub fun ($x) {
   warn enter: fun($x)\n if $DEBUG;
   $x + 1;
   }
I hope it's clear that whether or not fun() has side effects is a 
runtime decision, and can't realistically be determined at function call 
time.
Now, let's assume that this falls under Damian's heading of happens to 
autothread when I wasn't expecting it to.
If $DEBUG is off, no worries.
If $DEBUG is on, I expect my explicit warning, as promised.

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

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

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


As for the 

Re: Junction Values

2005-02-19 Thread Damian Conway
Rod Adams wrote:
Simply put,
I want my junctions.
Standard in Perl 6.
I want my hyper operator superstrength arrays.
Standard in Perl 6.
I want them both at the same time.
Standard in Perl 6.
I never want to see implicit threading. Ever.
If this is the only stumbling block, then it's easily solved.
Instead of ruining junctions by imposing all kinds of complex and annoying 
hoops and hurdles (i.e. Cuse junctions and Cno junctions), we can just 
offer a Cno autothreading pragma that prevents any non-explicit junction 
from autothreading any operator or subroutine. Put it at the top of your code 
and you'll never get any implicit threading.

Damian


Re: Junction Values

2005-02-19 Thread Brent 'Dax' Royal-Gordon
Damian Conway [EMAIL PROTECTED] wrote:
 Yes, it's a side-effect of the new default prohibition on junction assignments
 (though I'm still working hard to convince everyone that that prohibition
 cripples junctions and that having to use junctions before you can assign a
 basic Perl 6 scalar datatype to a variable is an abomination).

Point of consideration: is accidentally autothreading over a junction
any more dangerous than accidentally looping forever over an infinite
lazy list?

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junction Values

2005-02-19 Thread Rod Adams
Damian Conway wrote:
Rod Adams wrote:
I never want to see implicit threading. Ever.

If this is the only stumbling block, then it's easily solved.
Instead of ruining junctions by imposing all kinds of complex and 
annoying hoops and hurdles (i.e. Cuse junctions and Cno 
junctions), we can just offer a Cno autothreading pragma that 
prevents any non-explicit junction from autothreading any operator or 
subroutine. Put it at the top of your code and you'll never get any 
implicit threading.
Well, allow me to explain what I want in a little more detail, so I can 
be sure I'm getting it.

I want to be able to feed a junction to functions that handle it, but I 
also want to thread over ones that do not. But I do not want the 
decision of which way to go to be made for me.

So, I want to be able to pass a raw junction into C == , because it 
understands junctions, and will take care of the threading for me, 
likely in a way that's much more efficient than my generalized »« 
threading ever could. I do not consider this implicit threading. It's 
passing the task of threading off to C == , which itself performs some 
form of explicit threading.

But when I'm faced with some function that does not directly support 
junctions, or one which does, but not in a way that I like, I want to be 
able to thread my junction over it.


I do not think that what you said above is enough to accomplish this. I 
believe what I need to separate your threading desires from mine is two 
fold:

1) I need my »« modifier which forces explicit threading, which will not 
normally be needed under use autothreading; conditions.
2) I need no autothreading; to alter the calling syntax to require »« 
when threading is desired (or you can do a .values() and .junctiontype() 
and roll your own if you really want to). But I can still pass junctions 
around at will, withstanding normal type check requirements.

Then the only argument left is whether use autothreading or no 
autothreading should be default.  I would, of course, say no 
autothreading;, and then turn back on the ability to store junctions.

IMO, no autothreading would provide enough cover for the unsuspecting, 
removing the Bad Side Effects problems that spawned Larry's no junction 
storage default. At the same time, junctions still have enormous power 
via the »«. If people don't want to have to bother figuring out when to 
thread for themselves, they can then turn on use autothreading, and 
let perl attempt to figure it out for them.

Also, if no autothreading is default, the person new to Perl6 will 
always have something to present to investigate to figure out what is 
going on. In my code, it'll be the funny looking C »$junction«  
things. In your code, it'll be the C use autothreading;  at the top of 
the page.


The only implementation problem I see is a potential for the »« to be 
mis-parsed, since » and « seem to be serving several different roles 
these days, but I don't think any of them conflict with this meaning. If 
you want to rename »« to something else, I'm open to suggestions. Just 
leave it fairly simple.

As for why implementation should be easy (or at least the delta between 
your way and my way is easy):

- The functionality of »$junction« has to be defined anyways if 
autothreading happens. It's just calling an already existent chunk of code.

- The logic of when to thread becomes:
   given $situation {
  when marked_with_»«()
{ thread }
  when use_autothreading()  damians_ouija_board()
{ thread }
  default
{ don't thread }
   }
And you've already defined how the ouija board works, everything else 
should be boilerplate for the compiler/runtime to handle.

This sound reasonable enough?
-- Rod Adams


Re: Junction Values

2005-02-18 Thread Brent 'Dax' Royal-Gordon
Rod Adams [EMAIL PROTECTED] wrote:
 Larry Wall wrote:
 Junctions can short circuit when they feel like it, and might in some
 cases do a better job of picking the evaluation order than a human.
 
 
 I was afraid someone was going to say that. And I now must convert my
 reservations about junction autothreading from very disturbing to
 you've got to be kidding.
...
 Not to mention it contradicts S09:
 ... that routine is autothreaded, meaning the routine will be called 
 automatically as many times as necessary to process the individual scalar 
 elements of the junction in parallel.
 
 Now there is some wiggle room in there for short circuiting, but not very 
 much.

The wiggle room is that the junction knows when it's being asked to
collapse into a Boolean, and can know if there's no possible way the
function it's running will have side effects.  (That's why we're
declaring ties now.  There may be cases where we can't know for sure
if there will be side effects or not--Halting Problem stuff--but we
can make sure the junction optimizer is conservative.  The Halting
Problem becomes a lot easier if you ask whether a program *might* halt
instead of whether it *will*.)

In general, it seems to simply be an amazingly bad idea to autothread
a function with side effects.  In fact, I'd recommend that we warn if
a side effect occurs during autothreading.

 Besides, people were telling me that my Sets were not needed, because
 they could be rendered with Arrays and Hashes. I fail to see how
 junctions are that different.

Junctions are intended to be used mainly within conditionals and other
statements; it's sort of a happy accident that they can be assigned to
variables.  At the intra-statement level, there's nothing else (short
of involving a function like Cgrep) that'll do the job.  From what I
saw, your sets are mainly designed to be used at the inter-statement
level, where we have arrays and hashes to do that sort of thing.

I think junctions are important at the statement level because they
help make similar things look similar.  Consider these two statements:

   if($foo == $bar) { .. }
   if(grep { $foo ==  $_ } $bar, $baz) { ... }

What makes these two statements so fundamentally different from each
other that they should be expressed in ways that *look* so different?

 : - Edge cases which, IMHO, do not merit the huffman level of several
 : single character operators. All of which can be accomplished without the
 : use of junctions, though not as gracefully.
 
 Grace is important.  Even more important is mapping naturally to human
 linguistic structures, to the extent that it can be done unambiguously.
 
 
 In my experience, English tends not to superimpose several values on a
 given noun at once.

No, but nor does it have a concept quite like a variable.  There's a
reason many people have trouble understanding what 'x' and 'y' are all
about in algebra.  (And remember, algebra variables can sometimes have
multiple values--consider y = x ** 2, for example.)

Junctions are equivalent to the English sentence Get eggs, bacon, and
toast from the store.  (In Perl, that'd be something like C
$store-get(eggs  bacon  toast) .)  It's just a bit of
orthogonality that allows you to give eggs, bacon, and toast a name
and use it later.

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junction Values

2005-02-18 Thread David Wheeler
On Feb 18, 2005, at 2:04 AM, Brent 'Dax' Royal-Gordon wrote:
Junctions are equivalent to the English sentence Get eggs, bacon, and
toast from the store.  (In Perl, that'd be something like C
$store-get(eggs  bacon  toast) .)  It's just a bit of
orthogonality that allows you to give eggs, bacon, and toast a name
and use it later.
Junctions are grocery lists, then.
Regards,
David


Re: Junction Values

2005-02-18 Thread Rod Adams
Brent 'Dax' Royal-Gordon wrote:
Rod Adams [EMAIL PROTECTED] wrote:
 

Larry Wall wrote:
   

Junctions can short circuit when they feel like it, and might in some
cases do a better job of picking the evaluation order than a human.
 

I was afraid someone was going to say that. And I now must convert my
reservations about junction autothreading from very disturbing to
you've got to be kidding.
   

...
 

Not to mention it contradicts S09:
... that routine is autothreaded, meaning the routine will be called 
automatically as many times as necessary to process the individual scalar elements of the junction 
in parallel.
Now there is some wiggle room in there for short circuiting, but not very much.
   

The wiggle room is that the junction knows when it's being asked to
collapse into a Boolean, and can know if there's no possible way the
function it's running will have side effects.  (That's why we're
declaring ties now.  There may be cases where we can't know for sure
if there will be side effects or not--Halting Problem stuff--but we
can make sure the junction optimizer is conservative.  The Halting
Problem becomes a lot easier if you ask whether a program *might* halt
instead of whether it *will*.)
In general, it seems to simply be an amazingly bad idea to autothread
a function with side effects.  In fact, I'd recommend that we warn if
a side effect occurs during autothreading.
 

Besides, people were telling me that my Sets were not needed, because
they could be rendered with Arrays and Hashes. I fail to see how
junctions are that different.
   

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

This way, you get all the happy functionality, at the cost of typing 
use Junction;, and I get loads of protection against the evil side of 
autothreading. Doing Junctions this way also makes the them extensible. 
If someone figures out what a not junction is, they can add it in 
later. And people like me can't complain about what the module is doing 
to the language, because all's fair if you predeclare would be in effect.

I think junctions are important at the statement level because they
help make similar things look similar.  Consider these two statements:
  if($foo == $bar) { .. }
  if(grep { $foo ==  $_ } $bar, $baz) { ... }
What makes these two statements so fundamentally different from each
other that they should be expressed in ways that *look* so different?
 

You mean besides the shift in plurality? A shift in plurality in English 
forces you to modify a hefty portion of your sentence to accommodate it. 
At a minimum, you change your verb, in this case the C == .
Shifting plurality in programming languages also incurs changes to the 
code around it.

: - Edge cases which, IMHO, do not merit the huffman level of several
: single character operators. All of which can be accomplished without the
: use of junctions, though not as gracefully.
Grace is important.  Even more important is mapping naturally to human
linguistic structures, to the extent that it can be done unambiguously.
In my experience, English tends not to superimpose several values on a
given noun at once.
   

No, but nor does it have a concept quite like a variable. 

Which significantly weakens the mapping naturally to human linguistic 
structures argument, IMO.

Junctions are equivalent to the English sentence Get eggs, bacon, and
toast from the store.  (In Perl, that'd be something like C
$store-get(eggs  bacon  toast) .) 
 

Or just have C get()   take a list, and it's:
$store-get(eggs bacon toast); # is that the latest use of ?
It's just a bit of
orthogonality that allows you to give eggs, bacon, and toast a name
and use it later.
@shopping list = eggs bacon toast;
gives them a name you can use later, as well.
-- Rod Adams


Re: Junction Values

2005-02-18 Thread Rod Adams
Larry Wall wrote:
The need for junctions
first became evident when we found ourselves filling the ~~ tables
with various sorts of weird non-symmetries.
 

~~ can easily be called the DWIM compare operator. It even looks like 
you're waving your hands, asking for some strange voodoo to happen. It 
can also be thought of as Here! take these two things, do something 
with them, and tell me how it went. So it's magic central. And magic is 
invariably a messy thing to implement.

And once the concept is out there, is makes sense to have practically 
every combination of types do _something_ useful if fed to ~~. Which 
makes it where ~~ is likely destined to be one of the most overloaded 
operators in the history of computing. So be it. It's amazingly useful. 
It also takes a monstrous amount of the Perl 6 DWIMery and puts it all 
in one place.

Not to mention, you've already defined P6 to be good at this 
multi-sub/method game, so take advantage of it. It's not like this table 
will be represented all in one function (at least I hope not)

-- Rod Adams


Re: Junction Values

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

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

Let me demonstrate something:

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

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

2..sqrt($x)

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

When I say:

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

I expect to run the codeblock if any of my stuff is prime.  Instead I
get an error, always.  I could always do this:

if @stuff.grep:{ is_prime($_) } {...}

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

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

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

And:

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

No matter what the value of $x.

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

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

Luke

 
 This way, you get all the happy functionality, at the cost of typing 
 use Junction;, and I get loads of protection against the evil side of 
 autothreading. Doing Junctions this way also makes the them extensible. 
 If someone figures out what a not junction is, they can add it in 
 later. And people like me can't complain about what the module is doing 
 to the language, because all's fair if you predeclare would be in effect.
 
 I think junctions are important at the statement level because they
 help make similar things look similar.  Consider these two statements:
 
   if($foo == $bar) { .. }
   if(grep { $foo ==  $_ } $bar, $baz) { ... }
 
 What makes these two statements so fundamentally different from each
 other that they should be expressed in ways that *look* so different?
  
 
 You mean besides the shift in plurality? A shift in plurality in English 
 forces you to modify a hefty portion of your sentence to accommodate it. 
 At a minimum, you change your verb, in this case the C == .
 Shifting plurality in programming languages also incurs changes to the 
 code around it.
 
 : - Edge cases which, IMHO, do not merit the huffman level of several
 : single character operators. All of which can be accomplished without 
 the
 : use of junctions, though not as gracefully.
 
 Grace is important.  Even more important is mapping naturally to human
 linguistic structures, to the extent that it can be done unambiguously.
 
 In my experience, English tends not to superimpose several values on a
 given noun at once.

 
 
 No, but nor does it have a concept quite like a variable. 
 
 Which significantly weakens the mapping naturally to human linguistic 
 structures argument, IMO.
 
 Junctions are equivalent to the English sentence Get eggs, bacon, and
 toast from the store.  (In Perl, that'd be something like C
 $store-get(eggs  bacon  toast) .) 
  
 
 Or just have C get()   take a list, and it's:
 
 $store-get(eggs bacon toast); # is that the latest use of ?
 
 It's just a bit of
 orthogonality that allows you to give eggs, bacon, and toast a name
 and use it later.
 
 @shopping list = eggs bacon toast;
 
 gives them a name you can use later, as well.
 
 -- Rod Adams


Re: Junction Values

2005-02-18 Thread Jonathan Scott Duff
On Fri, Feb 18, 2005 at 12:42:31PM -0600, Rod Adams wrote:
 
 No, but nor does it have a concept quite like a variable. 
 
 Which significantly weakens the mapping naturally to human linguistic 
 structures argument, IMO.

Why exactly?  It's just the variable-nature of variables that isn't
exactly expressed linguistically, otherwise variables are just nouns
really.

 Junctions are equivalent to the English sentence Get eggs, bacon, and
 toast from the store.  (In Perl, that'd be something like C
 $store-get(eggs  bacon  toast) .) 
  
 
 Or just have C get()   take a list, and it's:
 
 $store-get(eggs bacon toast); # is that the latest use of ?
 
 It's just a bit of
 orthogonality that allows you to give eggs, bacon, and toast a name
 and use it later.
 
 @shopping list = eggs bacon toast;
 
 gives them a name you can use later, as well.

Except that you've introduced a definite ordering where one isn't
needed.

This whole analogy has me wishing for an Exegesis.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: Junction Values

2005-02-18 Thread Rod Adams
Luke Palmer wrote:
Rod Adams writes:
 

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

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

Okay, I think your proposal is thinning.
I'm trying to salvage what I can, since people seem to be rejecting 
everything I offer.

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

So will I.
Let me demonstrate something:
   sub is_prime($x) {
   my @primes;
   for 2..sqrt($x) {
   if $_ % none(@primes) == 0 {
   push @primes, $_;
   }
   }
   return 1 if $x % none(@primes) == 0;
   }
Run through your mind how this would be done with a junction in $x.
Particularly focus on:
   2..sqrt($x)
What the hell does that mean?  Do you get a junction of lists out?  Or
does sqrt die because it's not expecting a junction?  
 

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

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

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

Should also be able to overload   Junction ~~ CodeRef  to make this work:
   if any(@stuff) ~~ is_prime {...}
In this manner, you are explicitly controlling when and how the 
autothreading happens. There is no way for is_prime to slurp up the 
junction and pass it on in this case.

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

   sub is_prime {
   my @primes;
   for 2..sqrt(@_[0]) {
   if $_ % none(@primes) == 0 {
   push @primes, $_;
   }
   }
   return 1 if $x % none(@primes) == 0;
   }
Pushing the autothreading directly onto the C for (2..sqrt(3|5)) {...}  
, which as you pointed out earlier, is almost definitely _not_ what 
was wanted, whatever it means. (btw, My current analysis says it will 
stop at the lowest value in the junction.)

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

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

Something like:
   if is_prime(any(@stuff)) {...}
Would more than suffice. It says that you're not attempting to pass the 
junction, but instead doing something in parallel, which is what the 
hyper operators are all about, anyways.

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

But the whole point of junctions is to get rid of obscure expressions
like that.  Brent makes a fantastic case here.
The point is that when you say makes no assumptions, you're giving the
sub writers too much credit.  I think a reasonable assumption
(especially for these alledged novices you keep talking about) that
these two code segments are equivalent:
   if $x == 2 {...}
   elsif $x == 3 {...}
And:
   if $x == 2 {...}
   if $x == 3 {...}
No matter what the value of $x.
Yet in the presence of junctions, they are not.  Also note that this is
a practical example.  I like the former, I know people who like the
latter.  It's a matter of style, and it's one that will bite you if you
don't know about junctions. 
 

You get into this problem when you allow any form of overloading of 
built in operators, not just with junctions. It'd be trivial to create 
an AlwaysTrue class, which overloads all forms of comparison against it 
to always return 

Re: Junction Values

2005-02-18 Thread Ashley Winters
On Fri, 18 Feb 2005 12:47:51 -0700, Luke Palmer [EMAIL PROTECTED] wrote:
 Run through your mind how this would be done with a junction in $x.
 Particularly focus on:
 
 2..sqrt($x)
 
 What the hell does that mean?  Do you get a junction of lists out?  Or
 does sqrt die because it's not expecting a junction?

sqrt() won't die; it gets threaded and returns a Junction, I would
expect. It's the lack of an *infix:..(Int, Junction) function which
causes death

I suppose you could write one which would pick a random value:

multi sub *infix:..(Int $x, Junction $y) {
return $x .. first { .does(Int) } $y.values;
}

Ashley Winters


Re: Junction Values

2005-02-18 Thread Eirik Berg Hanssen
Ashley Winters [EMAIL PROTECTED] writes:

 On Fri, 18 Feb 2005 12:47:51 -0700, Luke Palmer [EMAIL PROTECTED] wrote:
 Run through your mind how this would be done with a junction in $x.
 Particularly focus on:
 
 2..sqrt($x)
 
 What the hell does that mean?  Do you get a junction of lists out?  Or
 does sqrt die because it's not expecting a junction?

 sqrt() won't die; it gets threaded and returns a Junction, I would
 expect. It's the lack of an *infix:..(Int, Junction) function which
 causes death

  Why does that cause death instead of authothreading?


Eirik
-- 
Ever heard of .cshrc?
That's a city in Bosnia.  Right?
(Discussion in comp.os.linux.misc on the intuitiveness of commands.)


Re: Junction Values

2005-02-18 Thread Rod Adams
Jonathan Scott Duff wrote:
On Fri, Feb 18, 2005 at 12:42:31PM -0600, Rod Adams wrote:
 

No, but nor does it have a concept quite like a variable. 

 

Which significantly weakens the mapping naturally to human linguistic 
structures argument, IMO.
   

Why exactly?  It's just the variable-nature of variables that isn't
exactly expressed linguistically, otherwise variables are just nouns
really.
 

And nouns either refer to single item, or a group of items as a whole. 
Not one item that behaves like a chameleon.

When you say The French, you are referring to the entire group of 
people that associate themselves with the country of France. Not all the 
people of France juxtaposed into one entity. If you want that, you say 
A Frenchmen or One of the French, but even then you are referring to 
a single person, who happens to part of the group The French. This 
last is a pure Set membership question. The same The French can be 
used as : The French are invading!!. With a junction, you can build 
something that says any group of people from France, one person from 
France, everyone from France, and even not from France, but none of 
them embody the concept that we think of as The French.

If you were to have an embodiment of The French (as I proposed way 
back in Sets vs Junctions), it is fairly easy to then create all of 
the above junctions. Via the introspection that Junctions are being 
defined with, it's possible to get that back out, but not smoothly.

So, linguistically, a noun is either a specific entity, or a group of 
things, taken as a whole.
As Damian so emphatically stated earlier in this long and twisting 
thread, a Junction is not a group of things, lopped together. It is one 
single thing, that has several different values at once. In addition, it 
also has a boolean function (any/all/one/none), declaring how all these 
values relate when evaluated. The closest linguistic parallel to this 
I've see is the double entendre, which doesn't even come close.

Sets and Junctions are two different things. They are related, but quite 
different, and should not be confused.

Junctions are equivalent to the English sentence Get eggs, bacon, and
toast from the store.  (In Perl, that'd be something like C
$store-get(eggs  bacon  toast) .) 

Or just have C get()   take a list, and it's:
$store-get(eggs bacon toast); # is that the latest use of ?
   

It's just a bit of
orthogonality that allows you to give eggs, bacon, and toast a name
and use it later.
shopping list = eggs bacon toast;
gives them a name you can use later, as well.
   

Except that you've introduced a definite ordering where one isn't
needed.
 

Yes, well, people don't get to use that argument on me after repeatedly 
saying that sets could be easily stored in arrays and/or hashes. I don't 
remember if you, personally said it, but it felt like a consensus vote 
from over here. One I don't really disagree with.

Not to mention the definite ordering only matters if you process it in a 
way that it does.

In attempts to better explain:
   $store-get(eggs  bacon  toast);
   $store-get(eggs bacon toast);
say two radically different things. The first statement says: Go to the 
store and get Eggs. Go to the store and get Bacon. Go to the store and 
get Toast. Save the results of each trip separately, and then when 
someone asks how your trip (not trips) to the store went, you then see 
if all the results are the same.

The second statement says: Go to the store once. You have the following 
shopping list: Eggs, Bacon, Toast. Was your trip successful?

-- Rod Adams



Re: Junction Values

2005-02-18 Thread Ashley Winters
On Fri, 18 Feb 2005 23:12:40 +0100, Eirik Berg Hanssen
[EMAIL PROTECTED] wrote:
 Ashley Winters [EMAIL PROTECTED] writes:
 
  On Fri, 18 Feb 2005 12:47:51 -0700, Luke Palmer [EMAIL PROTECTED] wrote:
  Run through your mind how this would be done with a junction in $x.
  Particularly focus on:
 
  2..sqrt($x)
 
  What the hell does that mean?  Do you get a junction of lists out?  Or
  does sqrt die because it's not expecting a junction?
 
  sqrt() won't die; it gets threaded and returns a Junction, I would
  expect. It's the lack of an *infix:..(Int, Junction) function which
  causes death
 
   Why does that cause death instead of authothreading?

Okay, I changed my mind. I think it does it does work for ~~ matching,
but not as an iterator

given 2 {
when 1 .. sqrt(3|6) { ... }# would work
}

for(1 .. sqrt(3|6)) { ... }   # would fail, since Junction doesn't do
Iterator or whatever

1 .. sqrt(10) - LazyList of (1..3)
1 .. sqrt(10|20) - Junction of any(1,2,3, 1,2,3,4)

LazyList does Iterator, but Junction does not. You'd have to use (1 ..
sqrt(3|6)).values to iterate through the possible values
semi-randomly.

More likely, I'm nuts.

Ashley


Re: Junction Values

2005-02-18 Thread Ashley Winters
On Fri, 18 Feb 2005 14:35:53 -0800, Ashley Winters
[EMAIL PROTECTED] wrote:
 1 .. sqrt(10) - LazyList of (1..3)
 1 .. sqrt(10|20) - Junction of any(1,2,3, 1,2,3,4)
 
 LazyList does Iterator, but Junction does not. You'd have to use (1 ..
 sqrt(3|6)).values to iterate through the possible values
 semi-randomly.

Okay, changed my mind again.

1 .. sqrt(10|20) - Junction of any(1,2,3, 1,2,3,4)

therefore, for(1 .. sqrt(10|20)) iterates ONCE, but $_ is a junction.
Anything inside the loop which uses $_ would autothread. Anything
which doesn't use $_ would only get called once. That's insane, right?

for(1 .. sqrt(10|20) {
if($_  2) {}# uses junctive value
say Here;  # called once
bar($_);   # calls bar() lots of times
}

 More likely, I'm nuts.

I'm definitely crazy. I give up! I'll stop now, since I clearly don't get it. :)

Ashley Winters


Re: Junction Values

2005-02-18 Thread Rod Adams
Ashley Winters wrote:
On Fri, 18 Feb 2005 12:47:51 -0700, Luke Palmer [EMAIL PROTECTED] wrote:
 

Run through your mind how this would be done with a junction in $x.
Particularly focus on:
   2..sqrt($x)
What the hell does that mean?  Do you get a junction of lists out?  Or
does sqrt die because it's not expecting a junction?
   

sqrt() won't die; it gets threaded and returns a Junction, I would
expect. It's the lack of an *infix:..(Int, Junction) function which
causes death
In the context this question was posed, the proposal I was making, 
sqrt() would throw an exception. But that's likely not what this 
discussion is about.

In the terms of junctions as defined, I expect that it would stop at the 
lowest value of $x greater than or equal to 4. Unless we start allowing 
junctive lists as well as junctive scalars...

-- Rod Adams.




Re: Junction Values

2005-02-18 Thread Craig DeForest
Hmmm... It seems that this way does lie madness -- there's a fundamental 
ambiguity between autothreading happening inside or outside the declared 
loop, and there's no least surprising way to implement it.  Certainly 
inside the loop is the easiest and most natural to implement, but that acts 
strange from an API standpoint.  Outside the loop works well from an API 
standpoint but introduces all sorts of weird cases that the implementation 
has to consider.  

P5/PDL has some junction-like aspects, in that it does autothreading. 
We sidestep the issue by not allowing multiple-element PDLs in boolean 
comparisons, but treating single-element PDLs as scalars whenever possible.
This flows down to '..',  so (1..pdl(3)) returns (1,2,3) or does the Right 
Thing in scalar context --  but (1..pdl(3,4)) probably ought to throw an 
exception (it actually returns the empty set or always-false, depending on 
context).

I'm no language designer, but it seems to me that certain operators simply 
won't generalize well to the autothreaded case, and those operators should 
simply try to pick up the pieces -- ie treat single-element junctions like 
ordinary scalars, and treat empty junctions like undef values, but otherwise 
do something exceptional  (whether or not that involves throwing an actual 
exception).  My personal preference is that constructs like 1..($a|$b) should 
be disallowed.  It's certainly easy enough to expand the junction manually 
into a list and loop over that.

Note that other weird constructs in perl5, such as (1..[2,3]), do very 
surprising, architecture-dependent things.


Quoth Ashley Winters on Friday 18 February 2005 04:09 pm,
 On Fri, 18 Feb 2005 14:35:53 -0800, Ashley Winters

 [EMAIL PROTECTED] wrote:
  1 .. sqrt(10) - LazyList of (1..3)
  1 .. sqrt(10|20) - Junction of any(1,2,3, 1,2,3,4)
 
  LazyList does Iterator, but Junction does not. You'd have to use (1 ..
  sqrt(3|6)).values to iterate through the possible values
  semi-randomly.

 Okay, changed my mind again.

 1 .. sqrt(10|20) - Junction of any(1,2,3, 1,2,3,4)

 therefore, for(1 .. sqrt(10|20)) iterates ONCE, but $_ is a junction.
 Anything inside the loop which uses $_ would autothread. Anything
 which doesn't use $_ would only get called once. That's insane, right?

 for(1 .. sqrt(10|20) {
 if($_  2) {}# uses junctive value
 say Here;  # called once
 bar($_);   # calls bar() lots of times
 }

  More likely, I'm nuts.

 I'm definitely crazy. I give up! I'll stop now, since I clearly don't get
 it. :)

 Ashley Winters


Re: Junction Values

2005-02-18 Thread Rod Adams
Craig DeForest wrote:
Hmmm... It seems that this way does lie madness -- there's a fundamental 
ambiguity between autothreading happening inside or outside the declared 
loop, and there's no least surprising way to implement it.  Certainly 
inside the loop is the easiest and most natural to implement, but that acts 
strange from an API standpoint.  Outside the loop works well from an API 
standpoint but introduces all sorts of weird cases that the implementation 
has to consider.  
 

I would think that my latest idea of turning off autothreading per se, and replacing it with an explicit threading call/operator, would solve this dilemma. The idea was specifically to have it where threading happened on function calls when a junction was surrounded by hyper operators. Otherwise, the junction is passed as is. 

So we still get:
if $x == 3|4|5|6 {...}
would thread over infix:== without any funkiness, since we'll assume 
operators are well written, and can take junctions as parameters, same as:
if is_prime(3|4|5|6) {...}
Would pass the junction to is_prime, to do with as it pleases, including throwing an exception. However, 

if is_prime(»3|4|5|6«) {...}
would thread over is_prime, and collate the results outside of call.
These semantics also give us the ability to easily mix and match what we 
send to a function, so we can say:
if funky_test(all(@A), »any(@B)«) {...}
Basically I'm putting all the power of threading into the hands of the 
caller.
I will further argue that C »junction«  should not short circuit. It should do the 
simple brute force try all values approach, since the side effects are likely 
desired. Operators, which should be able to accept junctions as parameters, are encouraged to 
short circuit, since there are no side effects possible for the evaluation of that operator. By 
the time the operator gets called, it should have all the parameters it needs, and there are no 
more side effects to be had.
As for C .. , I'd say that it should handle junctions being fed into it 
by throwing an exception.
-- Rod Adams



Re: Junction Values

2005-02-18 Thread Brent 'Dax' Royal-Gordon
Rod Adams [EMAIL PROTECTED] wrote:
 if $x == 3|4|5|6 {...}
 
 would thread over infix:== without any funkiness, since we'll assume 
 operators are well written, and can take junctions as parameters, same as:
 
 if is_prime(3|4|5|6) {...}
 
 Would pass the junction to is_prime, to do with as it pleases, including 
 throwing an exception. However,
 
 if is_prime(»3|4|5|6«) {...}
 
 would thread over is_prime, and collate the results outside of call.

So basically you're proposing that, rather than do one implicit loop
that'll probably do what you want, the default should be to do an
unknown number of implicit loops in somebody else's code, and you have
to ask explicitly for the more sensible behavior.  Somehow this
doesn't strike me as an improvement.

 These semantics also give us the ability to easily mix and match what we send 
 to a function, so we can say:
 
 if funky_test(all(@A), »any(@B)«) {...}

sub funky_test ( Junction|Any @a, @b ) { ... }

 Basically I'm putting all the power of threading into the hands of the caller.

The caller is not in a position to know if the callee is internally
structured in such a way that passing in a raw junction makes sense. 
The right place to say I can handle a junction, don't autothread is
in the callee; that's the behavior @Larry is proposing.

 As for C .. , I'd say that it should handle junctions being fed into it by 
 throwing an exception.

Why is this more sensible than returning a list of junctions in list
context and a junction of arrayrefs in scalar context?  (I believe
infix:.. will return an arrayref in scalar context, though I could
be wrong.)

(The array of junctions is negotiable, by the way; whatever it is,
though, it should probably be the same as the default meaning for list
returns from an autothreaded function.)

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junction Values

2005-02-18 Thread Brent 'Dax' Royal-Gordon
Rod Adams [EMAIL PROTECTED] wrote:
 Luke Palmer wrote:
 2..sqrt($x)
 
 What the hell does that mean?  Do you get a junction of lists out?  Or
 does sqrt die because it's not expecting a junction?
 
 What on earth does C for (2..sqrt(3|5)) {...}   mean in the current
 state of junctions?

In the current state of junctions, the autothreading is done at the
level of the call to do_prime, so $x is never a junction.  Only under
your notion of junctions as just another object with no autothreading
until the operator level will $x ever be a junction.

But if it somehow *did* become a junction, I would imagine something
like this would happen:

   for (2 .. sqrt( 3 | 5 )) { ... }
   for (2 .. ( sqrt 3 | sqrt 5 )) { ... }
   for ( ( 2 .. sqrt 3 ) | ( 2 .. sqrt 5 ) ) { ... }
   for ( 2 .. sqrt 3 ) { ... } | for ( 2 .. sqrt 5 ) { ... }#notionally

However, it's clear that the last step doesn't make a whole lot of
sense, since Cfor has no return value.  Maybe Cfor would be
declared with a signature that didn't allow junctions at all.

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

I will readily admit that the behavior of junctions in a slurpy
subroutine call is suboptimal, and it might be a good idea to
reexamine it.  However, I will also point out that most newbie
programmers probably won't use the @_ behavior, and likely won't be
using slurpy parameters either, while more experienced programmers
will know better.

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junction Values

2005-02-18 Thread Rod Adams
Brent 'Dax' Royal-Gordon wrote:
Rod Adams [EMAIL PROTECTED] wrote:
 

Luke Palmer wrote:
   

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

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

In the current state of junctions, the autothreading is done at the
level of the call to do_prime, so $x is never a junction. 

Actually, if one writes is_prime to have slurpy array passing a la 
Perl5, as I wrote in a different post, $x most certainly is a junction 
at this point.

Although this does beg the question: If by default one can't assign a 
junction to a variable, does this apply only in cases with an assignment 
operator, or does it also happen on parameter passing?

I've just reread Larry's post about normally disallowing storage of 
junctions in a lvalue. He covers the point about declaring parameters 
that are junctional, and the parameters are otherwise non-junctional. 
What is not clear here is whether or not the S09 talk about if a 
junction is inside another container (like a slurpy array), if it gets 
caught or not. The array itself is not a junction, but one or more of 
it's elements might be. So do we have to walk the entire reference tree 
if we are given a complex data type, looking for junctions? This is not 
an option, think no further than lazy lists to see why. So the other 
option is to have a runtime check, and as soon as a memory store 
containing a junction is encountered, then throw an exception. Even if 
this happens well after the parameter passing step. Hmm. Messy, but 
possible.


Only under
your notion of junctions as just another object with no autothreading
until the operator level will $x ever be a junction.
 

For the record, I've withdrawn that proposal.
All I want now is for autothreading to be explicit.
But if it somehow *did* become a junction, I would imagine something
like this would happen:
  for (2 .. sqrt( 3 | 5 )) { ... }
  for (2 .. ( sqrt 3 | sqrt 5 )) { ... }
  for ( ( 2 .. sqrt 3 ) | ( 2 .. sqrt 5 ) ) { ... }
  for ( 2 .. sqrt 3 ) { ... } | for ( 2 .. sqrt 5 ) { ... }#notionally
However, it's clear that the last step doesn't make a whole lot of
sense, since Cfor has no return value.  Maybe Cfor would be
declared with a signature that didn't allow junctions at all.
 

Or is it the case that C ..   acts a bit like the old flip flop it 
used to be, and stop at the first true value it sees?
AFAIK, the concept of Junctional Lists has not been created yet, so what 
else would it return? A list of junctions? all of which are ($x|$x) or 
($x|undef)?

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

I will readily admit that the behavior of junctions in a slurpy
subroutine call is suboptimal, and it might be a good idea to
reexamine it.  However, I will also point out that most newbie
programmers probably won't use the @_ behavior, and likely won't be
using slurpy parameters either, while more experienced programmers
will know better.
 

Except for the absolutely massive amount of Perl5 code out there that 
will be hastily translated by people who don't trust the Perl6 - Ponie 
interplay, and the flocks of Perl5 programmers coming over without 
learning all the new features of their upgraded language, you're 
probably right.

-- Rod Adams


Re: Junction Values

2005-02-18 Thread Rod Adams
Brent 'Dax' Royal-Gordon wrote:
Rod Adams [EMAIL PROTECTED] wrote:
 

   if $x == 3|4|5|6 {...}
would thread over infix:== without any funkiness, since we'll assume 
operators are well written, and can take junctions as parameters, same as:
   if is_prime(3|4|5|6) {...}
Would pass the junction to is_prime, to do with as it pleases, including 
throwing an exception. However,
   if is_prime(»3|4|5|6«) {...}
would thread over is_prime, and collate the results outside of call.
   

So basically you're proposing that, rather than do one implicit loop
that'll probably do what you want, the default should be to do an
unknown number of implicit loops in somebody else's code, and you have
to ask explicitly for the more sensible behavior.  Somehow this
doesn't strike me as an improvement.
 

What I'm asking for is to be in control of how often I get the possible 
side effects of calling a function. If I make a call to a DBI method to 
go insert a record, I want exactly 0 (on error) or 1 (on success) 
records inserted into my database, _unless_ I told it do otherwise. 
Since a junction is a single item, it should produce a single effect 
_unless_ I tell it to expand the values and act like several items at once.

Simply put, I want control over my side effects.
As for whether passing the junction as a junction or passing the 
junction via autothreading should be the default:

Junctions exists. I want to say stay a junction or explode into 
pieces, go your separate ways, and then come back. In one case I'm 
doing nothing to the junction, in the other case I'm doing quite a bit. 
So it makes sense that the latter is something additional to the former.

Taking into account how common that particular action might be, I chose 
to propose a rather short modification to it, that still clearly said 
something special was going on here. One could say I'm just extending 
the hyper operator from do this operator several times to do this 
expression several times.

More sensible behavior is entirely subject to the exact instance at 
hand. In the case of let's say C == , I want to feed it the raw, 
unexploded junction.
I well written C ==  should be able to apply all kinds of 
optimizations to the task at hand, and provide much more sensible results.
I expect calls with operators to be considerably more common than 
function calls w/ junctions.

So if I grant you your default of autothreading, we then get:
   if $x == »3|4|5« {...}
   given $x {
  when »3|4|5« {...}
   }
Which seemed far more suboptimal than the other way around, IMO.
These semantics also give us the ability to easily mix and match what we send 
to a function, so we can say:
   if funky_test(all(@A), »any(@B)«) {...}
   

sub funky_test ( Junction|Any @a, @b ) { ... }
 

Unless you have a junction, and you wanted it to autothread on the first 
parameter, rather than be passed in, in order to get some perceived 
desirable side effect out of funky_test that passing it a Junction would 
only give a subset of.

Suppose funky_test is a derivative of C printf . Only this printf 
let's you feed it a junction for the format, and it will sort through 
them and see which one matches best depending on actual number of 
parameters, parameter types, etc. Ordinarily, this would be fairly cool 
stuff.
But let's say you instead wanted it to print the same data with all the 
different formats. With my calling, you could make the distinction 
rather easily. With yours, you have to set up the looping yourself.

Basically I'm putting all the power of threading into the hands of the caller.
   

The caller is not in a position to know if the callee is internally
structured in such a way that passing in a raw junction makes sense. 
 

Sure they are. It's called reading the documentation. If it doesn't say 
it can handle junctions, it probably can't.

The right place to say I can handle a junction, don't autothread is
in the callee; that's the behavior @Larry is proposing.
 

I'm sending the same message. Only my message goes to the programmer, 
not the runtime.
I'm also making it where the decision to insert autothreading code or 
not is made at compile time, not runtime.

As for C .. , I'd say that it should handle junctions being fed into it by throwing an exception.
   

Why is this more sensible than returning a list of junctions in list
context and a junction of arrayrefs in scalar context?  (I believe
infix:.. will return an arrayref in scalar context, though I could
be wrong.)
(The array of junctions is negotiable, by the way; whatever it is,
though, it should probably be the same as the default meaning for list
returns from an autothreaded function.)
 

About the only thing is could return would be a lazy list of junctions. 
And about the only places C ..  gets used is inside C for  and 
inside array slice indices. Lists of junctions certainly make no sense 
in a for loop... the loop cannot simultaneously exit and not exit at the 
same time. Feeding a list 

Re: Junction Values

2005-02-18 Thread Brent 'Dax' Royal-Gordon
Rod Adams [EMAIL PROTECTED] wrote:
  Suppose funky_test is a derivative of C printf . Only this printf let's
 you feed it a junction for the format, and it will sort through them and see
 which one matches best depending on actual number of parameters, parameter
 types, etc. Ordinarily, this would be fairly cool stuff.
  But let's say you instead wanted it to print the same data with all the
 different formats. With my calling, you could make the distinction rather
 easily. With yours, you have to set up the looping yourself. 

I would argue that this function is badly designed.

Junctions are intended to ultimately be used in boolean tests.  That's
why the values of the junction have an any/all/one/none relationship. 
The proper data structure here is an array.  (Actually, ironically
enough, it's probably a set, not an array.)

IMHO, there are three cases where it's legitimate to specifically ask
for junctions to be passed in:
1. When it makes absolutely no sense to use a junction in a particular
function, especially one with side effects.[1]
2. When doing some sort of junction-aware serialization, a la Storable
or Data::Dumper.
3. When the author of the function can optimize the way junctions are
handled without changing their basic semantics.

Outside of these cases, it's probably wrong.

A junction is *not* a meaningless data structure to be slung around at
will; it is a construct that implies a certain type of behavior when
used.

  The caller is not in a position to know if the callee is internally
  structured in such a way that passing in a raw junction makes sense.
 
 Sure
 they are. It's called reading the documentation. If it doesn't say it can
 handle junctions, it probably can't.

I don't want to have to stop in the middle of a hundred-line function
to think, Does Store::Market.get act sanely when I give it a
junction?  Do I need to explode it manually, or will it handle the
junction nicely on its own?  Nor do I want to work in a language
where most functions don't handle a basic construct elegantly, even
when they can.

 About the only thing is could return
 would be a lazy list of junctions. And about the only places C ..  gets
 used is inside C for  and inside array slice indices. Lists of junctions
 certainly make no sense in a for loop... the loop cannot simultaneously exit
 and not exit at the same time.

You don't think this makes sense?  (Cfor itself wouldn't autothread;
the calls and operators inside the loop body would.)

for 1|2, 3|4, 5|6 { ... }

(Actually, Synopsis 3 talks about what happens when you give Cfor a
single junction--essentially, it loops over the contents of the
junction in whatever order it feels is most optimal.  But in this case
we're giving it an array of junctions, which presumably would act
differently)

 Feeding a list of junctions into an array
 slice index is asking for what? Another list of junctions out?

Synopsis 3:

print if @foo[any(1,2,3)]


[1] Note, however, that this needs to be done carefully.  For example,
while it doesn't really make sense for the string arguments of a call
to Cprint to be junctions, the object argument is another matter
entirely:
#!/usr/bin/perl6
# naive tee
$OUT=$OUT  open( $_) for @ARGS;
print or die Can't write to $!.filename: $! for *$IN;# Or
however it's done this week

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junction Values

2005-02-18 Thread Damian Conway
Rod Adams wrote:
All I want now is for autothreading to be explicit.
It already *is*.
The only way that:
is_prime($x)
can ever autothread is if $x holds a junction. But that can now only happen if 
there's an explicit Cuse junctions in scope where $x was assigned to (or the 
explicit use of some other module that also activates Cuse junctions). So $x 
having a junction must be a known possibility at that point.

Of course, literal junctions *will* autothread in all circumstances:
is_prime(any(6,7,8))
is_prime(6|7|8)
But they're both explicit too: you're explicitly using junction constructors, 
so the autothreading can hardly come as a surprise.

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

Junctions are just another type of scalar value. All the arguments I hear 
against that seem to mirror the arguments we always hear against Perl scalars 
being dynamically typed at all: but how will you know whether $x has a number 
or a string or a reference in it??? And of course the answer is: most people 
know most of the time, simply by paying attention to the data flow of their 
program. And when they occasionally mess up and accidentally give a function 
or subroutine the wrong kind of value, Perl usually warns them about it.

Personally, I think it's completely fascist to require a Cuse junctions 
pragma in order for junctions to even be stored in variables. It's as bizarre 
as requiring Cuse strings or Cuse references or Cuse undef or Cuse 
infinities would be. Yes, it *is* possible to get unexpected behaviour from 
passing a junction where it isn't expected, but it's already possible to get 
unexpected behaviour by passing a string or an undef or a reference or an 
object where it isn't expected. Junctions are nothing new in that respect.

I think junctions ought to be first class scalar data types and not have to 
ask permission before they can even be assigned. If you want to be sure that a 
particular variable doesn't have a junction in it, you should have to specify 
that, in exactly the same way you have to be explicit in order to prevent a 
variable storing a string or a reference or an object...by giving it an 
explicit type:

my Num $x; # Can't store a string or reference
my Ref $y; # Can't store a number or string
my Nonjunctive $x; # Can't store junctions
And where did CNonjunctive come from? I created it. Ironically, by using the 
Awesome Power of Junctions:

type Nonjunctive ::= none(Junction);
And if typing a variable to prevent it storing a junction is too onerous, it 
would still be perfectly sufficient to simply provide a Cno junctions 
pragma, under whose geas no junction shall be suffered to live.

Look, I do understand the arguments in the other direction. I've understood 
them for the past five years that I've been developing the concept of 
superpositional data-types. I've thought them through numerous times myself, 
and in the end: I just don't buy them.

The whole point of junctions is to make the threading of operations on 
datasets both automatic and implicit; to make it Do The Right Thing without 
the hassles of explicit threading. If you don't want that, that's fine: just 
don't use junctions. Use arrays and hyperoperators instead. And we'll happily 
give you a Cno junctions pragma so you can be emphatic about not wanting them.

But bowdlerizing the concept of junctions isn't the answer.
Damian


Re: Junction Values

2005-02-17 Thread Rod Adams
Brent 'Dax' Royal-Gordon wrote:
Rod Adams [EMAIL PROTECTED] wrote:
 

Larry Wall wrote:
   

That, and we'd like a novice to be able to write
  given $x {
 when 1 | 2 | 3 {...}
 when 4 | 5 | 6 {...}
  }
Or just change Cwhen to accept a list of things to compare against,
followed by a coderef.
   

And change if, unless, while and until to do the same thing.  
 

Actually, upon further investigation, I believe we get this all of this 
without junctions.

According to S03, The scalar comma |,| now constructs a list reference 
of its operands.
Then S04 mentions that C $scalar ~~ @array  is true if $scalar is in 
@array.
Since C given ... when  uses smart matching for it's evaluation, one 
should be able to write the above as:

given $x {
 when 1, 2, 3 {...} # at worst, this is:  when (1,2,3) {...}
 when 4, 5, 6 {...}
}
The simple if is:
if $x ~~ (1,2,3,4) {...} # parens needed here since , is lower than ~~ 
in precedence.

Same for unless/while/until. And all of this from the entirely useful C 
~~ . The S04 code describing @Array ~~ $Scalar (for Num/Str) uses 
junctions, but I'd argue a better implementation would be a short 
circuiting C for  loop, even if junctions exist. It's just plain 
faster that way.

So what I see now for utility of junctions is thus:
- Common cases which C ~~  appears to handle for us suitably well.
- Edge cases which, IMHO, do not merit the huffman level of several 
single character operators. All of which can be accomplished without the 
use of junctions, though not as gracefully.

I see no need for junctions in core.
And lose the ability to say:
   when none(1, 2, 3) { ... }
   when 1 ^ 2 ^ 3  { ... }# More useful with classes, regexen, etc.
   when 1  2  3 { ... }# Likewise
All so that a newbie doesn't confuzzle himself.
 

You can always write your switch statements the Perl 5 way.
Or you could write:
   when ({$^a ~~ /1/   $^a ~~ /2/   $^a ~~/3/}) {...}
And the like. Look up what C $scalar ~~ $coderef  does if you're not 
convinced.
(side question: what is the proper syntax for using a closure as the 
evaluation expression in a C when  statement?)

hmm, since the $_ is set, you could likely get away with:
   when ({/1/   /2/   /3/}) {...}
in the case of RE's.
Personally, I'd rather have a chain saw than a nail trimmer, even if
I'm less likely to hurt myself with the nail trimmer.  And it looks
like we'll have a warning or stricture to keep newbies from chopping
their legs off anyway.
 

I can understand your sentiments here, but I'd be a lot more sympathetic 
to your cause if the alternative ways of accomplishing these things were 
actually difficult. I think it's been demonstrated that any of the 
junction evaluations could be done with a call to C grep , with 
numerous other ways to perform them as well.

-- Rod Adams


Re: Junction Values

2005-02-17 Thread Larry Wall
On Thu, Feb 17, 2005 at 02:18:55AM -0600, Rod Adams wrote:
: The simple if is:
: 
: if $x ~~ (1,2,3,4) {...} # parens needed here since , is lower than ~~ 
: in precedence.

That is asking if $x is a list containing 1,2,3,4.

: Same for unless/while/until. And all of this from the entirely useful C 
: ~~ . The S04 code describing @Array ~~ $Scalar (for Num/Str) uses 
: junctions, but I'd argue a better implementation would be a short 
: circuiting C for  loop, even if junctions exist. It's just plain 
: faster that way.

Junctions can short circuit when they feel like it, and might in some
cases do a better job of picking the evaluation order than a human.

: So what I see now for utility of junctions is thus:
: 
: - Common cases which C ~~  appears to handle for us suitably well.

Only if we make lists second-class citizens.  The need for junctions
first became evident when we found ourselves filling the ~~ tables
with various sorts of weird non-symmetries.

: - Edge cases which, IMHO, do not merit the huffman level of several 
: single character operators. All of which can be accomplished without the 
: use of junctions, though not as gracefully.

Grace is important.  Even more important is mapping naturally to human
linguistic structures, to the extent that it can be done unambiguously.

: I see no need for junctions in core.

I do, and I'm not likely to change my mind on this one.  Sorry.

Larry


Re: Junction Values

2005-02-17 Thread John Macdonald
On Thu, Feb 17, 2005 at 09:06:47AM -0800, Larry Wall wrote:
 Junctions can short circuit when they feel like it, and might in some
 cases do a better job of picking the evaluation order than a human.

Hmm, yes, there is an interesting interaction with lazy
evaluation ranges here.

$x = any( 1 .. 1_000_000_000 );

if( $y == $x ) { ... }

It would be nice if the junction equality test here was much
smarter than a for loop (regardless of whether the for loop
short circuited - suppose $y happens to be -1!).

A range need not enumerate all of its components to be used
in a useful way.

-- 


Re: Junction Values

2005-02-17 Thread Rod Adams
Larry Wall wrote:
On Thu, Feb 17, 2005 at 02:18:55AM -0600, Rod Adams wrote:
: The simple if is:
: 
: if $x ~~ (1,2,3,4) {...} # parens needed here since , is lower than ~~ 
: in precedence.

That is asking if $x is a list containing 1,2,3,4.
 

Quoting S04:
   $_  $xType of Match ImpliedMatching Code
   ==  = ==
   Array   Array arrays are identical match if $_ »~~« $x
   Array   any(list) list intersectionmatch if any(@$_) ~~ any(list)
   Array   Rule  array grep   match if any(@$_) ~~ /$x/
   Array   Num   array contains numbermatch if any($_) == $x
   Array   Str   array contains stringmatch if any($_) eq $x
And since there are no tell tell *'s on these saying that they are _not_ 
reversible, I must assume they _are_.

In C if $x ~~ (1,2,3,4) {...} , if $x is type Num or Str, then I see 
no way of reconciling your statement above.

: Same for unless/while/until. And all of this from the entirely useful C 
: ~~ . The S04 code describing @Array ~~ $Scalar (for Num/Str) uses 
: junctions, but I'd argue a better implementation would be a short 
: circuiting C for  loop, even if junctions exist. It's just plain 
: faster that way.

Junctions can short circuit when they feel like it, and might in some
cases do a better job of picking the evaluation order than a human.
 

I was afraid someone was going to say that. And I now must convert my 
reservations about junction autothreading from very disturbing to 
you've got to be kidding.

According to Patrick, and since no one has corrected him, I will assume 
he is right,

perl6 -e say1 'cat'|'dog'; sub say1 ($x) {say $x}
Should output cat\ndog\n or dog\ncat\n. Now, if we allow Junctions to short circuit, and since there is no fixed order of values in a junction, we could get any of cat\ndog\n, dog\ncat\n, cat\n, or dog\n. 
What's that get us? non-deterministic output! I could handle non-deterministic *order* of output, because by the simple fact that you were using a junction, you didn't care about order.

Non-deterministic output! how fun!
Not to mention it contradicts S09:
... that routine is autothreaded, meaning the routine will be called 
automatically as many times as necessary to process the individual scalar elements of the junction 
in parallel.
Now there is some wiggle room in there for short circuiting, but not very much.

: So what I see now for utility of junctions is thus:
: 
: - Common cases which C ~~  appears to handle for us suitably well.

Only if we make lists second-class citizens.  The need for junctions
first became evident when we found ourselves filling the ~~ tables
with various sorts of weird non-symmetries.
 

So what other semantic makes sense for:
Str ~~ Array
Num ~~ Array
which would better appeal to your sense of symmetry?
Besides, people were telling me that my Sets were not needed, because 
they could be rendered with Arrays and Hashes. I fail to see how 
junctions are that different.

: - Edge cases which, IMHO, do not merit the huffman level of several 
: single character operators. All of which can be accomplished without the 
: use of junctions, though not as gracefully.

Grace is important.  Even more important is mapping naturally to human
linguistic structures, to the extent that it can be done unambiguously.
 

In my experience, English tends not to superimpose several values on a 
given noun at once.

: I see no need for junctions in core.
I do, and I'm not likely to change my mind on this one.  Sorry.
 

I realized that fairly early on. The situation I'm in is that while I 
don't agree with all the design initiatives that come out here, it's 
been the case that the more I think about them, the more I like them. I 
always achieve at least a state of ambivalence or better about it.

With Junctions, it's been the case that at first I thought they were 
useful and cool, but the more I think about them, the more I dislike them.

I'll argue my case for a few more days, and if I haven't gotten anywhere 
by then, I'll likely give up.

-- Rod Adams


Re: Junction Values

2005-02-16 Thread Eirik Berg Hanssen
Jonathan Scott Duff [EMAIL PROTECTED] writes:

 On Wed, Feb 16, 2005 at 12:17:35PM +1100, Damian Conway wrote:
 none($a, $a) == undef
 
 True.

 Isn't this one false in the case when $a is undef?

  Since it is numerical comparison, it is false as long as $a == 0.
(I would hope.)


Eirik
-- 
So this is the Sword of Immortality?  Huh?
 What's it doin' in a CRYPT?!
   --- John S. Novak, III, quoting an unnamed player


Re: Junction Values

2005-02-16 Thread Nigel Sandever
On Wed, 16 Feb 2005 12:17:35 +1100, [EMAIL PROTECTED] (Damian Conway) wrote:
 
 ..values tells you what raw values are inside the junction. The other kind of 
 introspection that's desirable is: what raw values can *match* this 
 junction. There would probably be a .states method for that.
 
 To see the difference between the two, consider:
 
   my $ideal_partner = all( any(tall dark rich),
   any(rich old frail),
   any(Australian rich),
 );
 
 $ideal_partner.values would return the three distinct values in the junction:
 
   ( any(tall dark rich),
any(rich old frail),
any(Australian rich),
  );
 
 But $ideal_partner.states would return only those non-junctive values that 
 (smart-)match the junction. Namely, rich.
 
 
 

I, and I think many others, have been trying to follow along on the discussions 
regarding junctions, and I have to say that for the most part, much of it goes
insert graphic of open hand, palm down, waving to and fro above head.

Any chance that you could provide one or two simple but realistic examples of 
using Junctions and their operators?

I see individual snippets of use and they appear to make sense, but when I try 
envisage using them in code I have recently written, I find nothing leaping off 
the page at me as an obvious candidate.

Thanks.




Re: Junction Values

2005-02-16 Thread Patrick R. Michaud
On Wed, Feb 16, 2005 at 01:06:22PM +, Nigel Sandever wrote:
 
 Any chance that you could provide one or two simple but realistic examples of 
 using Junctions and their operators?

I'll give it a shot, but keep in mind that I'm somewhat new to this 
also.  :-)

First, junctions are an easy way to represent the relationships
any, all, one, or none.  So, where we once had to say:

   if ($x==$a or $x==$b or $x==$c or $x==$d) { ... }

we can now say

   if $x == any($a, $b, $c, $d) { ... }

Similarly, where we once had to say

   if (grep { $x == $^z } @list) { ... }
   if (grep { $x == $^z } @list) == 0 { ... }
   
we can now say

   if $x == any(@list) { ... }
   if $x == none(@list) { ... }

And for fun, try writing the equivalent of 

   if $x == one($a, $b, $c, $d) { ... }

without a junction.  (Okay, one can cheat with Cgrep.)

A programmer can easily use these without having to worry about the
notions of autothreading or superpositions or the like, and
their translations to English are fairly obvious.  I suspect that
constructs like the above will be the majority of use for junctions.

Things start to get weirder when we start storing junctions into
variables, and/or passing those variables/junctions into subroutines.
But I think this is not *too* far removed from the idea of placing a 
subroutine or a rule into a scalar -- i.e., using a scalar to represent
something more than a single-valued primitive type.  Thus, just as one
can write

   $x = new CGI;
   $y = rule { \d+ };
   $z = sub { ... };

and then use $x, $y, and $z later on for an object, rule, and sub 
(which may have a variety of side-effects associated with them), it makes
sense that one can write

   $w = any(@list);

and then use $w to refer to the junction later.  And a programmer who
does this is taking on some responsibility for understanding that $w
isn't one of the trivial scalars anymore (same as for $x, $y, and $z).

However, one difference is that when one typically uses an object, rule,
or subroutine in a scalar there is some syntax that makes their nature
apparent.  Some feel that Junctions might be just a bit too magical
in this respect (e.g., Luke has made some syntactic suggestions to try
make the existence/threading of a junction more apparent).

Pm


Re: Junction Values

2005-02-16 Thread Nigel Sandever
On Wed, 16 Feb 2005 09:18:42 -0600, [EMAIL PROTECTED] (Patrick R. Michaud) 
wrote:
 On Wed, Feb 16, 2005 at 01:06:22PM +, Nigel Sandever wrote:
  
  Any chance that you could provide one or two simple but realistic examples 
of 
  using Junctions and their operators?
 
 I'll give it a shot, but keep in mind that I'm somewhat new to this 
 also.  :-)
 
 First, junctions are an easy way to represent the relationships
 any, all, one, or none.  So, where we once had to say:
 
if ($x==$a or $x==$b or $x==$c or $x==$d) { ... }
 
 we can now say
 
if $x == any($a, $b, $c, $d) { ... }
 
 Similarly, where we once had to say
 
if (grep { $x == $^z } @list) { ... }
if (grep { $x == $^z } @list) == 0 { ... }


 we can now say
 
if $x == any(@list) { ... }
if $x == none(@list) { ... }
 

I'd write the P5 none() case as 

if ( grep { $x != $_ } @list ) { ... }
or
unless( grep{ $x == $_ } @list ) { ... }

which tends to reduce the sugaryness of the new syntax slightly.

 And for fun, try writing the equivalent of 
 
if $x == one($a, $b, $c, $d) { ... }

I'm also not entirely sure at this point whether that means

if( grep( { $x == $_ } $a, $b, $c, $d ) == 1 ) { ... }

or something different?

 
 without a junction.  (Okay, one can cheat with Cgrep.)


But most of those examples pretty clear and understandable. I'm not sure that I 
see their convenience alone as a convincing arguement for the existance of 
Junctions. I keep thinking that there is something altogether more 
fundementally 
useful and ...well... cleverer underlying their inclusion, but at this stage I 
am not seeing it. 

In this usage, they appear to be replicating functionality that is already 
being 
provided via the inclusion of the hyper-operators.
('scuse me if I skip the unicode and/or get the syntax wrong!)

if(   $x == @list ){ ... }   ## any?
if(   $x != @list ){ ... }   ## none?
if( ( $x == @list ) == 1 ) { ... }   ## one?
if( ( $x == @list ) == @list ) { ... }   ## all?

It would very much depend upon what a hyper operator returns in a boolean 
context, but they /could/ be made to work as I've indicated I think. 

If the hyper operator returned one boolean result for each comparison it made, 
and if a list of boolean values in a boolean context collapsed to a count of 
the 
trues/1s it contained, I think those would work. You would also get the bonus of

if( ( $x == @list ) == 2 ) { ... } ## two() ( three(), ten() etc. )
if( ( $x = @list ) == @list/2 ) { ... } ## fify percent below...

But I think the promise of Junctions appears to come from using them in 
conjunction with each other. 

$x = any( @list1 );
$y = all( @list2 );
$z = none( @list3 );
if( $x = $y ) { ... }
if( any( $x != $y ) or all( $y == $z ) ) { ... }

except that I haven't got a clue what those mean? 

I've sat and starred at the worked examples given elsewhere in this and the 
other thread, and whilst I can follow how the results are derived when someone 
lays them out for me--though I fell into the trap of accepting the one where 
Damian made a mistake, which probably means I wasn't paying close enough 
attention--when I get to the the last line and see that the answer it true (or 
false), I look back at the original unexpanded statement and think: 

Yes! But what does it mean? When and where is that going to be useful?
 
 A programmer can easily use these without having to worry about the
 notions of autothreading or superpositions or the like, and
 their translations to English are fairly obvious.  I suspect that
 constructs like the above will be the majority of use for junctions.
 
 Things start to get weirder when we start storing junctions into
 variables, and/or passing those variables/junctions into subroutines.
 But I think this is not *too* far removed from the idea of placing a 
 subroutine or a rule into a scalar -- i.e., using a scalar to represent
 something more than a single-valued primitive type.  Thus, just as one
 can write
 
$x = new CGI;
$y = rule { \d+ };
$z = sub { ... };
 
 and then use $x, $y, and $z later on for an object, rule, and sub 
 (which may have a variety of side-effects associated with them), it makes
 sense that one can write
 
$w = any(@list);
 
 and then use $w to refer to the junction later.  And a programmer who
 does this is taking on some responsibility for understanding that $w
 isn't one of the trivial scalars anymore (same as for $x, $y, and $z).
 
 However, one difference is that when one typically uses an object, rule,
 or subroutine in a scalar there is some syntax that makes their nature
 apparent.  Some feel that Junctions might be just a bit too magical
 in this respect (e.g., Luke has made some syntactic suggestions to try
 make the existence/threading of a junction more apparent).


I see the dangers of scalars that aren't 

Re: Junction Values

2005-02-16 Thread Patrick R. Michaud
On Wed, Feb 16, 2005 at 06:04:37PM +, Nigel Sandever wrote:
 On Wed, 16 Feb 2005 09:18:42 -0600, [EMAIL PROTECTED] (Patrick R. Michaud) 
 wrote:
  And for fun, try writing the equivalent of 
 if $x == one($a, $b, $c, $d) { ... }
  without a junction.  (Okay, one can cheat with Cgrep.)
 
 I'm also not entirely sure at this point whether that means
   if( grep( { $x == $_ } $a, $b, $c, $d ) == 1 ) { ... }
 or something different?

Yes, that's essentially correct.  

 In this usage, they appear to be replicating functionality that is 
 already being provided via the inclusion of the hyper-operators.
 ('scuse me if I skip the unicode and/or get the syntax wrong!)
 
   if(   $x == @list ){ ... }   ## any?
   if(   $x != @list ){ ... }   ## none?
   if( ( $x == @list ) == 1 ) { ... }   ## one?
   if( ( $x == @list ) == @list ) { ... }   ## all?

Ouch, this makes my head hurt.  :-)

A syntax note -- C== is an infix operator, thus the correct
syntax would have to be

   if(   $x == @list ){ ... }   ## any?
   if(   $x != @list ){ ... }   ## none?

and the result of $x == @list would end up being a list of
true/false values.  

 If the hyper operator returned one boolean result for each 
 comparison it made, and if a list of boolean values in a 
 boolean context collapsed to a count of the trues/1s it contained, 
 I think those would work. 

Part of the problem is that we don't have a list of boolean values
that is somehow distinguishable from list of values.  (And a list
evaluated in boolean context is true if the list is non-empty.)

If we create a list of boolean values type, it effectively becomes
a junction.  :-)

 But I think the promise of Junctions appears to come from using them in 
 conjunction with each other. 
 
   $x = any( @list1 );
   $y = all( @list2 );
   $z = none( @list3 );
   if( $x = $y ) { ... }
   if( any( $x != $y ) or all( $y == $z ) ) { ... }
 
 except that I haven't got a clue what those mean? 

Well, 

 if ($x = $y) { ... }

is better written out as:

 if ( any(@list1) = all(@list2) ) { ... }

which reads if any of the elements of list1 are less than or equal to
all of the elements of list2.  One could arguably claim/show that this
is mathematically equivalent to   

 if ( min(@list1) = min(@list2) ) { ... } 

except that junctions could potentially work with relationships that
aren't transitive as C =  is.

I'll have to think about your second Cif statement a bit -- I agree
that it's not immediately obvious what it means, but I'm not sure that
we could come up with an alternate way of writing it which is also
immediately obvious.  Phrased another way -- regardless of the
construct being discussed we can probably write an expression using
that construct that isn't easily deciphered at first.

 I've sat and starred at the worked examples given elsewhere in this 
 and the other thread, and [...] I look back at the original 
 unexpanded statement and think: 
 
 Yes! But what does it mean? When and where is that going to be useful?

Part of the reason for this may simply be that many of the examples 
discussed in these threads are in fact edge cases that have been
designed to illustrate a point rather than to be useful.  Indeed,
they're discussed simply because they aren't obvious.

 And whilst the simple examples show some syntatic sugaryness, I think that it 
 will not be until I begin to see how to apply the more complex cases 
 to real-world problems that I could reach a conclusion about whether 
 the value of their inclusion outweights the onus of awareness the 
 impose upon the programmer.

I think one can make this observation for many features slated for
Perl 6 -- i.e., the simple cases look simple but the full application
of complex cases isn't always immediately obvious.  I know I get this
feeling from looking at things like roles, mixins, slurpy arrays, 
slurpy hashes, Ctemp declarations, hypotheticals, hyperoperators, etc.  
However, just as I don't have to be aware of every CPAN module that 
exists in order to write Perl programs, I don't think having these 
features built into the language will require a great deal of 
awareness on the programmer until the programmer chooses to use them.

Others could reasonably disagree with this statement.  And to
anticipate the followup question of Well, why not make features such
as junctions into optional modules?, I think a partial answer is that
features like these really need deep language support to work
effectively in their complex applications.  Otherwise we'd just
stick with Perl 5. :-)

Pm


Re: Junction Values

2005-02-16 Thread Larry Wall
On Wed, Feb 16, 2005 at 01:55:31PM -0600, Patrick R. Michaud wrote:
: And to
: anticipate the followup question of Well, why not make features such
: as junctions into optional modules?, I think a partial answer is that
: features like these really need deep language support to work
: effectively in their complex applications.  Otherwise we'd just
: stick with Perl 5. :-)

That, and we'd like a novice to be able to write

given $x {
when 1 | 2 | 3 {...}
when 4 | 5 | 6 {...}
}

without having to know there are junctions there underneath.  Forcing
them to cargo-cult a use junctions declaration merely to get switch
alternatives would not solve any problems I can think of.  Nor would
inventing a separate switch syntax for alternatives be appropriate when
we can make junctions work for that in a semi-orthogonal fashion.  As I
said elsewhere, the training wheels probably belong on the variable's
type checking, not on the underlying type space.  Variable types are
*views* into the actual underlying object types bound to the variable,
and so variable types can place arbitrary restrictions on the use of
those underlying general types.

Larry


Re: Junction Values

2005-02-16 Thread Rod Adams
Patrick R. Michaud wrote:
On Wed, Feb 16, 2005 at 06:04:37PM +, Nigel Sandever wrote:
If the hyper operator returned one boolean result for each 
comparison it made, and if a list of boolean values in a 
boolean context collapsed to a count of the trues/1s it contained, 
I think those would work. 
   

Part of the problem is that we don't have a list of boolean values
that is somehow distinguishable from list of values.  (And a list
evaluated in boolean context is true if the list is non-empty.)
If we create a list of boolean values type, it effectively becomes
a junction.  :-)
What if we instead redefine any/all/one/none to be functions (and/or 
list methods) that take a list, evaluates each element in boolean 
context, and returns boolean?

Therefore, Nigels's examples become:
   if any( $x »==« @list) { ... }
   if none($x »==« @list) { ... }
   if all( $x »==« @list) { ... }
   if one( $x »==« @list) { ... }
Then case that I see happening most often will then be:
   if any($x »==« (1,2,10,100,200,1000,2000)) { ... }
I'll also throw in the argue that anything much more complex than this 
definitely falls into the category of edge case, and is of dubious 
utility, and IMHO, a lot of danger.

It occurred to me that junctions felt a lot like typeglobs. Very 
powerful thing, that little *. But also something that experienced 
programmers tell inexperienced ones something like Don't mess with them 
unless you really understand them. Then throw in that most programmers 
use a heavy dose of lexicals, which aren't typeglobable. In the end, you 
are left with only one useful idiom left:
   *NewFunc = sub {...};
Which will usually appears inside an AUTOLOAD.
(yes, I'm sure that Damian and some others on this list can create 
exceptionally cool use of typeglobs, in ways that would warp our minds, 
but I'm talking overall utility).

How does this relate to junctions? All I think anyone ever *asked* for 
out of a junction was an easier way to write:

   if ($x==$a or $x==$b or $x==$c or $x==$d) { ... }
The rest of the invention feels like Magic, and is something the 
experienced will tell the inexperienced not to mess with until they 
really understand the consequences of using them. And even then, few of 
the experienced will make more use of it than the simple case.

-- Rod Adams



Re: Junction Values

2005-02-16 Thread Rod Adams
Larry Wall wrote:
That, and we'd like a novice to be able to write
   given $x {
when 1 | 2 | 3 {...}
when 4 | 5 | 6 {...}
   }
Or just change Cwhen to accept a list of things to compare against, 
followed by a coderef.

-- Rod Adams


Re: Junction Values

2005-02-16 Thread Ashley Winters
On Wed, 16 Feb 2005 14:29:14 -0600, Rod Adams [EMAIL PROTECTED] wrote:
 Larry Wall wrote:
 
 That, and we'd like a novice to be able to write
 
 given $x {
when 1 | 2 | 3 {...}
when 4 | 5 | 6 {...}
 }
 
 Or just change Cwhen to accept a list of things to compare against,
 followed by a coderef.

Well, I don't think anyone can argue that having ~~ behave properly
with junctions is wrong. After all, we can make it do whatever we
want.

$foo ~~ 1 | 2 | 3

Perhaps we can make ~~ an even more magical comparison operator.

$x ~~ $y is a huffmanized version of $x ~==~ $y

@x ~~ $y is a smart-match based on  instead of ==

Or perhaps you can choose on which side the magic works:

@x ~ $y

OK, enough craziness for today.

$foo ~~ $bar   # uses Clt for strings, C+for numbers, voodoo for
junctions, etc...

Ashley


Re: Junction Values

2005-02-16 Thread Brent 'Dax' Royal-Gordon
Rod Adams [EMAIL PROTECTED] wrote:
 Larry Wall wrote:
 That, and we'd like a novice to be able to write
 
 given $x {
when 1 | 2 | 3 {...}
when 4 | 5 | 6 {...}
 }
 
 Or just change Cwhen to accept a list of things to compare against,
 followed by a coderef.

And change if, unless, while and until to do the same thing.  And lose
the ability to say:

when none(1, 2, 3) { ... }
when 1 ^ 2 ^ 3  { ... }# More useful with classes, regexen, etc.
when 1  2  3 { ... }# Likewise

All so that a newbie doesn't confuzzle himself.

Personally, I'd rather have a chain saw than a nail trimmer, even if
I'm less likely to hurt myself with the nail trimmer.  And it looks
like we'll have a warning or stricture to keep newbies from chopping
their legs off anyway.

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Junction Values

2005-02-15 Thread Rod Adams
Okay, so we've established that:
$x = any(3,4,5);
@l = $x.values.sort;
Leaves us with @l == (3,4,5), and that makes a fair amount of sense.
What do the following evaluate to:
@l1 = all(3,4,5).values.sort;
@l2 = one(3,4,5).values.sort;
@l3 = none(3,4,5).values.sort;
@l4 = any(all(1,2),all(3,4)).values.sort;
If C.values doesn't it cut it for these cases, what other forms of 
introspection are we going to allow on junctions, to determine what they 
are?


On a slightly different topic, do the following equivalences work:
any($a, $a) == $a
any($a,$a,$b) == any($a,$b)
any(any($a,$b),any($c,$d)) == any($a,$b,$c,$d)
all($a, $a) == $a
all($a,$a,$b) == all($a,$b)
all(all($a,$b),any($c,$d)) == all($a,$b,$c,$d)
none($a, $a) == undef
none($a,$a,$b) == none($a,$b)
none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d)
one($a, $a) == false
one($a,$a,$b) == ($a == $b ?? undef ::  $b)

-- Rod Adams


Re: Junction Values

2005-02-15 Thread Damian Conway
Rod Adams wrote:
Okay, so we've established that:
$x = any(3,4,5);
@l = $x.values.sort;
Leaves us with @l == (3,4,5), and that makes a fair amount of sense.
What do the following evaluate to:
@l1 = all(3,4,5).values.sort;
Same.
@l2 = one(3,4,5).values.sort;
Same.
@l3 = none(3,4,5).values.sort;
Same.

@l4 = any(all(1,2),all(3,4)).values.sort;
  = (all(1,2),all(3,4)).sort
  = (all(1,2),all(3,4))

If C.values doesn't it cut it for these cases, what other forms of 
introspection are we going to allow on junctions, to determine what they 
are?
.values tells you what raw values are inside the junction. The other kind of 
introspection that's desirable is: what raw values can *match* this 
junction. There would probably be a .states method for that.

To see the difference between the two, consider:
my $ideal_partner = all( any(«tall dark rich»),
 any(«rich old frail»),
 any(«Australian rich»),
   );
$ideal_partner.values would return the three distinct values in the junction:
( any(«tall dark rich»),
  any(«rich old frail»),
  any(«Australian rich»),
);
But $ideal_partner.states would return only those non-junctive values that 
(smart-)match the junction. Namely, rich.


On a slightly different topic, do the following equivalences work:
(I will assume in all my answers that $a, $b, $c, $d have different values, 
except where it doesn't matter either way).


any($a, $a) == $a
True.

any($a,$a,$b) == any($a,$b)
True.

any(any($a,$b),any($c,$d)) == any($a,$b,$c,$d)
True.

all($a, $a) == $a
True.

all($a,$a,$b) == all($a,$b)
False. The autothreading makes that:
  all( $a==$a, $a==$b, $b==$b, $b==$a)
and they're not (in general) all true.

all(all($a,$b),any($c,$d)) == all($a,$b,$c,$d)
False.  Because all($a,$b) != all($a,$b,$c,$d)

none($a, $a) == undef
True.

none($a,$a,$b) == none($a,$b)
True.

none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d)
True.

one($a, $a) == false
True.

one($a,$a,$b) == ($a == $b ?? undef ::  $b)
True.
Damian


Re: Junction Values

2005-02-15 Thread Damian Conway
Jonathan Scott Duff wrote:
none($a, $a) == undef
True.
Isn't this one false in the case when $a is undef?
Yes. Apologies for not being more precise.
Damian


Re: Junction Values

2005-02-15 Thread Patrick R. Michaud
On Wed, Feb 16, 2005 at 12:17:35PM +1100, Damian Conway wrote:
 Rod Adams wrote:
 On a slightly different topic, do the following equivalences work:
 [...]
 none($a, $a) == undef
 True.

Scott already caught (and Damian acknowledged) this one, it's false 
if $a == undef.

 none($a,$a,$b) == none($a,$b)
 True.

Okay, I follow this one -- here's the derivation.

  - none($a == none($a, $b),
  $b == none($a, $b))

  - none(none($a==$a, $a==$b),
  none($b==$a, $b==$b))

  - none(none(1, 0), none(0, 1))

  - none(0, 0)

  - true


 none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d)
 True.

H...

   - none(none($a,$b) == none($a,$b,$c,$d),
   none($c,$d) == none($a,$b,$c,$d))

   - none(none($a == none($a,$b,$c,$d),
$b == none($a,$b,$c,$d)),
   none($c == none($a,$b,$c,$d),
$d == none($a,$b,$c,$d)))

   - none(none(none($a==$a, $a==$b, $a==$c, $a==$d),
none($b==$a, $b==$b, $b==$c, $b==$d)),
   none(none($c==$a, $c==$b, $c==$c, $c==$d),
none($d==$a, $d==$b, $d==$c, $d==$d)))

   - none(none(none(1, 0, 0, 0),
none(0, 1, 0, 0)),
   none(none(0, 0, 1, 0),
none(0, 0, 0, 1)))

   - none(none(0, 0), none(0, 0))

   - none(1,1)

   - false

Ummm, what am I missing?  To state it another way... we can
show that none($a,$b) == none($a, $b, $c, $d) is true, so

  none( none($a,$b), none($c,$d) ) == none($a, $b, $c, $d)

is equivalent to

  none( none($a,$b) == none($a, $b, $c, $d),
none($c,$d) == none($a, $b, $c, $d))

which is none(1, 1), or false.  Did I autothread wrongly here?

And for completeness...

 one($a,$a,$b) == ($a == $b ?? undef ::  $b)
 True.

...except when $a == $b == undef.

Pm


Re: Junction Values

2005-02-15 Thread Rod Adams
Damian Conway wrote:
.values tells you what raw values are inside the junction. The other 
kind of introspection that's desirable is: what raw values can 
*match* this junction. There would probably be a .states method for 
that.

To see the difference between the two, consider:
my $ideal_partner = all( any(tall dark rich),
any(rich old frail),
any(Australian rich),
);
$ideal_partner.values would return the three distinct values in the 
junction:

( any(tall dark rich),
any(rich old frail),
any(Australian rich),
);
But $ideal_partner.states would return only those non-junctive values 
that (smart-)match the junction. Namely, rich.
One would need a method of determining whether the C.values are in an 
any/all/none/one relationship. Trivial, but necessary. That and 
C.values are likely enough introspection. Leave the C.state for CPAN 
to solve.


On a slightly different topic, do the following equivalences work:

(I will assume in all my answers that $a, $b, $c, $d have different 
values, except where it doesn't matter either way).

all($a,$a,$b) == all($a,$b)

False. The autothreading makes that:
all( $a==$a, $a==$b, $b==$b, $b==$a)
and they're not (in general) all true.
I knew I was typing this all wrong. Whipping out math symbols, replace 
the == with , or identical to.
In other words, I was not asking how C if all($a,$a,$b) == all($a,$b) 
{...}  evaluated, but instead if

if all($a,$a,$b) {...}
if all($a,$b) {...}
would both evaluate the same.
And I was making no assumptions about the values of $a .. $d.

all(all($a,$b),any($c,$d)) == all($a,$b,$c,$d)
False. Because all($a,$b) != all($a,$b,$c,$d)
Should have been
all(all($a,$b), all($c,$d))  all($a,$b,$c,$d)
Sorry for any confusion. It's just a real pain to type chars that are 
not bound on your keyboard.

As for the undef's, I didn't know what else to call the empty junctive.
-- Rod Adams



Re: Junction Values

2005-02-15 Thread Rod Adams
Patrick R. Michaud wrote:
none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d)
 

True.
   

H...
  - none(none($a,$b) == none($a,$b,$c,$d),
  none($c,$d) == none($a,$b,$c,$d))
  - none(none($a == none($a,$b,$c,$d),
   $b == none($a,$b,$c,$d)),
  none($c == none($a,$b,$c,$d),
   $d == none($a,$b,$c,$d)))
  - none(none(none($a==$a, $a==$b, $a==$c, $a==$d),
   none($b==$a, $b==$b, $b==$c, $b==$d)),
  none(none($c==$a, $c==$b, $c==$c, $c==$d),
   none($d==$a, $d==$b, $d==$c, $d==$d)))
  - none(none(none(1, 0, 0, 0),
   none(0, 1, 0, 0)),
  none(none(0, 0, 1, 0),
   none(0, 0, 0, 1)))
  - none(none(0, 0), none(0, 0))
  - none(1,1)
  - false
Ummm, what am I missing?  To state it another way... we can
show that none($a,$b) == none($a, $b, $c, $d) is true, so
 none( none($a,$b), none($c,$d) ) == none($a, $b, $c, $d)
is equivalent to
 none( none($a,$b) == none($a, $b, $c, $d),
   none($c,$d) == none($a, $b, $c, $d))
which is none(1, 1), or false.  Did I autothread wrongly here?
 

No, upon closer looking, you're right that it should both evaluate 
false, and that they are not equivalent in what I meant to be asking.

none(none($a,$b),none($c,$d)) ? all(any($a,$b),any($c,$d))
Should work, though. Not that it helps simplify matters at all.
In essence, what I'm doing is attempting to create a set of rules 
whereby one can simplify a junction, by removing the nestedness of it, 
or removing terms outright. In the process, I'm making sure that I 
understand what they mean.

-- Rod Adams


Re: Junction Values

2005-02-15 Thread Damian Conway
Patrick R. Michaud wrote:
none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d)
True.

H...
   - none(none($a,$b) == none($a,$b,$c,$d),
   none($c,$d) == none($a,$b,$c,$d))
RHS distributes first. So the expansion is this instead...
 - none(none(none($a,$b),none($c,$d)) == $a,
 none(none($a,$b),none($c,$d)) == $b,
 none(none($a,$b),none($c,$d)) == $c,
 none(none($a,$b),none($c,$d)) == $d,
)
 - none(none(none($a,$b)=$a, none($c,$d)=$a),
 none(none($a,$b)=$b, none($c,$d)=$b),
 none(none($a,$b)=$c, none($c,$d)=$c),
 none(none($a,$b)=$d, none($c,$d)=$d),
)
 - none(none(0, 1),
 none(0, 1),
 none(1, 0),
 none(1, 0),
)
 - none(0,
 0,
 0,
 0,
)
 - true
Ummm, what am I missing?  To state it another way... we can
show that none($a,$b) == none($a, $b, $c, $d) is true, 
RHS distributes first again:
none($a,$b) == none($a, $b, $c, $d)
-  none(
none($a,$b)==$a,
none($a,$b)==$b,
none($a,$b)==$c,
none($a,$b)==$d,
)
-  none(
0,
0,
1,
1,
)
-  false
Damian


Re: Junction Values

2005-02-15 Thread Patrick R. Michaud
On Wed, Feb 16, 2005 at 02:53:15PM +1100, Damian Conway wrote:
 Patrick R. Michaud wrote:
 
 none(none($a,$b),none($c,$d)) == none($a,$b,$c,$d)
 
 True.
 
 
 H...
 
- none(none($a,$b) == none($a,$b,$c,$d),
none($c,$d) == none($a,$b,$c,$d))
 
 RHS distributes first. So the expansion is this instead...

Ummm, okay, but that's not what I interpreted from S09, where
it says that the left-most conjunction or injunction is
autothreaded first.  In this I've also assumed that 

$a == $b 

is equivalent to

infix:==($a, $b) 

so I'm missing the piece that says to distribute the RHS first.

Pm


Re: Junction Values

2005-02-15 Thread Damian Conway
Patrick R. Michaud wrote:
RHS distributes first. So the expansion is this instead...
Ummm, okay, but that's not what I interpreted from S09, where
it says that the left-most conjunction or injunction is
autothreaded first.  In this I've also assumed that 

$a == $b 

is equivalent to
infix:==($a, $b) 

so I'm missing the piece that says to distribute the RHS first.
Probably because that piece is still only in my head.
Or because I got that bit of S09 wrong.
Or because Larry or Luke overrode me on it and I haven't updated my 
Perl6::Junctions module accordingly.

;-)
So forget what I said, and go with what Patrick said. Since it's easy to argue 
the outcome of these corner cases either way (depending on how you 
backtranslate them to English), it will be best to make the rules consistent 
(i.e. left-most first for both functions and operators).

Apologies all...and thanks Patrick.
Damian