, , and backtracking.

2007-09-06 Thread Jonathan Scott Duff
How do C and C differ with respect to backtracking?  For instance,

foobar ~~ / [a..z]+  [ ... ] /;

Both sides of the C happen in parallel, so I would guess that they
both match foo then stop. Please correct me if that's wrong.

Were we using the procedural conjunction:

foobar ~~ / [a..z]+  [ ... ] /;

I would guess that the LHS matches as much as it can (foobar), then
the RHS matches foo. Since foobar ne foo, the regex engine
backtracks on the LHS matching fooba and then the RHS matches foo
again. Again, since fooba ne foo, the regex engine backtracks as
before and this behavior continues until both sides match foo (or, in
the general case, it can determine that the conjunctions can't match the
same portion of the string)

Or it's much simpler than that and both of the regexes above just fail
because of the greediness of C+ and there is no intra-conjunction
backtracking.

So ... anyone care to enlighten me on how this is supposed to work?

Thanks,

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: , , and backtracking.

2007-09-06 Thread Jonathan Lang
Jonathan Scott Duff wrote:
 How do C and C differ with respect to backtracking?  For instance,

 foobar ~~ / [a..z]+  [ ... ] /;

 Both sides of the C happen in parallel, so I would guess that they
 both match foo then stop. Please correct me if that's wrong.

As written, this match would fail, since '[a..z]+' would match
foobar while '[ ... ]' would match foo.  '' requires that both
sides match the same start and end points.  I suppose that it might be
worth considering requiring only the start points to match, and having
the conjoined match use the earliest end point; so that the above
match would then match foo instead of failing.  But it's entirely
possible that there's something faulty with this approach.

The difference between '' and '' is that '' evaluates the two
sides in an arbitrary order, possibly even in parallel; '' always
evaluates the left side first, and only bothers with the right side if
the left side matched.

-- 
Jonathan Dataweaver Lang


Re: , , and backtracking.

2007-09-06 Thread Larry Wall
On Thu, Sep 06, 2007 at 01:25:12PM -0500, Patrick R. Michaud wrote:
:  Were we using the procedural conjunction:
:  
:  foobar ~~ / [a..z]+  [ ... ] /;
:  
:  I would guess that the LHS matches as much as it can (foobar), then
:  the RHS matches foo [...and then backtracks the LHS until a 
:  conjunctional match is found...]
: 
:  Or it's much simpler than that and both of the regexes above just fail
:  because of the greediness of C+ and there is no intra-conjunction
:  backtracking.
: 
: I think we definitely allow intra-conjunction backtracking.
: PGE implements it that way.

That's what I think.

: On a somewhat similar question, what happens with a pattern
: such as
: 
: foobar ~~ / foo.+? | fooba /
: 
: The LHS initially matches foob, but with backtracking could
: eventually match foobar.  Do the longest-token semantics
: in this case cause the RHS to be dispatched first, even
: though the token declaration of the LHS _could_ match a 
: longer token prefix?  

Yow.  ICATBW.  Non-greedy matching is somewhat antithetical to
longest-token matching.  But basically it boils down to this:
Does the longest-token matcher ignore the ?  and do

foo.+ | fooba

or is there an implicit ordering above and beyond the DFA engine of

foob | fooba ||
fooba | fooba ||
foobar | fooba ||

I think longest-token semantics have to trump minimal matching here,
and my argument is this.  Most uses of *? have additional information
on what terminates it, either implicitly in what it is matching, or
explicitly in the next bit of regex.  That is, you'd typically see
either

foo\w+? | fooba

or

foo.+? wb | fooba

In either case, the clear intent is to match foobar over fooba.
Therefore I think the DFA matcher just strips ? and does its ordinary
character by character match, relying on that extra info to match
the real extent of the quantifier.

Larry


Re: , , and backtracking.

2007-09-06 Thread Geoffrey Broadwell
On Thu, 2007-09-06 at 12:37 -0700, Larry Wall wrote:
 Yow.  ICATBW.

The what now?


-'f




Re: , , and backtracking.

2007-09-06 Thread Patrick R. Michaud
On Thu, Sep 06, 2007 at 12:37:37PM -0700, Larry Wall wrote:
 On Thu, Sep 06, 2007 at 01:25:12PM -0500, Patrick R. Michaud wrote:
 : On a somewhat similar question, what happens with a pattern
 : such as
 : 
 : foobar ~~ / foo.+? | fooba /
 : 
 : The LHS initially matches foob, but with backtracking could
 : eventually match foobar.  Do the longest-token semantics
 : in this case cause the RHS to be dispatched first, even
 : though the token declaration of the LHS _could_ match a 
 : longer token prefix?  
 
 Yow.  ICATBW.  Non-greedy matching is somewhat antithetical to
 longest-token matching.  

I agree.  One thought I had was that perhaps non-greedy matching
could also terminate the token prefix.

 [...]
 I think longest-token semantics have to trump minimal matching here,
 and my argument is this.  Most uses of *? have additional information
 on what terminates it, either implicitly in what it is matching, or
 explicitly in the next bit of regex.  That is, you'd typically see
 either
 foo\w+? | fooba
 or
 foo.+? wb | fooba
 
 In either case, the clear intent is to match foobar over fooba.
 Therefore I think the DFA matcher just strips ? and does its ordinary
 character by character match, relying on that extra info to match
 the real extent of the quantifier.

Does this still hold true for a non-greedy quantifier in the
middle of an expression... ?  I.e.,

foobazbar deborah ~~ /foo .+? b.r | fooba | foobazb /

matches foobazbar debor ?

(I completely grant that the examples I'm coming up with here
may be completely nonsensical in real application, but I'm
just exploring the space a bit.)

Pm


Re: , , and backtracking.

2007-09-06 Thread Larry Wall
On Thu, Sep 06, 2007 at 03:49:42PM -0700, Larry Wall wrote:
: On Thu, Sep 06, 2007 at 04:02:19PM -0500, Patrick R. Michaud wrote:
: : I agree.  One thought I had was that perhaps non-greedy matching
: : could also terminate the token prefix.
: 
: Well, that's more or less arguing it the other way.  It kind of assumes
: your fooba-ish arguments are smart enough to test for non-r after.

The more I think about it, the more I like this approach.  Most token
should be matched in ratchet mode, and I think minimal matching
is perhaps a form of cheating: Look for the nearest end of this
without me actually bothering to parse the middle.  And certainly
any reasonable grammer is going to be checking that a keyword is
properly terminated by a word boundary anyway.

Larry


Re: , , and backtracking.

2007-09-06 Thread Larry Wall
On Thu, Sep 06, 2007 at 04:02:19PM -0500, Patrick R. Michaud wrote:
: I agree.  One thought I had was that perhaps non-greedy matching
: could also terminate the token prefix.

Well, that's more or less arguing it the other way.  It kind of assumes
your fooba-ish arguments are smart enough to test for non-r after.

:  [...]
:  I think longest-token semantics have to trump minimal matching here,
:  and my argument is this.  Most uses of *? have additional information
:  on what terminates it, either implicitly in what it is matching, or
:  explicitly in the next bit of regex.  That is, you'd typically see
:  either
:  foo\w+? | fooba
:  or
:  foo.+? wb | fooba
:  
:  In either case, the clear intent is to match foobar over fooba.
:  Therefore I think the DFA matcher just strips ? and does its ordinary
:  character by character match, relying on that extra info to match
:  the real extent of the quantifier.
: 
: Does this still hold true for a non-greedy quantifier in the
: middle of an expression... ?  I.e.,
: 
: foobazbar deborah ~~ /foo .+? b.r | fooba | foobazb /
: 
: matches foobazbar debor ?

I suppose one approach would be to limit the DFA to the longest known
constant string, and then rerun any variable branches individually
to see if they will actually match something that long.  Alternately,
if the DFA engine is smart enough to kick out all the matches of the
foo .+? b.r branch then it could conceivably be taught to return
the shortest one rather than the longest one.  Course, the question
after than is, what if you mix minimal with maximal quantifiers?

Another consideration is the efficiency of matching that pattern
against foobazbar ~ 'b' x 1.  That would definitely run
faster if you cut off the DFA after the longest known token, or as
soon as the DFA reduces to one possibility, presuming you can know
such a thing.

Any way we work it, there will be a way to use it wrong.

Larry


Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Austin Hastings

Consider this code:

  if (specific_condition())
  {
if (detail())
{
  act();
}
  }
  elsif (general_condition())
  {
act();
  }

Logically, this turns into:

  if ((my $sc = specific_condition())  detail())
  || (!$sc  general_condition())
  {
act();
  }

Both look horrible, of course. I'd like to rewrite them as

  if (specific_condition() ::  detail()) || general_condition()
  {
act();
  }

so that if specific_condition() succeeded, it would cause the entire
expression to fail if detail() failed.

The use of :: comes, of course, from rexen.

Is this feasible?

=Austin



Re: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Damian Conway
Austin Hastings wrote:

Both look horrible, of course. I'd like to rewrite them as

  if (specific_condition() ::  detail()) || general_condition()
  {
act();
  }
so that if specific_condition() succeeded, it would cause the entire
expression to fail if detail() failed.
The use of :: comes, of course, from rexen.

Is this feasible?
Not in Perl itself. But you could always put 'em in regexen:

if (/(specific_condition()) :: (detail()) | (general_condition())/)
{
   act();
}
However that's just showing off. All you really need is:

if ( specific_condition() ? detail() : general_condition() )
{
   act();
}
;-)

Damian


Re: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Damian Conway
 All you really need is:

 if ( specific_condition() ? detail() : general_condition() )
Oops! That's the Perl 5 version. In Perl 6, of course, it's:

  if ( specific_condition() ?? detail() :: general_condition() )

Which means you *do* get to use the :: after all!
(Just not where you might have expected ;-)
Damian





RE: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Austin Hastings
 -Original Message-
 From: Damian Conway [mailto:[EMAIL PROTECTED]

  Since paren's aren't required with keywords, can they still serve as rex
  delimiters?

 No. For other syntactic reasons parens aren't allowed as rule
 delimiters at all. And only /.../ delimit raw matches. Every other
delimiter
 requires an explicit 'm'.

I keep forgetting poor Cm.

  Sadly, it doesn't generalize well:
 
if (specific() ::  detail1() ::  detail2()) || general() {...}
 
  becoming
 
if (specific() ? detail1() ? detail2() : FALSE : general() ) {...}
 
  to say nothing of readability.

 Your proposed version is hardly a model of readability either. ;-)

Hmm. You'll want to take that up with the folks responsible for the rex
syntax. :-O

 Besides, the correct solution there is just:

  if (specific() ?? detail1()  detail2() :: general()) {...}

For some value of correct I suppose. Using ??:: within an if/else context
makes my skin crawl, stylistically. :-(

=Austin



Re: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Simon Cozens
[EMAIL PROTECTED] (Austin Hastings) writes:
   if (specific() ?? detail1()  detail2() :: general()) {...}
 
 For some value of correct I suppose. Using ??:: within an if/else context
 makes my skin crawl, stylistically. :-(

Ah, then use if!

  if (if(specific()) { detail() } else { general() }) {
  ...
  } else {
  ...
  }
-- 
Complete the following sentence: People *ought* to weigh bricks, cats
and cinnamon in the same units because... - Ian Johnston


Re: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Larry Wall
On Fri, Apr 02, 2004 at 03:05:30PM +0100, Simon Cozens wrote:
: [EMAIL PROTECTED] (Austin Hastings) writes:
:if (specific() ?? detail1()  detail2() :: general()) {...}
:  
:  For some value of correct I suppose. Using ??:: within an if/else context
:  makes my skin crawl, stylistically. :-(
: 
: Ah, then use if!
: 
:   if (if(specific()) { detail() } else { general() }) {
:   ...
:   } else {
:   ...
:   }

What's that?  PL/Ruby?

In Perl 6 that would more clearly be written:

if do { if specific() { detail() } else { general() } } {
  ...
} else {
  ...
}

or, of course,

if specific() ?? detail() :: general() {
  ...
} else {
  ...
}

Sorry, Perl 6 is just not going to confuse statements and expressions.
A statement is the artificial equivalent of a sentence, and it's no
coincidence that every natural language has something like a sentence
for the purpose of clocking and resynchronizing the discourse.
I think pinning the large-scale control structures to the discourse
structure is a really good idea, both for the computer trying to
decide what error message to spew, and for the person who is going
to have to try to decipher that error message.   To break that in
the name of orthogonality ignores the linguistic evidence built up
over many thousands of years.  Even an almost purely RPN language
like Japanese likes to use honorifics and/or a bunch of particles to
mark the ends of its sentences, yo?

Larry


Re: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Aaron Sherman
On Fri, 2004-04-02 at 10:01, Larry Wall wrote:
 Even an almost purely RPN language
 like Japanese likes to use honorifics and/or a bunch of particles to
 mark the ends of its sentences, yo?

Hai, and it's not just there to help in error reporting. Imagine the
case:

if if if if if ... {...} else {...} {...} else {...} {...} else {...}
{...} else {...} {
...
} else {
...
}

so very, very far from readability. Even if you try to indent in some
logical way, it's just painful.

What's more, your,

if specific() ?? detail() :: general() { ... }

is also:

if ((my $s = ?specific())  detail()) || (!$s  general()) { ... }

If you prefer to avoid trinary logic constructs directly. I'm not sure
if using the ? there does what I want (which is to strip away any
potential side-effects on $s for when I evaluate it again). It would be
nice to have an un-lazying operator of some sort which could assert a
lack of side-effects as a side-effect.

-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
It's the sound of a satellite saying, 'get me down!' -Shriekback




RE: Q: Can colons control backtracking in logical expressions?

2004-04-02 Thread Austin Hastings
 -Original Message-
 From: Larry Wall [mailto:[EMAIL PROTECTED]

 On Fri, Apr 02, 2004 at 03:05:30PM +0100, Simon Cozens wrote:
 : [EMAIL PROTECTED] (Austin Hastings) writes:
 :if (specific() ?? detail1()  detail2() :: general()) {...}
 : 
 :  For some value of correct I suppose. Using ??:: within an
 :  if/else context makes my skin crawl, stylistically. :-(
 :
 : Ah, then use if!
 :
 :   if (if(specific()) { detail() } else { general() }) {
 :   ...
 :   } else {
 :   ...
 :   }

 What's that?  PL/Ruby?

 In Perl 6 that would more clearly be written:

 if do { if specific() { detail() } else { general() } } {
   ...
 } else {
   ...
 }

 or, of course,

 if specific() ?? detail() :: general() {
   ...
 } else {
   ...
 }

 Sorry, Perl 6 is just not going to confuse statements and expressions.
 A statement is the artificial equivalent of a sentence, and it's no
 coincidence that every natural language has something like a sentence
 for the purpose of clocking and resynchronizing the discourse.
 I think pinning the large-scale control structures to the discourse
 structure is a really good idea, both for the computer trying to
 decide what error message to spew, and for the person who is going
 to have to try to decipher that error message.   To break that in
 the name of orthogonality ignores the linguistic evidence built up
 over many thousands of years.


Or, as per the original:

  if specific()
  {
if detail()
{
  act();
}
  }
  elsif general()
  {
act();
  }

 Even an almost purely RPN language like Japanese likes to use
 honorifics and/or a bunch of particles to mark the ends of its
 sentences, yo?

I'm witcha, homie. Word.

However, what I was trying for was not so much destroy the end product of
thousands of years of linguistic evidence, as more of the kind of
abstractions that have happened before. In this case,

A :: in a rex is just a form of 'cut', and 'cut' is a valid expression
modifier, so we'll put the same operators (or similar ones) to use outside
the context of rexen.

=Austin



Backtracking syntax

2002-09-22 Thread Me

Backtracking syntax includes:

:, ::, :::, commit, cut

I like the way the ':' looks in patterns. But I noticed I have
several niggles about a number of other aspects of the
above syntax. All the niggles are minor, individually, but
they added up to enough that I thought I'd see what the
bikeshed might look like in another color.

First, the niggles:

1. It's nice how the ':', '::', and ':::' progression indicates
progressively wider scope. But I would be surprised if
newbies don't say to themselves, now just how wide a
scope am I backtracking when there's three colons?.

2. Typo-trap: I can imagine it being fairly easy for some
people to miss, during debugging, both the visual and
behavioral distinction between '::' and ':::'.

3. It seemed odd how the commit and cut assertions
switch to the general ... syntax. I felt like it would be better
if they avoided the general syntax, and preferably had some
family resemblance with the first three backtracking controls.

So, how about something like:

:   # lock in current atom, ie as now
:]  # lock in surrounding group, currently ::
:  # lock in surrounding rule, currently :::
:/  # lock in top level rule, currently commit
:// # cut

Thus, redoing a couple examples from synopsis 5:

m:w/ [ if   :] expr block
 | for  :] list block
 | loop :] loop_controls? block
 ]

rule subname {
([alpha|_] \w*) :/ { fail if %reserved{$1} }
}
m:w/ sub subname? block /

--
ralph









Re: Backtracking syntax

2002-09-22 Thread Simon Cozens

[EMAIL PROTECTED] (Me) writes:
 1. It's nice how the ':', '::', and ':::' progression indicates
 progressively wider scope. But I would be surprised if
 newbies don't say to themselves, now just how wide a
 scope am I backtracking when there's three colons?.

Why would newbies be writing three-colon regexes?

-- 
dhd even though I know what a 'one time pad' is, it still sounds like
a feminine hygiene product.



Re: Backtracking syntax

2002-09-22 Thread Me

 [EMAIL PROTECTED] (Me) writes:
  1. It's nice how the ':', '::', and ':::' progression indicates
  progressively wider scope. But I would be surprised if
  newbies don't say to themselves, now just how wide a
  scope am I backtracking when there's three colons?.
 
 Why would newbies be writing three-colon regexes?

By newbie I meant it in a relative sense, ie. someone who
is learning those particular features. The newbie could be
an expert in Prolog and Perl 5.

And I'm more concerned about when they are reading some
existing patterns than when they are writing one.

--
ralph



Re: Backtracking syntax

2002-09-22 Thread Markus Laire

 Backtracking syntax includes:
 
 :, ::, :::, commit, cut
 
 1. It's nice how the ':', '::', and ':::' progression indicates
 progressively wider scope. But I would be surprised if
 newbies don't say to themselves, now just how wide a
 scope am I backtracking when there's three colons?.

What problem there is? Scopes are atom/group/rule - I don't see any 
possible misunderstanding there as these scopes are so natural.

 2. Typo-trap: I can imagine it being fairly easy for some
 people to miss, during debugging, both the visual and
 behavioral distinction between '::' and ':::'.

If that really is big problem, it can be solved easily by using 
proper editor which supports high-lighting.
::: could be shown with different color or bold while :: uses some 
other syntax.

 3. It seemed odd how the commit and cut assertions
 switch to the general ... syntax. I felt like it would be better if
 they avoided the general syntax, and preferably had some family
 resemblance with the first three backtracking controls.
 
 So, how about something like:
 
 :   # lock in current atom, ie as now
 :]  # lock in surrounding group, currently ::
 :  # lock in surrounding rule, currently :::
 :/  # lock in top level rule, currently commit
 :// # cut

I find :,::,::: to be a lot easier to remember than :,:],: - and 
also easier to type.

While commit and cut don't follow same syntax, I don't really see 
any better solutions. Better solution should IMHO keep :,::,::: and 
offer better alternative only to commit.
cut doesn't really belong to this serie as it's different 
backtracking-operation and so it can and should have different 
syntax.

I wonder if  might be usefull instead of commit with proper 
syntax-highlighting.

-- 
Markus Laire 'malaire' [EMAIL PROTECTED]





Re: Backtracking syntax

2002-09-22 Thread Simon Cozens

[EMAIL PROTECTED] (Markus Laire) writes:
 While commit and cut don't follow same syntax, I don't really see 
 any better solutions.

commit is sufficiently hard that it musn't be confused with the
colon series.

 I wonder if  might be usefull instead of commit with proper 
 syntax-highlighting.

Yeah. :: should show up in bold, ::: in bold with a red background, and
 should blink.

-- 
I would imagine most of the readers of this group would support abortion
as long as fifty or sixty years after conception for certain individuals
- Michael Stevens



Re: Backtracking syntax

2002-09-22 Thread Markus Laire

On 22 Sep 2002 at 21:06, Simon Cozens wrote:

 [EMAIL PROTECTED] (Markus Laire) writes:
  While commit and cut don't follow same syntax, I don't really see 
  any better solutions.
 
 commit is sufficiently hard that it musn't be confused with the
 colon series.

Yes, I didn't think that enough.
:,::,::: only affects current rule while commit goes further to 
possibly affect other rules also, so it must have different syntax.

-- 
Markus Laire 'malaire' [EMAIL PROTECTED]





Re: Backtracking syntax

2002-09-22 Thread Steve Fink

On Sun, Sep 22, 2002 at 01:39:29PM -0500, Me wrote:
 So, how about something like:
 
 :   # lock in current atom, ie as now
 :]  # lock in surrounding group, currently ::
 :  # lock in surrounding rule, currently :::
 :/  # lock in top level rule, currently commit
 :// # cut

I kinda like it, since :: and ::: look very similar to me, too. (I
don't buy the syntax highlighting argument, partly because I often
encounter code in bw printouts, perlmonks, or wherever.) Though I'd
probably prefer cut stayed cut. And those mismatched brackets
bother me, too. What about

:- :
::   - :[]  or [:]
:::  - :  or :
commit - ://  or /:/
cut- :cut or :cut or :cut or just stay cut

Then again, I've never been convinced of the similarity between : and
::. To me, a single colon is modifying another operation, so it's like
the ? non-greedy modifier. Is that incorrect? Everything else does
something when backtracked over; the only thing : has in common with
them is that it has something to do with backtracking.

Btw, is /:/ ambiguous? I can't remember if there's any way a /pattern/
can be followed by a colon.

Staring at the third column above, I can't help wondering if [:cut],
:cut, and /:cut/ would all be useful. But not enough to really think
about it and figure out what they would mean, exactly -- my brain and
cut are still having some marital difficulties.

 Thus, redoing a couple examples from synopsis 5:
 
 m:w/ [ if   :] expr block
  | for  :] list block
  | loop :] loop_controls? block
  ]
 
 rule subname {
 ([alpha|_] \w*) :/ { fail if %reserved{$1} }
 }
 m:w/ sub subname? block /

 m:w/ [ if   :[] expr block
  | for  :[] list block
  | loop :[] loop_controls? block
  ]
 
 rule subname {
 ([alpha|_] \w*) :// { fail if %reserved{$1} }
 }
 m:w/ sub subname? block /

or

 m:w/ [ if   [:] expr block
  | for  [:] list block
  | loop [:] loop_controls? block
  ]
 
 rule subname {
 ([alpha|_] \w*) /:/ { fail if %reserved{$1} }
 }
 m:w/ sub subname? block /



Re: backtracking into { code }

2002-08-30 Thread Damian Conway

Ken Fox wrote:

 A question: Do rules matched in a { code } block set backtrack points for
 the outer rule? 

I don't believe so. From A5:

A pattern nested within a closure is classified as its own rule,
however, so it never gets the chance to pass out of a {...} closure.

Indeed, to get a rule in a closure to even continue matching from the same
point in the string, you would need to write:


rule expr1 {
term { m:cont/operators/ or fail } term
}

Backtracking would just step back over the rule as if it were atomic
(or followed by a colon).

Damian





Re: backtracking into { code }

2002-08-30 Thread Ken Fox

Damian Conway wrote:
 rule expr1 {
 term { m:cont/operators/ or fail } term
 }
 
 Backtracking would just step back over the rule as if it were atomic
 (or followed by a colon).

Ok, thanks. (The followed by a colon is just to explain the behavior,
right? It's illegal to follow a code block with a colon, isn't it?)

After talking to Aaron yesterday, I was wondering if sub-rules are
meant to backtrack at all.

Does the following example backtrack into foo?

   rule foo { b+ }
   rule bar { a foo b }

If it doesn't, I think we're restricted to pure LL(1) grammars.
That would suck. Apoc 5 is so close to ANTLR or precc that it would
be a shame not to be LL(k).

I've been playing around with converting regex operators into
Perl 6 attribute grammars and they look good. If backtracking into
rules doesn't work though, these conversions don't work.

   a ?rule x { a | null }
   a *rule x { a x | null }
   a +rule x($i=0) { a x($i+1) | ($i0) null }
   a {n,m}rule x($i=0) { ($i$m) a x($i+1) | ($i=$n) null }

The non-greedy versions just reverse the productions, so for example

   a *?   rule x { null | a x }

- Ken




Re: backtracking into { code }

2002-08-30 Thread Aaron Sherman

[NOTE: BCCing off-list to protect private email addresses]

On Fri, 2002-08-30 at 09:07, Ken Fox wrote:

 Does the following example backtrack into foo?
 
rule foo { b+ }
rule bar { a foo b }

This was the bit that got me on-board. I did not see the need for
backtracking into rules until he pulled out that darn C+. Until then I
was convinced that you could just step over the sub-rule in backtracking
and treat it as atomic. Lack of formal education is biting me here. :(

I await the response with interest.






Re: backtracking into { code }

2002-08-30 Thread Larry Wall

On Fri, 30 Aug 2002, Ken Fox wrote:
: Ok, thanks. (The followed by a colon is just to explain the behavior,
: right? It's illegal to follow a code block with a colon, isn't it?)

I don't see why it should be illegal--it could be useful if the closure
has played continuation games of some sort to get backtracking.
In the normal case it's a no-op, since closures don't normally get
control back when backtracked over.

: After talking to Aaron yesterday, I was wondering if sub-rules are
: meant to backtrack at all.
: 
: Does the following example backtrack into foo?
: 
:rule foo { b+ }
:rule bar { a foo b }

Yes, it must.  It's only rules embedded in closures that are exempt
by default, I think.

Larry




Re: backtracking into { code }

2002-08-30 Thread Ken Fox

Larry Wall wrote:
 On Fri, 30 Aug 2002, Ken Fox wrote:
 : Ok, thanks. (The followed by a colon is just to explain the behavior,
 : right? It's illegal to follow a code block with a colon, isn't it?)
 
 I don't see why it should be illegal--it could be useful if the closure
 has played continuation games of some sort to get backtracking.

Apoc 5 has It is an error to use : on any atom that does no
backtracking. Code blocks don't backtrack (at least that's what
I understood Damian to say). Are zero width atoms treated specially?

And can you give me an example of a continuation game? That sounds
sort of like my original question.

Great news about backtracking into sub-rules. Perl 6 is going to
be a lovely system to work with. I think it's going to suffer a bit
from the same declarative-face vs procedural-heart** that Prolog
does, but it hits the little language target perfectly.

- Ken

** Prolog uses a cut (!) operator to control backtracking just like
Perl 6. A big problem (at least for me...) is learning when ! just
makes things run faster vs. when ! gives me the wrong answer. Maybe
I just haven't used Prolog enough to get my brain wrapped around it.




Re: backtracking into { code }

2002-08-30 Thread Larry Wall

On Fri, 30 Aug 2002, Ken Fox wrote:
: Apoc 5 has It is an error to use : on any atom that does no
: backtracking. Code blocks don't backtrack (at least that's what
: I understood Damian to say).

Code blocks don't backtrack *by default*.  But you can do anything
in a closure.

: Are zero width atoms treated specially?

Code blocks are zero width *by default*.  But you can do anything in
a closure.

: And can you give me an example of a continuation game? That sounds
: sort of like my original question.

Nope.  I don't understand continuations.  :-)

: Great news about backtracking into sub-rules. Perl 6 is going to
: be a lovely system to work with. I think it's going to suffer a bit
: from the same declarative-face vs procedural-heart** that Prolog
: does, but it hits the little language target perfectly.

There's a famous book called Golf is Not a Game of Perfect.

: ** Prolog uses a cut (!) operator to control backtracking just like
: Perl 6. A big problem (at least for me...) is learning when ! just
: makes things run faster vs. when ! gives me the wrong answer. Maybe
: I just haven't used Prolog enough to get my brain wrapped around it.

The purists would say that the cut operator is always the wrong
answer even when it gives the right answer.

I am not a purist.  In case you hadn't noticed...

Larry




Re: backtracking into { code }

2002-08-30 Thread Ken Fox

Larry Wall wrote:
 There's a famous book called Golf is Not a Game of Perfect.

Well now I'm *totally* confused. I looked that up on Amazon
and it has something to do with clubs and grass and stuff. That's
completely different than what I thought golfing was. ;)

Seriously, though. I have a positive and confident outlook that
Perl 6 will be a lovely system for hacking grammars.

- Ken




backtracking into { code }

2002-08-29 Thread Ken Fox

A question: Do rules matched in a { code } block set backtrack points for
the outer rule? For example, are these rules equivalent?

  rule expr1 {
term { /operators/ or fail } term
  }

  rule expr2 {
term operators term
  }

And a comment: It would be nice to have procedural control over back-
tracking so that { code } can fail, succeed (not fail), or succeed and
commit. Right now we can follow { code } with ::, :::, etc. but that does
not allow much control. I'm a little afraid of what happens in an LL(Inf)
grammar if backtracking states aren't aggressively pruned.

- Ken



Re: backtracking into { code }

2002-08-29 Thread Aaron Sherman

On Thu, 2002-08-29 at 08:05, Ken Fox wrote:
 A question: Do rules matched in a { code } block set backtrack points for
 the outer rule? For example, are these rules equivalent?
 
   rule expr1 {
 term { /operators/ or fail } term
   }
 
   rule expr2 {
 term operators term
   }
 
 And a comment: It would be nice to have procedural control over back-
 tracking so that { code } can fail, succeed (not fail), or succeed and
 commit. Right now we can follow { code } with ::, :::, etc. but that does
 not allow much control. I'm a little afraid of what happens in an LL(Inf)
 grammar if backtracking states aren't aggressively pruned.

Well, if /.../ is returning a result object (Let's say
CORE::RX::Result), then I would imagine it's an easy enough thing to let
you create your own, or return the one from a rule that you invoke.
e.g.:

rule { term { /operators/.commit(1) or fail } term }

The hypothetical commit() method being one that would take a number and
modify the result object so that it commits as if you had used that many
colons.

{} inside a rule would, I imagine be implemented like so:

sub rxbraces ($code) {
my $stat = $code();
if $stat.isa(CORE::RX::Result) {
return $stat;
} else {
my $r is CORE::RX::Result;
$r.success($stat); # Boolean status-setting method
return $r;
}
}

Or the moral equiv In other words, it should be able to return a
result of your choosing.

Sorry if I've missed some of the design. My Perl 6 pseudo-code may not
be legal.





Re: backtracking into { code }

2002-08-29 Thread Ken Fox

Aaron Sherman wrote:
 rule { term { /operators/.commit(1) or fail } term }
 
 The hypothetical commit() method being one that would take a number and

That would only be useful if the outer rule can backtrack into the
inner /operators/ rule. Can it?

I agree with you that a commit method would be useful -- especially when
used on $self. I'd probably write your example as:

  rule { term { m/operators { $self.commit(1) }/ or fail } term }

which is of course just a complicated

  rule { term { m/operators :/ or fail } term }

BTW, why isn't fail a method? Then a rule could pass itself to a sub-rule
and allow the sub-rule to fail it's parent, but not the entire match. Isn't
failing just invoking the last continuation on the backtrack stack?

- Ken



Re: backtracking into { code }

2002-08-29 Thread Aaron Sherman

On Thu, 2002-08-29 at 10:28, Ken Fox wrote:
 Aaron Sherman wrote:
  rule { term { /operators/.commit(1) or fail } term }
  
  The hypothetical commit() method being one that would take a number and
 
 That would only be useful if the outer rule can backtrack into the
 inner /operators/ rule. Can it?

Of course not. In the same way that 

rule foo { b }
rule bar { a foo+ b }
abb =~ /bar/

would not. You backtrack OVER it, and that's when your commit (of
whatever degree) would come into play.

 I agree with you that a commit method would be useful -- especially when
 used on $self. I'd probably write your example as:
 
   rule { term { m/operators { $self.commit(1) }/ or fail } term }.
 which is of course just a complicated
 
   rule { term { m/operators :/ or fail } term }

There's no way that can affect anything, as : doesn't affect calling
rules, e.g.:

rule foo { b : }
rule bar { a foo+ b }
abb =~ /bar/

will match, because the foo rule never needs to backtrack. If foo had
used C commit , then you'd fail, but that's a horse of a different
animal.

The goal was to dynamically cause backtracking over inline code to fail.





Re: RFC 104 (v1) Backtracking

2000-08-17 Thread raptor

hi,

  So how is that different from:
 
  do BLOCK1 until do BLOCK2

 It's the same.
 But the real fun starts when blocks and functions can suspend and
 resume.

{ ...
  # Return value and suspend.
  suspend $i;
  # Next iteration will resume here
  ...
} andthen { ... };

 -- Johan

]- BIG GREEN  hm
I will say wrong point of view. Why ?
You are looking at this code at "Procedure semantic side" of view.
Let'see how this look to me... "declarative guy" :")

"Suspend" works for me like "INBLOCK CUT".

I will ask what will happen in recursive block if you place the "end
conditions" before suspend :")
=
iVAN
[EMAIL PROTECTED]
=






Re: RFC 104 (v1) Backtracking :ref

2000-08-17 Thread raptor

=head1 REFERENCE
Icon language brief intro :
http://www.cs.arizona.edu/icon/intro.htm




Re: RFC 104 (v1) Backtracking

2000-08-17 Thread David L. Nicol

Jonathan Scott Duff wrote:
 
 On Tue, Aug 15, 2000 at 05:47:53PM -0600, Nathan Torkington wrote:
  I want
@result  = @a || @b;
  to be like:
(@result = @a) or (@result = @b);
 
  That's what all my students keep expecting it to mean.
 
 And that's what I keep wishing it meant too.
 
 -Scott
 --
 Jonathan Scott Duff
 [EMAIL PROTECTED]



So we want to define operator||, in a list context, operating on two lists,
to choose between them and return a list, rather than imposing scalar context.



We want ( LHS || RHS ) to mean, 


( LHS-BOOLEAN() ? LHS : RHS )


Correct?

-- 
  David Nicol 816.235.1187 [EMAIL PROTECTED]
  Does despair.com sell a discordian calendar?



Re: Component wise || and RFC 82 (was Re: RFC 104 (v1) Backtracking)

2000-08-16 Thread Damien Neil

On Tue, Aug 15, 2000 at 10:26:13PM -0600, Nathan Torkington wrote:
 I like the idea of adding the context-aware operators, but I don't
 think I'd use them as often as I use "the number of things in the
 array".  I think most Perl programmers would be in the same camp.
 Unless you can show a couple of cool things that this makes possible,
 that is.
 
 So I'd say: option, yes.  Default, no.

I also like the idea of context-aware operators.  I don't know if I
like them enough to want to break with former practice, but I do know
that I don't like the idea of making them optional.  This would be
the mother of all action-at-a-distance hells:

  set_size(@elts * 5);   # size = Five times the number of elements.

  set_size(@elts * 5);   # $size = The number of elements -- someone
 # turned on context-sensitive operators,
 # 2000 lines above here.

I don't know what the right thing to do is.  Context is crypto enough
these days, without shifting the rules on operator contexts around.
Perhaps the benefits outweigh the breakage that will occur.

- Damien



Uses for array notation (was Re: RFC 104 (v1) Backtracking)

2000-08-16 Thread Jeremy Howard

Mark Cogan wrote:
 At 12:39 PM 8/16/00 +1000, Jeremy Howard wrote:
 It seems obvious that @a should be the whole array @a, not the size of
the
 array. If I want to check the size of @a, I should have to do so
explicitly,
 with scalar or $#.
 
 This is non-obvious if you think that || is a flow control statement, so
 think about * for a moment:
 
@c = @b * @a;

 But, to me at least, arrays aren't something you multiply. Multiplication
 applies to numbers (scalars), and returns a scalar, so when you see

 @c = @b * @a

 it should be clear that something funny is going on.

Well, they're not something you multiply in Perl now. But there's plenty of
languages where you can, and it's ever so convenient.

 And, really, what is wrong with:

 @c = map {$a[$_] * $b[$_]} (0..$#a);

Numerical programming is all about manipulating arrays (or n-dim tensors,
but they're just order array slices really). Writing such programs in a
language that requires explicit loops is not only a pain, but creates code
that bears no resemblance to the numeric algorithm it's implementing.
Furthermore, it's out of the question in anything other than low-level
languages, because the looping and array dereferencing is much too slow.

It also makes easy things easy:

  @full_names = @first_names . @surnames;

and with the extension to scalars as one operand (coming in v2!):

  @quoted_lines = ' ' . @raw_lines;

or

  @histogram = '#' x @num_recs;

 It's pretty clear what working on 'the whole array' means here, I think.

 I disagree. In particular, think of it from the point of view of someone
 who hasn't studied computer science.

 What should:

 @a = defined @a;

 return?

defined() is a function. Under the proposed extension of RFC 82 from
operators to functions, this example should return a list of booleans, where
each is true if the corresponding element of the original list was defined.
Under Perl 5.6, 'defined @a' is deprecated. This RFC would give it a useful
meaning (in a list context).

 Treating || as a special case is asking for trouble. If you want a flow
 control statement, use one:
 
@result = @b unless @result = @a;

 || may be a suboptimal example, but I think the idea that a @-variable
 without an iteration function refers to the array as a whole, and not its
 elements is an intuitive one, and having array iteration magically happen
 when you're not looking is dangerous.

It seems funny if you're not used to it. But that's because we learn that
lists are hard, and computers have to loop. After just a little unlearning
it actually becomes quite intuitive, and is generally picked up with no
additional trouble by new students. Programmers shouldn't have to know how a
computer implements things behind the scenes--which is really what requiring
explicit looping forces.





Array notation (was Re: RFC 104 (v1) Backtracking)

2000-08-16 Thread Jeremy Howard

Mark Cogan wrote:
 At 11:11 PM 8/15/00 -0400, Chaim Frenkel wrote:
 You are missing the beauty of vector/matrix operations.

 No, I'm not; I'm opining that the vast majority of Perl users don't need
to
 do vector/matrix ops, and that they don't belong in the core.

The vast majority of Perl 5 users don't, because it's a pain in Perl 5. They
use other languages instead, but those other languages aren't nearly as nice
as Perl in almost every other way. Why not open up Perl for a whole new
class of folks?

 The math folks
 really would like to be able to describe the operation wanted and have
 perl do the optimization.

 Then maybe they should use a dedicate math extension to Perl, like PDL.

You've got to be joking! You think PDL is a simple convenient add-on to Perl
that provides these features? It's not! PDL is an astonishing hack by some
incredibly clever people, but it still _does_not_ support array notation,
and optimised loops have to be written in yet *another* language named PP,
which is compiled into C by a special compiler, and linked into the program.
This is the absolute best that can be done right now, and the PDL folks
deserve a medal for what they've achieved. But really, no-one should have to
jump through these kinds of hoops!

 Would adding another character be helpful
 
  @result = @a x|| @b?
 
  @result = @a ||| @b?
 
 or perhaps a modifier?
 
  @result = @a || @b forall;
 
 (Blech, that just doesn read right.)

 Perhaps we just need a two-list map, which aliases $a and $b like sort():

 @result = map {$a || $b} @a,@b;

No. It would need to be n-list, and it would have to handle slices and
lazily generated lists incredibly cleverly. map is too generic to easily
make the kinds of optimisations required for array notation.

I don't know how to convince you here. There's a feature that, if added to
Perl, would make my life and many of my collegues lives easier. I know this
for a fact because I've used it elsewhere. I doesn't break much that can't
fairly easily be incorporated into P52P6, it's a generic abstraction that
applies to many things other than numeric programming (it's great for string
manipulation!), and it's proved itself elsewhere.

I'm not ruling out a modifier, as Chaim outlined, although I agree that the
word 'blech' comes to mind. But this is too good an opportunity to see it
just disappear. Have a look at the examples in RFCs 23, 76, 81, 82, 90, and
91, which combine together to provide as strong a data manipulation language
as you'll find anywhere. Over the next few days I'll be updating these to
include more examples, particularly non-numeric ones.





Re: RFC 104 (v1) Backtracking

2000-08-16 Thread raptor

 There's also the cut operator which I didn't see mentioned in the RFC.
 It blocks backtracking so that something like this:

 B1 andthen B2 andthen cut B3 andthen B4 andthen B5
 wouldn't backtrack to B2 once it forwardtracked to B3.

]- I tried minimalistic approach as small as possible additions to the Perl
language, we get only the "backtrack" mechanism i.e. something that is
harder or slower to be done outside of the perl core.
The rest should be done outside . (I too want all in the core)
Example :

my $cutState = 0;
{
  { block1 } andthen { block2 } andthen { block3 } andthen


 if ($cutState) { last AFTER}
  else { $cutState = 1}; 1;
 }
andthen { block4 } andthen { block5 };
}
AFTER:
  code 

not sure will this also do the job :
 { $cutState = $cutState ? last AFTER : 1 } .

So the CUT is candidate for module. Offcourse I preffer all syntax to be
embeeded, cut,fail ... but if I tried in this way there is smaller chance
this to get in the core ..
Think, it is only around 10 lines of code to be added in perly.y i.e. 10
lines C code in Perl-core.
Mainwhile CUT is small too :")

 Okay, the more I think about it, the more I think it should be a
 module.
]- How this can be done as module ?
=
iVAN
[EMAIL PROTECTED]
=




Re: RFC 104 (v1) Backtracking

2000-08-16 Thread raptor

  They behave similarly like , ||, and, or operator with one main
  distinction they "backtrack" for example:
 
  { block1 } Bandthen { block2 };

 This would be a good use of the to-be-liberated = operator:

   { block1 } = { block2 };

 In any case, "andthen" doesn't seem like a good choice.
 Other possibilities:
 therefore
 implies
 segue
 seq
 so
]- any proposal for the name are welcomethey must be two.  the
reason I decided to use this is cause it works like/is similar to -
if-then-else, also look like and/or comparions operator.
The Prolog operators "," and ";" are already overused in perl.
THEN is not used by PERL, so here comes :

AND+THEN
OR+THEN

:")
=
iVAN
[EMAIL PROTECTED]
=




Re: RFC 104 (v1) Backtracking

2000-08-16 Thread Jeremy Howard

raptor wrote:
 ]- I tried minimalistic approach as small as possible additions to the
Perl
 language, we get only the "backtrack" mechanism i.e. something that is
 harder or slower to be done outside of the perl core.
 The rest should be done outside . (I too want all in the core)

I don't know if you noticed the earlier thread, but there's a few people
(including myself) who are still having trouble understanding how your
proposal works.

Could you please provide a brief idiomatic example of some code where this
proposal would provide a real practical benefit--enough that slow learners
like myself can really understand what it makes easier, and how? It would be
great if you could provide the equivalent Perl 5 code too.

TIA,
  Jeremy





Re: RFC 104 (v1) Backtracking

2000-08-16 Thread Jeremy Howard

Johan Vromans wrote:
 Damian Conway [EMAIL PROTECTED] writes:

  As I understand things:
 
  BLOCK1 andthen BLOCK2
 
  evaluates BLOCK1 and then if BLOCK1 evaluates to "true" evaluates
  BLOCK2.  If BLOCK2 evaluates to "true" we're done.  If BLOCK2
  evaluates to "false", then BLOCK1 is re-evaluated.
 
  So how is that different from:
 
  do BLOCK1 until do BLOCK2

 It's the same.
 But the real fun starts when blocks and functions can suspend and
 resume.

There's already an RFC for coroutines that proposes allowing suspension and
resumption of subroutines. Do the proposed backtracking operators buy
anything that do/until/coroutines don't provide?





Re: RFC 104 (v1) Backtracking

2000-08-16 Thread Chaim Frenkel

 "MC" == Mark Cogan [EMAIL PROTECTED] writes:

 is equivalent to
 
 @a = (\$a, \$b, \$c);
 
 rather than what you wrote.

MC Ah, so it is. I'd argue that that's broken and should be handled with map 
MC or for.

Err, That's not an accident. Larry designed that in. 

chaim
-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: RFC 104 (v1) Backtracking

2000-08-16 Thread John Porter

Damian Conway wrote:
 
 So how is that different from:
 
   do BLOCK1 until do BLOCK2
 
 ???

Because if BLOCK1 ever evaluates to False, the operation terminates.

It's more like

do { r = f1() } until ( not r or f2() );

-- 
John Porter




Re: RFC 104 (v1) Backtracking

2000-08-16 Thread Jonathan Scott Duff

On Wed, Aug 16, 2000 at 07:42:33PM +1000, Jeremy Howard wrote:
 raptor wrote:
  ]- I tried minimalistic approach as small as possible additions to the
 Perl
  language, we get only the "backtrack" mechanism i.e. something that is
  harder or slower to be done outside of the perl core.
  The rest should be done outside . (I too want all in the core)
 
 I don't know if you noticed the earlier thread, but there's a few people
 (including myself) who are still having trouble understanding how your
 proposal works.
 
 Could you please provide a brief idiomatic example of some code where this
 proposal would provide a real practical benefit--enough that slow learners
 like myself can really understand what it makes easier, and how? It would be
 great if you could provide the equivalent Perl 5 code too.

Here's some perl psuedo code that'll implement the "andthen" semantics:

BLOCK1 andthen BLOCK2 andthen BLOCK3 andthen BLOCK4

B1: if (BLOCK1) {
B2: if (BLOCK2) {
B3: if (BLOCK3) {
B4: if (BLOCK4) {
return "true"   
} else { goto B3 }
} else { goto B2 }
} else { goto B1 }
}
return "false"

The semantics for "orthen" are similar:

BLOCK1 orthen BLOCK2 orthen BLOCK3 orthen BLOCK4

B1: unless (BLOCK1) {
B2: unless (BLOCK2) {
B3: unless (BLOCK3) {
B4: unless (BLOCK4) {
return "false"  
} else { goto B3 }
} else { goto B2 }
} else { goto B1 }
}
return "true"

As for examples where this would be of benefit ... I really can't think
of any.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: RFC 104 (v1) Backtracking

2000-08-16 Thread John Porter

Johan Vromans wrote:
  So how is that different from:
  
  do BLOCK1 until do BLOCK2
 
 It's the same.

No, not quite.  See my other post.

-- 
John Porter




Re: RFC 104 (v1) Backtracking

2000-08-15 Thread John Porter

iVAN Georgiev [EMAIL PROTECTED]:
 
 They behave similarly like , ||, and, or operator with one main
 distinction they "backtrack" for example:
 
 { block1 } Bandthen { block2 };

This would be a good use of the to-be-liberated = operator:

  { block1 } = { block2 };

In any case, "andthen" doesn't seem like a good choice. 
Other possibilities:
therefore
implies
segue
seq
so

-- 
John Porter




Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Jonathan Scott Duff

On Wed, Aug 16, 2000 at 08:26:26AM +1000, Jeremy Howard wrote:
 Doesn't RFC 82 (Make operators behave consistantly in a list context)
 provide this functionality? This is perfectly valid under that proposal:
 
   @result = @a || @b;
 
 Which applies '||' component-wise to elements of @a and @b, placing the
 result in @result.
 
 I'm no Prolog guru, so feel free to correct me if I'm missing something
 here.

I think you're missing the backtracking part (I'm no guru either).
As I understand things:

BLOCK1 andthen BLOCK2

evaluates BLOCK1 and then if BLOCK1 evaluates to "true" evaluates
BLOCK2.  If BLOCK2 evaluates to "true" we're done.  If BLOCK2
evaluates to "false", then BLOCK1 is re-evaluated.  Er, let me see if
I can write the logic better:

1. eval BLOCK1
2. if "false", stop, else goto 3
3. eval BLOCK2
4. if "true", stop, else goto 1

It's kind of an all-or-nothing expression with side effects
(evaluating the blocks).  This sort of logic can be extended to N
blocks too.

Though I think if we're going to support backtracking like this, we'll
need to support the cut operator as well  (! in prolog)

(Note the only prolog I've done was about 10 years ago for about 2 weeks
and about 2 years ago for 2 or 3 weeks in a programming languages class
at a university)

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Damian Conway

As I understand things:

   BLOCK1 andthen BLOCK2

evaluates BLOCK1 and then if BLOCK1 evaluates to "true" evaluates
BLOCK2.  If BLOCK2 evaluates to "true" we're done.  If BLOCK2
evaluates to "false", then BLOCK1 is re-evaluated. 

So how is that different from:

do BLOCK1 until do BLOCK2

???



Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Nathan Torkington

Jeremy Howard writes:
   @result = @a || @b;
 
 Which applies '||' component-wise to elements of @a and @b, placing the
 result in @result.

*Ptui*  That's not how *I* want || to behave on lists/arrays.

I want
  @result  = @a || @b;
to be like:
  (@result = @a) or (@result = @b);

That's what all my students keep expecting it to mean.

Nat



Component wise || and RFC 82 (was Re: RFC 104 (v1) Backtracking)

2000-08-15 Thread Jeremy Howard

Nathan Torkington wrote:
 Jeremy Howard writes:
@result = @a || @b;
 
  Which applies '||' component-wise to elements of @a and @b, placing the
  result in @result.

 *Ptui*  That's not how *I* want || to behave on lists/arrays.

 I want
   @result  = @a || @b;
 to be like:
   (@result = @a) or (@result = @b);

 That's what all my students keep expecting it to mean.

Note that RFC 82 (http://tmtowtdi.perl.org/rfc/82.pod) proposes that _all_
operators behave the same way in a list context. To me, this consistancy
would be a real win.

The behaviour you're discussing is described in RFC 45. RFC 45 proposes a
special case for the || operator, which is only using its short-circuiting
functionality, not its 'or' functionality. In this case I would think that
using an explicit 'if' would be more appropriate. I'm working with the
maintainer of RFC 45 at the moment to see if we can get the consistency of
component-wise behaviour in a list context without losing the ability to
short-circuit in an assignment.

A potential compromise would be to say that RFC 82 only applies to operators
that do not short-circuit. However, my view is that the loss of consistency
through such a step would be a substantial source of confusion. It would
also mean that overloaded operators with a lazily evaluated parameter would
not work in a consistent manner.





Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Mark Cogan

At 05:47 PM 8/15/00 -0600, Nathan Torkington wrote:
Jeremy Howard writes:
@result = @a || @b;
 
  Which applies '||' component-wise to elements of @a and @b, placing the
  result in @result.

*Ptui*  That's not how *I* want || to behave on lists/arrays.

I want
   @result  = @a || @b;
to be like:
   (@result = @a) or (@result = @b);

That's what all my students keep expecting it to mean.

Seconded.

It seems obvious that @a should be the whole array @a, not an iteration 
over its elements. If I want to iterate over @a, I should have to do so 
explicitly, with a for() or map().
---
Mark Cogan[EMAIL PROTECTED] +1-520-881-8101 
ArtToday  www.arttoday.com




Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Mark Cogan

At 12:39 PM 8/16/00 +1000, Jeremy Howard wrote:
Mark Cogan wrote:
  At 05:47 PM 8/15/00 -0600, Nathan Torkington wrote:
  Jeremy Howard writes:
  @result = @a || @b;
   
Which applies '||' component-wise to elements of @a and @b, placing
the
result in @result.
  
  *Ptui*  That's not how *I* want || to behave on lists/arrays.
  
  I want
 @result  = @a || @b;
  to be like:
 (@result = @a) or (@result = @b);
  
  That's what all my students keep expecting it to mean.
 
  Seconded.
 
  It seems obvious that @a should be the whole array @a, not an iteration
  over its elements. If I want to iterate over @a, I should have to do so
  explicitly, with a for() or map().

It seems obvious that @a should be the whole array @a, not the size of the
array. If I want to check the size of @a, I should have to do so explicitly,
with scalar or $#.

This is non-obvious if you think that || is a flow control statement, so
think about * for a moment:

   @c = @b * @a;

But, to me at least, arrays aren't something you multiply. Multiplication 
applies to numbers (scalars), and returns a scalar, so when you see

@c = @b * @a

it should be clear that something funny is going on.

And, really, what is wrong with:

@c = map {$a[$_] * $b[$_]} (0..$#a);

?

(or, for that matter:

push @c, $a[$_] * $b[$_] for (0..$#a);

)

in both cases it's clear that you're iterating over the elemnts in the array.

It's pretty clear what working on 'the whole array' means here, I think.

I disagree. In particular, think of it from the point of view of someone 
who hasn't studied computer science.

What should:

@a = defined @a;

return?

Treating || as a special case is asking for trouble. If you want a flow
control statement, use one:

   @result = @b unless @result = @a;

|| may be a suboptimal example, but I think the idea that a @-variable 
without an iteration function refers to the array as a whole, and not its 
elements is an intuitive one, and having array iteration magically happen 
when you're not looking is dangerous.

---
Mark Cogan[EMAIL PROTECTED] +1-520-881-8101 
ArtToday  www.arttoday.com




Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Chaim Frenkel

You are missing the beauty of vector/matrix operations. The math folks
really would like to be able to describe the operation wanted and have
perl do the optimization.

Would adding another character be helpful

@result = @a x|| @b?

@result = @a ||| @b?

or perhaps a modifier?

@result = @a || @b forall;

(Blech, that just doesn read right.)

chaim

 "MC" == Mark Cogan [EMAIL PROTECTED] writes:

MC At 05:47 PM 8/15/00 -0600, Nathan Torkington wrote:
 Jeremy Howard writes:
@result = @a || @b;
 
  Which applies '||' component-wise to elements of @a and @b, placing the
  result in @result.
 
 *Ptui*  That's not how *I* want || to behave on lists/arrays.
 
 I want
 @result  = @a || @b;
 to be like:
 (@result = @a) or (@result = @b);
 
 That's what all my students keep expecting it to mean.

MC Seconded.

MC It seems obvious that @a should be the whole array @a, not an iteration 
MC over its elements. If I want to iterate over @a, I should have to do so 
MC explicitly, with a for() or map().





-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Mark Cogan

At 11:11 PM 8/15/00 -0400, Chaim Frenkel wrote:
You are missing the beauty of vector/matrix operations.

No, I'm not; I'm opining that the vast majority of Perl users don't need to 
do vector/matrix ops, and that they don't belong in the core.


The math folks
really would like to be able to describe the operation wanted and have
perl do the optimization.

Then maybe they should use a dedicate math extension to Perl, like PDL.

Would adding another character be helpful

 @result = @a x|| @b?

 @result = @a ||| @b?

or perhaps a modifier?

 @result = @a || @b forall;

(Blech, that just doesn read right.)

Perhaps we just need a two-list map, which aliases $a and $b like sort():

@result = map {$a || $b} @a,@b;



---
Mark Cogan[EMAIL PROTECTED] +1-520-881-8101 
ArtToday  www.arttoday.com




Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Chaim Frenkel

 "MC" == Mark Cogan [EMAIL PROTECTED] writes:

MC What should:
MC @a = defined @a;
MC return?

Counter example:@a = \($a, $b, $c);

(Not really a full fledged counter example since it is a liter list.)

 Treating || as a special case is asking for trouble. If you want a flow
 control statement, use one:
 
 @result = @b unless @result = @a;

MC || may be a suboptimal example, but I think the idea that a @-variable 
MC without an iteration function refers to the array as a whole, and not its 
MC elements is an intuitive one, and having array iteration magically happen 
MC when you're not looking is dangerous.

Not unless you are coming from a math background or are an old basic 
programmer, and would like to have matrix operations built in.

chaim
-- 
Chaim FrenkelNonlinear Knowledge, Inc.
[EMAIL PROTECTED]   +1-718-236-0183



Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Mark Cogan

At 11:43 PM 8/15/00 -0400, Chaim Frenkel wrote:
  "MC" == Mark Cogan [EMAIL PROTECTED] writes:

MC What should:
MC @a = defined @a;
MC return?

Counter example:@a = \($a, $b, $c);

I guess I'm missing the point; how is this different from

@a = [$a,$b,$c];

which works to be the same as

push @a, [$a,$b,$c];

?

[]

MC || may be a suboptimal example, but I think the idea that a @-variable
MC without an iteration function refers to the array as a whole, and not its
MC elements is an intuitive one, and having array iteration magically happen
MC when you're not looking is dangerous.

Not unless you are coming from a math background or are an old basic
programmer, and would like to have matrix operations built in.

But we're trying to decide what is best for perl as a whole, not just what 
is good for math people who use perl. I don't think that the requirement 
that a relatively small portion of the user base put :

use magical_array_iteration;

at the top of their code is too outre.

(and, for that matter, it might be nice to have an environment variable 
that implicitly sets -M command line options in the same way that PER5LIB 
sets -I. That way, math types can just set their perls to preload all the 
modules they want.)

---
Mark Cogan[EMAIL PROTECTED] +1-520-881-8101 
ArtToday  www.arttoday.com




Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Jonathan Scott Duff

On Tue, Aug 15, 2000 at 08:59:25PM -0700, Mark Cogan wrote:
 At 11:43 PM 8/15/00 -0400, Chaim Frenkel wrote:
 Counter example:@a = \($a, $b, $c);
 
 I guess I'm missing the point; how is this different from
 
 @a = [$a,$b,$c];

Well, I've lost the point of this thread, but 

@a = \($a, $b, $c);

is equivalent to 

@a = (\$a, \$b, \$c);

rather than what you wrote.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]



Re: RFC 104 (v1) Backtracking

2000-08-15 Thread Mark Cogan

At 11:05 PM 8/15/00 -0500, Jonathan Scott Duff wrote:
On Tue, Aug 15, 2000 at 08:59:25PM -0700, Mark Cogan wrote:
  At 11:43 PM 8/15/00 -0400, Chaim Frenkel wrote:
  Counter example:@a = \($a, $b, $c);
 
  I guess I'm missing the point; how is this different from
 
  @a = [$a,$b,$c];

Well, I've lost the point of this thread, but

 @a = \($a, $b, $c);

is equivalent to

 @a = (\$a, \$b, \$c);

rather than what you wrote.

Ah, so it is. I'd argue that that's broken and should be handled with map 
or for.
---
Mark Cogan[EMAIL PROTECTED] +1-520-881-8101 
ArtToday  www.arttoday.com




RFC 104 (v1) Backtracking

2000-08-15 Thread Perl6 RFC Librarian

This and other RFCs are available on the web at
  http://dev.perl.org/rfc/

=head1 TITLE

Backtracking

=head1 VERSION

  Maintainer: iVAN Georgiev [EMAIL PROTECTED]
  Date: 14 Aug 2000
  Version: 1
  Mailing List: [EMAIL PROTECTED]
  Number: 104

=head1 ABSTRACT

Backtraking mechanism is core functionality of languages like PROLOG.
Perl-regex engine has this ability too.

Adding this mechanism to our programming arsenal will bring alot of
new functionality. Will help us solve problems that otherwise cost us 
alot of time and effort (laziness).

A new paradigm to Perl - DECLARATIVE programming.

=head1 DESCRIPTION

The whole gang-bang can be done with only two new operators: andthen, orthen.

They behave similarly like , ||, and, or operator with one main
distinction they "backtrack" for example:

{ block1 } Bandthen { block2 };

mean this:
 
 if "block1" return true(1) "block2" is evaluated then 
 if "block2" return true(1) the end result is true(1)
 if "block2" return false(0) 
 we evaluate "block1" again i.e start from the beginning.
 but if "block1" return false(0) the end result is false(0)
 
or to be more clear this is the Perl equivalent/example:

 my $res = 0;
 {
  my $ex1;
  { $l = (rand()  0.3) ? 1:0;print "block1=$l\n"; $ex1=$l};
  if ($ex1)
   {
my $ex2;
{ $r = (rand()  0.7) ? 1:0;print "block2=$r\n"; $ex2=$r};
 if ($ex2) { $res = 1 } else { redo }
   };
  };

 print "The result is : $res\n";

Similarly "orthen":

 { block1 } Borthen { block2 };

mean this:

 if "block1" return true(1) the end result is true(1)
 but if "block1" return false(0) "block2" is evaluated then 
 if "block2" return true(1) the end result is true(1)
 if "block2" return false(0) 
 we evaluate "block1" again i.e start from the beginning.

OR this:

 if "block1" return true(1) 
 we evaluate "block2" and return true(1)
 w/o taking in consideration the result of "block2" evaluation.
 but if "block1" return false(0) "block2" is evaluated then 
 if "block2" return true(1) the end result is true(1)
 if "block2" return false(0) 
 we evaluate "block1" again i.e start from the beginning.

=head2 USAGE

Good candidates for "backtracking" are XML processors,
analytical "permutations!", expert systems and many more...
 
Cycle:
 
 my $i = 0;
 {$i++; $i = 10 } andthen {print $i};

equivalent to:
 
 for (my $i=1;$i++;$i=10) {print $i};

=head2 FURTHER WORK

As you saw I tried to propose as small change to the perl 
core/language as possible, which can be easily implemented.
What else we can expect?

One good addition that can we thought about is implementing 
the Perl BLOCK's as forth-state BLACKBOX structure not as 
it is now i.e. two states, what I mean ?

Currently AFAIK we have "entering" and "leaving" the block.
We can have "direction" i.e. with "backtrack" mechanism we 
can enter the block from previous block or from the next one - 
the four "states" are - enter(-),leave(-),reevaluate(-),fall(-), 
we will need also to count how many times the block has been 
in all of these states. We can leave the old behaviour as 
default(in the name of speed) and only when the Perl programmer 
need these states to use "state" pragma.
 
   use state "2";
   use state "4";
 
BUT this will be alot of work, so for now andthen, orthen 
are enough. If backtracking is made as more general algorithm 
it can be used both by Perl itself and regex engine ?!!

=head1 IMPLEMENTATION

There is many possible implementations one of them you saw 
in DESCRIPTION section, it can also be implemented as 
while, until cycle...

If I was perl-core hacker you now will be reading 
and applying the patch :"), I believe that this can be very 
easily implemented as just adding several lines in perly.y 
(please excuse my ignorance if this is not the case)

=head1 REFERENCES

perldoc perlre

The Prolog Language:
http://www.sics.se/SICS-reports/SICS-T--93-01--SE/report_10.html

Coroutining facilities:
http://www.sics.se/SICS-reports/SICS-T--93-01--SE/report_8.html