On Fri, 25 Oct 2002, Martin D Kealey wrote:
: Going back to Perl5 for a moment, we have
: 
:   substr($str,$start,$len) = $newstr
: 
: why not simply extend pattern-matching in a similar way to substr, making it
: an L-value, so that one gets
: 
:   $str ~ /[aeiou]+/ = "vowels($&)"
: 
: or
: 
:   $str ~ /\d/ {hyper-symbol}= (0) x {size-of-LHS-array};

Problem with that...the replacement argument has to be lazy, and currently
the RHS of an assignment is actually evaluated before the left.  You'd
really need something more like

    $str =~ /\d/ = { 0 }

However, I think readability suffers without a hint on the front what
you're trying to do.  So I'd be more inclined to say that the general
syntax is really more in the spirit of a conditional:

    where $str =~ /\d/ { 0 }

The difference between inplace and copying is then really the disposition
of the closure:

    where $str =~ /\d/, replace => { 0 }
    where $str =~ /\d/, return => { 0 }

But that's clunky.  If replacement is the norm, then returning a copy is just

    where $str =~ /\d/ { 0 }
    where $str.dup =~ /\d/ { 0 }

The topicalized forms would then be:

    where /\d/ { 0 }
    where .dup =~ /\d/ { 0 }

Except that still doesn't tell it whether to return a boolean or a string...

Of course, most of the time you want to replace with a string, and

    where /\d/ { "0" }

is still a lot clunkier than

    s/\d/0/;

Maybe we end up with that form and a Ruby-esque

    s(/\d/) { "0" }

in the general case.  Or it could go in the parens.  Hey, maybe that's
a good spot for an arrow:

    s(/\d/ -> { "0" })

In any event, we still haven't really solved the want-a-string vs
the want-a-boolean problem.  Maybe it's just context:

    if s(/\d/ -> { "0" }) {...}         # boolean context, in-place
    s(/\d/ -> { "0" });                 # void context, in-place

    print s(/\d/ -> { "0" })            # string context, return string

    $result = ~s(/\d/ -> { "0" })       # string context, return string
    $result = ?s(/\d/ -> { "0" })       # boolean context, return string
    $result = s(/\d/ -> { "0" })        # untyped context, return what?

But I suspect that's too much weight to put on the context system.  It
doesn't really solve the readability problem, especially when we get more
that one {...} in a row.

By all accounts, a s/// is an odd thing to put in a smart match
anyway.  You can't have a superposition of things with side effects,
for instance:

    $str =~ s/a/b/ | s/b/c/

Though doubtless Damian can think of something indeterminate to make
it mean.  :-)

The in-place really feels more like you want a method

    $str.s/a/b/
    @foo.s(1|2|3, {0})

or maybe

    $str.subst/a/b/
    @foo.subst(1|2|3, {0})

Maybe the return value form is also a method:

    $result = $str.where/a/b/
    @result = @foo.where(1|2|3 -> {0})

In typical topical string usage, that leaves us with

    if .subst/a/b/  {...}
    $result = .where/a/b/

That's quite livable, though the second is a bit odd, English-wise.
We could even keep around

    s/a/b/

as a shorthand for .subst/a/b/.  And maybe even add

    w/a/b/

as a synonym for .where/a/b/.

If so, possibly we don't have .subst/a/b/, but just .subst(/a/ -> { "b" })
for the general form.  But string-like method args are certainly a possibility
in general, provided we can keep the declarations in order.  But if not,
there's a bad ambiguity between

    .subst/a/b/

and things like

    .size/2

: (hyper, however it's spelt, will have some way for the RHS to reference the
: LHS, won't it?)

Haven't specified one.  @array ^= 0 is supposed to do the right thing already,
and doesn't require the right side to know anything about the left side.

Larry

Reply via email to