Debbie Pickett wrote:

> So . . correct me if I'm wrong . . .
> 
> C<rule> allows us to define both named and anonymous rules,

Yes.


> depending on context.

Depending on whether or not you provide a name.


> C<rx> allows us to define only anonymous rules.

Yes. And they can't take parameter lists.


> C<rule> is the more general one, and you can use it exclusively 
 > if that's what you feel like.

More or less. Delimiter-wise, C<rx> is the more general one, but
semantically, yes, C<rule> is the more general.


> The only extra piece of syntactic sugar that C<rx> is giving us over
> C<rule>[*] is the ability to have arbitrary delimiters.

Not quite arbitrary. Alphanumerics aren't allowed, nor are colon or
parens.


> If I were satisfied with always using C<{}> as delimiters for C<rx> then a
> program would run the same if I did a C<s:each/rx/rule/> on it.

Yes. Although, of course, you'd have to do a C<s:each{rx}{rule}> if you wanted
to be consistent ;-)


> Is there some _syntactic_ constraint (i.e., required by the parser)
> that requires C<rule> to use braces for delimiters?

No.


 > That is, shouldn't the following:
 >
>   $config_line = rule ($ident) { <$ident> = \N* }
>
> always be parseable for any given value of C<{> and C<}> (barring
> obvious exceptions like colons and parentheses)?

Yes. Modulo the obvious requirement to escape whatever delimiter you're using.


> Or, to put it more succinctly: do there exist two pieces of
> *syntactically correct* code like
>   ... rule ... 
> and
>   ... rx ...
> (where the ... are identical in both) which each produce *valid* and
> *different* semantics?

Yes. For example:

        sub foo;

        foo rule ($arg) { $var := <$arg> };
        foo rx   ($arg) { $var := <$arg> };

The first means:

        foo                     # Call foo
            rule                # Passing a single pattern
                  ($arg)         # That takes a single parameter
                  {
                      $var :=    # And binds hypothetical $var...
                      <$arg>     # ...to what the parameter (treated as a pattern) 
matches
                  }
         ;

The second means:

        foo                     # Call foo
            rx (                # Pass, as its first argument, a pattern...
                $arg             # ...that matches the contents of $arg as a literal 
string
             )                   # No comma needed after first arg since next arg is...
             {                   # ...a closure...
                $var := <$arg>   # ...that binds $var to a stream iterator over $arg
             }
         ;


In other words, the second is the same as:

        foo rule {$arg}, sub{ $var := <$arg> };


 > Notwithstanding C<< -> >>, which I now understand to be nothing
> more than a different spelling of C<sub>.

It's a little more than that. A C<< -> >> uses different delimiters
(now *there's* a parallel!) for its parameter list. Whereas C<sub>
requires {...}, C<< -> >> allows either (...) or <ws>...<ws>.

Damian

Reply via email to