Luke Palmer wrote:
Rod Adams writes:I *knew* I had seen a syntax for that before... I just didn't see it when I scanned S05 for it.
Or you could avoid the global modifier and write your tests in <( )>
blocks instead... after all, that's what it's there for.
I still want the :z modifier for matching zero length strings. That makes sense to be global.
I agree that * works that way... when you're matching against a string... which I'm not. I intend for the basic call to be something like C< "" ~~ /<test(1)>/ >, or more likely just C< /<test(1)>/ >. I won't care what the current topic is. I'll match the empty string, and everything that includes it, or nothing at all. My entire rule set will be a series of really complex zero-length assertions.The really big problem, however, is the lack of generators.
I'll establish a working definition of "generator" as "something which
offers a possible value, giving the new value each time the expression
is backtracked over, and fails when there are no more values to give".
One generator is the * combinator. It gives the longest string, then
the next shorter, then the next shorter...
I don't think this does what I want. In this, &generate returns a rule or string of some kind, matches the string being tested, captures what matches, and then binds the capture to $<x>.Clearly, desirable generators include lazy lists, arrays, and closures. All of which P6RE supports as ways of attempting different rules/strings to match against, but not as different values to assign a given $<var> to feed into later rules. Capturing assumes a string to match and capture against. Capturing the null string that I "match" is not terribly useful.
The only suggestion I can give for how to do this is by introducing the hyper operator. I'm very open to other ideas, because this one does not sit well with me, but it's all I've got at the moment. So, to give an array as a generator, one could write:
/:a {$<x> Â=Â @values} <test($<x>)>/
You could do all of this with a library of rules.
/ $<x>:=<generate(@values)> <test($<x>)> /
I have no underlying string, so the match fails right there. I want to bind/assign to the variable _without_ matching, but _with_ backtracking and iteration over several values.
I also now notice that I would need a C< let > in my example above.
How the <generate> rule is actually written is getting into some ruleThere were some thoughts in the back of my head about how I actually wanted a closure to be handled as a generator. I see the need to initialize it many separate times, once on each forward attempt, can be repeated if something after it fails, and something before it has an alternative. But I wanted the basic concept out there before I tried diving into that kind of detail.
engine internal stuff, but we're making sure that the rule engine has
enough hooks to do that.
Maybe we could unify the pattern proposal and your generation ideas for logic programming.There might be unification with logical programming to be had, but I'm not sure it's with the generation part of things.
@array[$^i] # returns a lazy pattern of everything in @array, bound
# together with the corresponding $i
How is this any different from just @array ?
(@array[$^i]).GENERATE # generates every element of @array
Now, let's just combine that with another array pattern:
@a[$^i] + @b[$^i] # returns lazy pattern of everything in @a # added to its corresponding element in @b (@a[$^i] + @b[$^i]).GENERATE # vector sum
Now if we just spell .GENERATE with ÂÂ:
 @a[$^i] + @b[$^i] Â
We have my tensor-hyper proposal back.
This example is easily done as:
@a Â+Â @b
But it's also not terribly far removed from my hyperthreader operator in the Junctions thread (oh, when, oh when is Damian coming back?). There are differences, but see if that does what you need.
Not to mention that   are already taken in that context as q:w// operators.
Problems with this:Now ÂÂ could have a similar meaning within rules, which would give you your generator.
# print everything in @array that matches test()
/ $<x> := [EMAIL PROTECTED] <( test($<x>) )> { say $<x>; fail } /
1) Â Â in RE's are already taken for non-capturing meta's. And binding doesn't work if you don't capture.
2) you're still trying to match the value against the string.
Not really a problem, but I had C< <test($<x>)> >, not C< <(test($<x>))> > on purpose. I was feeding into a rule, not a function.
I don't see what this gives me over a regular lazy list generation with gather/take.The biggest question is how this interacts with sub calls. We can't really expect sub calls to be pattern-aware: that puts constraints on what we're allowed to do in a sub (no side-effect constraints; gee, those kinds of constraints really go a long way). But &test could certainly implement a GENERATE method:
sub is_prime( $x will GENERATE { primes() } ) { ?grep { $_ == $x } primes() }
The will generate says that the sub can accept a generic pattern and
will fill it in on the spot.
-- Rod Adams