Larry Wall wrote:
Jonathan Lang wrote:
: Translating this to perl 6, I'm hoping that perl6 is smart enough to let me
: say:
:
:    s(pattern) { doit() }

Well, the () are illegal without intervening whitespace because that
makes s() a function call, but we'll leave that alone.

Thank you; I noticed this after I had sent it.

Perl 5 let certain choose-your-own quotes introduce various kinds of
odd semantics, and that was generally viewed as a mistake.  That is why
S02 says:

    For these "q" forms the choice of delimiters has no influence on the
    semantics.  That is, C<''>, C<"">, C<< <> >>, C<«»>, C<``>, C<()>,
    C<[]>, and C<{}> have no special significance when used in place of
    C<//> as delimiters.

We could make an exception for the second part of s///, but certainly
for this case I think it's easy enough to write:

    .subst(/pattern/, { doit })

However, taken as a macro, s/// is a rather odd fish.  The right side
isn't just a string, but a deferred string, which implies that there
are always curlies there, much like the right side of && implies
deferred evaluation.

Perhaps quotes should be given the same "defer or evaluate as
appropriate to the context" capability that regexes and closures have?
That is, 'q (text)' is always a Quote object, which may be evaluated
immediately in certain contexts and be passed as an object in others.
As a first cut, consider using the same rule for this that regexes
use: in a value context (void, boolean, string, or numeric) or as an
explicit argument of ~~, a quote is immediately evaluated; otherwise,
it's passed as an object to be evaluated later.

The main downside I see to this is that there's no way to force one
approach or the other; a secondary issue has to do with the usefulness
of an unevaluated string: with regexes and closures, the unevaluated
versions are useful in part because they can be made to do different
things when evaulated, based on the circumstances: $x ~~ $regex will
do something different than $y ~~ $regex, and closures can potentially
be fed arguments that allow one closure to do many things.  A quote,
OTOH, isn't neccessarily that flexible.

Or is it?  Is there benefit to extending the analogy all the way,
letting someone define a parameterized quote?

But it's possible that some syntactic relief of a dwimmy sort is
in order here.  One could view s[pattern] as a kind of metaprefix
on the following expression, sort of a self-contained unary &&.
I wonder how often we'd have to explain why

    s/pattern/ "expression"

doesn't do that, though.  'Course, it's already like that in Perl 5.

Probably not too often - although I _would_ recommend that you
emphasize the distinction between standard regex notation used
everywhere else and the "extended" regex notion used by s///.

I _do_ like the idea of reserving this behavior to situations where
the pattern delimiters are a matched set, letting you freely choose
some other delimiter for the expression.  In particular, I'm not
terribly fond of the idea of

   s'pattern'expression'

applying single-quote semantics to the expression.

Unlike in Perl 5, this approach would rule out things like:

    s[pattern] !foo!

which would instead have to be written:

    s[pattern] qq!foo!

Fine by me.  This would also let you easily apply quote modifiers to
the expression.

As a unary lazy prefix, you could even just say

    s[pattern] doit();

Of course, then people will wonder why

    .subst(/pattern/, doit())

doesn't work.

Perhaps.  But people quickly learn that different approaches in perl
often have their own unique quirks; this would just be one more
example.

Which makes me want to build it into the pattern somewhere
where there's already deferred evaluation that just happens to be triggered
at the right moment:

    /pattern {subst doit}/
    /pattern {subst "($0)"}/
    /pattern {subst q:to'END'}/
                    a new line
                    END

We can give the user even more rope to shoot themselves in the dark with:

    /pattern {$/ = doit}/
    /pattern {$0 = "($0)"}/
    /pattern {$() = q:to'END'}/
                    a new line
                    END

The possibilities are endless...

These aren't syntaxes that I'd want to use; but then, TIMTOWTDI.  The
main problem that I have with this approach is that it could interfere
with being able to use the venerable s/pattern/expression/ notation;
I'm looking to open up new possibilities, not to remove a perfectly
workable existing one.

Well, not quite.  One syntax we *can't* allow is /pattern/{ doit }
because that's already used to pull named captures out of the match
object.

...which brings up another potential conflict with the s/// notation:
how _do_ you pull named captures out of the match object in s///?

--

On a related subject: it seems to me that the notion of extending the
pattern notation to include a "replace" clause is at the heart of the
issue here.  In addition to the above issues, it seems to be too much
of a one-trick pony as currently conceived (well, a two-trick pony:
substitutions and transliterations.)  Perhaps we could generalize this
into some sort of alternate Pair syntax, with some sort of guideline
imposed so that the compiler won't have to do a look-ahead
disambiguation between // and /// - say, /// is only legal when the
compiler knows for certain that it's not looking for a regex.

--
Jonathan "Dataweaver" Lang

Reply via email to