Front page | perl.perl5.porters |
Postings from December 2022
Re: Deprecation of smartmatch
Thread Previous
|
Thread Next
From:
Paul "LeoNerd" Evans
Date:
December 2, 2022 17:39
Subject:
Re: Deprecation of smartmatch
Message ID:
20221202173853.286965b3@shy.leonerd.org.uk
On Fri, 2 Dec 2022 16:12:35 +0000
"Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk> wrote:
> [With my PSC hat on]
...
> We also aim to provide some thoughts on what new features may be added
> to Perl in the future to provide a better solution to these common
> situations that smartmatch and `given/when` are currently used for.
[And now with my personal hat on. These are just my own thoughts and
not the collected decisions of the PSC as a whole.]
I've been working on a number of CPAN module that implement syntax
extensions, which could be good design candidates for something to
provide in core.
Each of these has been designed, not to be a *total* replacement of
everything that smartmatch or given/when can do (because indeed, most
of the problem with them is the huge wide-ranging set of conflicting
features and behaviours they had), but instead to attack one small
specific problem area and find a nice neat solution to *that* problem
in a way that can be combined with the others, in programmer-controlled
(rather than runtime value-controlled) ways.
* The `match/case` statement
https://metacpan.org/pod/Syntax::Keyword::Match
The main use-case for given/when is to ask the question "does this
scalar value match any of these possible things?" - much like a
C-style switch statement. For this scenario, I imagined a new pair of
keywords used in a similar style to given/when. A key difference
here is that they don't use smartmatch, but instead use an operator
that the programmer specified upfront. That way, there can be no
surprises that it does "odd things" when it encounters some weird
value you weren't expecting. If you expected string equality
matching, you *know* you are getting string equality matching
because it says so right there:
my $var = "abc";
match($var : eq) {
case("abc") { $ok++ }
case("def") { fail('Not this one sorry'); }
}
* The `in` meta-operator
https://metacpan.org/pod/Syntax::Operator::In
One thing people liked to use `~~` for is to ask "is this value a
member of that list of values?"; a sortof set-element-of operator.
While it's been possible to ask this question using List::Util::any
ever since perl 5.6 (and likely before - I don't remember that far
back in time), people still aren't satisfied with that notation:
if($x ~~ @numbers) { ... }
if(any { $x == $_ } @numbers) { ... }
For those folks, I have written an `in` meta-operator. Motivated in
much the same way as match/case above, there can be no ambiguity on
"is this matching with number or string equality here?" because it
says right upfront in the operator name itself. You tell it - `==`
or `eq`.
if($x in:== @numbers) { ... }
* The `equ` and `===` operators
https://metacpan.org/pod/Syntax::Operator::Equ
Once the above things are taken into account, there isn't much left
that's "obvious" about smartmatch or given/when, that isn't already
handled. One remaining problem is that given/when and smartmatch can
distinguish undef from both the number zero and the empty string.
Neither of the above things can do that.
For this problem I imagined two new operators, `equ` and `===`, which
are slight variants of the familiar `eq` and `==` but which consider
undef to be a distinct value separate from empty or zero.
if($n === 0) { say "n is zero" }
else { say "n is undefined, or non-zero" }
Useful on their own perhaps, but they become more useful when you
realise you can use them with `match` or `in`:
match($x : equ) {
case(undef) { say "x is undef" }
case("") { say "x is the empty string" }
default { say "x is a non-empty string" }
}
if($x in:=== (0..9)) { say "x is a defined single-digit number" }
To recap on above: This set of ideas isn't supposed to cover every
possible use-case of smartmatch and given/when. Rather, it is intended
to cover a wide range of practical useful things that people *actually*
use the syntax for. Each was designed in the face of real practical
problems. Furthermore, match/case is already in use in a number of CPAN
modules, and actual real-world programs that I run all the time:
https://metacpan.org/module/Syntax::Keyword::Match/requires
I believe that, between them, this set of ideas and syntax could be a
useful addition to the Perl language, as a much more predictable and
controllable alternative to smartmatch.
--
Paul "LeoNerd" Evans
leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Thread Previous
|
Thread Next