[% setvar title Generalize %]
Note: these documents may be out of date. Do not use as reference! |
To see what is currently happening visit http://www.perl6.org/
Generalize =~ to a special "apply-to" assignment operator
Maintainer: Nathan Wiger <nate@wiger.org> Date: 29 Aug 2000 Last-Modified: 16 Sep 2000 Mailing List: perl6-language-regex@perl.org Number: 170 Version: 2 Status: Frozen
Currently, =~
is only available for use in specific builtin pattern
matches. This is too bad, because it's really a neat operator.
This RFC proposes a simple way to make it more general-purpose.
Probably the only way this could be implemented is if RFC 164 was
also implemented, freeing =~
for use as a more general-purpose
operator. Indeed, a main point of this RFC is to provide a means for a
backwards-compatible syntax for regex's.
Unlink RFC 164, most people I heard from liked this. Some criticized it as being too sugary, since this:
$string =~ quotemeta; # $string = quotemeta $string;
Is not as clear as the original. However, there is fairly similar precedent in:
$x += 5; # $x = $x + 5;
And to me it seems to be quite clear that quotemeta
is acting on
$string
in the above example, even when you take into account =~
's
current binding meaning (perhaps more so, in fact).
First off, this assumes RFC 164. Second, it requires you drop any
knowledge of how =~
currently works. Finally, it runs directly
counter to RFC 139, which proposes another application for =~
.
This RFC proposes a simple use for =~
as a generic "apply-to"
operator. When used, any values on the left side of the expression are
implicitly passed to the end of the right-side expression. What this
means is that an expression such as this:
$value = dostuff($arg1, $arg2, $value);
Could now be rewritten as:
$value =~ dostuff($arg1, $arg2);
And $value
would be implicitly transferred over to the right side as
the last argument. It's simple, but it makes what is being operated on
quite obvious.
This enables us to rewrite the following constructs:
$string = quotemeta($string); @array = reverse @array; ($name) = split /\s+/, $name; @vals = sort { $a <=> $b } @vals; @file = grep !/^#/, @file; $string = s/\s+/SPACE/, $string; # RFC 164 $matches = m/\w+/, $string; # RFC 164 @strs = s/foo/bar/gi, @strs; # RFC 164
As the shorter and more readable:
$string =~ quotemeta; @array =~ reverse; ($name) =~ split /\s+/; @vals =~ sort { $a <=> $b }; @file =~ grep /!^#/; $string =~ s/\s+/SPACE/; # looks familiar $string =~ m/\w+/; # this too [1] @strs =~ s/foo/bar/gi; # cool extension
It's a simple solution, true, but it has a good amount of flexibility and brevity. It could also be the case that multiple values could be called and returned, so that:
($name, $email) = special_parsing($name, $email);
Becomes:
($name, $email) =~ special_parsing;
Again, it's simple, but seems to have useful applications. One nice
thing is that in many (most?) situations it appears to be working very
much like =~
currently works with regex's (from a user perspective).
Finally, note this can only work with functions and function-like constructs. An attempt to do something like this:
$x =~ 5 +;
Should definitely remain a syntax error.
~=
operatorA symmetric operator, ~=
, was proposed informally on the list which
would left-pad the argument list:
$stuff =~ dojunk(@args); # $stuff = dojunk(@args, $stuff); $stuff ~= dojunk(@args); # $stuff = dojunk($stuff, @args);
but the consensus that I received was about 50/50: half liked it, half
thought it was too confusing. Even though we don't have a bitnot=
operator currently, creating something that looks like one but acts
completely differently is probably not a good idea.
If something like this was included, it would probably be best to go
with another operator, like =^
:
$stuff =~ dojunk(@args); # $stuff = dojunk(@args, $stuff); $stuff =^ dojunk(@args); # $stuff = dojunk($stuff, @args);
But that's awfully close to ^=
. Hmmm. Regardless, this operator is
unlikely to be used nearly as widely since Perl functions usually take
the argument to act on in the last position.
Simplistic (hopefully). Should just involve stacking values onto a function's argument list.
This introduces new functionality, which allows backwards compatibility for regular expressions. As such, it should require no special translation of code. This RFC assumes RFC 164 will be adopted (which it may not be) for changes to regular expressions.
[1] That m// one doesn't quite work right, but that's a special case that I would suggest should be caught by some other part of the grammar to maintain backwards compatability (like bare //).
RFC 164: Replace =~, !~, m//, s///, and tr/// with match(), subst(), and trade()
RFC 139: Allow Calling Any Function With A Syntax Like s///
Bart Lateur's suggestion of using the term "apply-to": www.mail-archive.com