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