develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About