Re: Junction Values
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
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
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
Damian Conway wrote: 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). Funny. I thought it was simple and elegant. My explanation might have been complex, as well as the motivations, but I truly considered it a straight forward and simple solution. As for too much of an imposition on the programmer, that's essentially what I was asking for all along. To be imposed upon to decide when threading occurs. I won't apologize for that, or change my position on it. But I was making the imposition optional. And, actually, now that I better understand your latest proposal, I realize how amazing close we are. 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) ) Change that C any($x) to C »$x« , and the important differences between our positions shrink dramatically. Reason I don't like any() here is that $x already has a junctive condition on it. While any() with a single value does not change in the least how this will be evaluated in the long run, it could be confusing to wrap an all() junction inside an any() call. Doubling up the type works for all the types except none(). Use »« for an explicit call designator, and you revert to the type already in the junction. Give me my »« as a secondary way of always explicitly threading, and I'll go away happy. You can keep the rest of your proposal the same. I'll just start using them wherever I think threading should happen, even if I never needed to use them in most of the places I will. It'll be a good visual to myself of what's going on. Don't give them to me, and I'll frown for a while, but then likely get over it. 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. I understand bowing out of this perfectly. There other tasks whose time I've raided for this discussion, and the backlog is starting to look pretty nasty. But it has been a good and healthy discussion. Many things have come of it. Thanks to all the participants. 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. Now THAT is an even better idea than the separate Set class I was going to champion whenever I next had time for such a thing! I support this concept fully! -- Rod Adams PS - Looks like Matt gets his wish. This juggernaut of a thread is coming to a close. I'd be happy to proof his summary of it if he gives me an advanced copy.
Re: Set sigils (was: Re: Junction Values)
On Sat, Feb 19, 2005 at 01:43:57PM -0800, Ashley Winters wrote: 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? :) Just noting that secondary sigils aren't limited to scalars: @*biglist = 1... ; # global @::*::biglist has %.dictionary; # public attribute has @:children;# private attribute say @?BLOCK; # which blocks am I in? { sort @^list; } # placeholder array %=POD{'DATA'} # filehandle for =begin DATA stream Pm
Re: Junction Values
On Sun, 20 Feb 2005 03:17:19 -0600, [EMAIL PROTECTED] (Rod Adams) wrote: --020209010404060902000407 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Nigel Sandever wrote: On Sat, 19 Feb 2005 18:42:36 +1100, [EMAIL PROTECTED] (Damian Conway) wrote: The Awesome Power of Junctions: 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 [SNIP] 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 {...} } SNIP] 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. By the power of a single good example, you can now count me amongst the convinced. 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. Patricks's arguement that there is no real difference between a scalar that contains a Junction and a scalar that contains a coderef or any type of ref when it comes to requiring the programmer to know (or test for) what the scalar holds, was enough to convince me that no additional pragmas are required for junctions. Though I wouldn't object to Damian's cno autothreading. My only problem was that I couldn't see the larger benefit of them. Your example above is sufficient to convince that being able to encapsulate not just a set of data, but /required result/ of *any* operations performed using that set data did the trick for me. I now view the junction my $x = any( @values ); as roughly equal to: my $junction = bless [ @values ], 'any'; and similarly for the other three. Simplistic, but enough for my mind to make the transition. Using the hyper operators, you would have to re-state the desired result for each operation, but with a junction you've encapsulated it in. HTH. -- Rod Adams Thanks for taking the time to produce your good example and so carrying me along. njs. --020209010404060902000407-- Examine what is said, not who speaks.
Re: Junction Values
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 /; 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? Eirik -- All bridge hands are equally likely, but some are more equally likely than others. -- Alan Truscott
Re: Junction Values
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
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
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
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
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
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
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. -???