develooper Front page | perl.perl5.porters | Postings from August 2012

fixing smartmatch (again (still))

Thread Next
From:
Ricardo Signes
Date:
August 28, 2012 11:43
Subject:
fixing smartmatch (again (still))
Message ID:
20120828184348.GA14244@cancer.codesimply.com

Let's try again.

First, though, I want to say that I was really happy with the discussion about
this.  It was on topic, interesting, and helpful.  Even if there *was* a holy
ton of it!

## The New ~~ Operator

    $a      $b                  Meaning
    ======= =======             ======================
    Any     undef               ! defined $a
    Any     ~~-overloaded       ~~ overloading is used
    Any     Regexp, qr-ol       $a =~ $b
    Any     CodeRef, &{}-ol     $b->($a)
    Any     Any                 fatal

So, this is the table I proposed in July 2011, and it's what I think we're back
to.  No special cases.

There is no question of how ($x=5) somehow became ambiguous, because if $x
contains 5 or "5" is is not allowed as the smartmatcher operator, period.  Use
Smart::Match and say stringwise(5) or numwise(5), or pass sub{$_==5}

If both 'qr' and '&{}' are overloaded, '~~' must be overloaded to disambiguate.

Switches are still okay.

## The new behavior of given/when

  given ($x) {
    when ($y)  { ... } # $x ~~ $y
    when (4)   { ... } # $x == 4
    when ('4') { ... } # $x eq 4
  }

Deferred/computed values of any sort mean smart match.

Two dead-simple special cases: Numeric literals mean ==.  String literals mean
eq.

If you want one case for $x eq a or b or c, then:

  given ($x) {
    when (stringwise any qw(a b c)) { ... }
  }

## What about what Father C. said?

Sprout proposed that smartmarch be jettisoned and that `when` always evaluate
its parameter as a boolean expression, save for the same simple cases above.

For the "$x eq a or b or c" example, that gives us at least two simple choices:

  given ($x) {
    # Here, "any" returns a "junction" that distributes the eq
    when ($_ eq any qw(a b c)) { ... }
  }

Or:

  given ($x) {
    # Here, stringwise implies the "$_ eq"
    when (stringwise any qw(a b c)) { ... }
  }

My thoughts on this are:

• I like the idea that we can have matcher objects that can be passed in
  more succinctly than a sub.  ->set_matcher(qr/../) or ->set_matcher($obj)
  both seems simpler to me than ->set_matcher(sub { /.../ }) or
  ->set_matcher(sub { $obj->match($_) })

• If we do, then Smart::Match and many other things keep working as they have
  without needing to be rewritten.  This is nice.

As Father Chrysostomos suggests, perl does not *need* smartmatch.  Really, it
doesn't need need features.  My question is, does perl benefit more from this
fix to smartmatching than it does from simply removing it?  I believe it does.

-- 
rjbs


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