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