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

Re: fixing smartmatch just hard enough (and when, too)

Thread Previous | Thread Next
Damian Conway
August 22, 2012 04:45
Re: fixing smartmatch just hard enough (and when, too)
Message ID:
I've found the discussion in this thread (and the newline thread it
has spawned) extremely useful. Thank-you to everyone who has

I don't want to curtail that discussion, but I felt it might be useful
to summarize some of those ideas...or rather, the way those ideas have
adjusted my own thinking.

So, in light of those discussions, here's my current preferred option...

Smartmatch (~~) table

    $a       $b                    Meaning
    =====    ===================   ========================
    Any      undef                 ! defined $a
    Any      ~~-overloaded   [1]   $b->ol_method($a, 'rev')
    ~~-ol    Any             [1]   $a->ol_method($b)
    Any      CodeRef, &{}-ol       $b->($a)
    Any      Regexp, qr-ol         $a =~ $b
    Any      unambiguous Num [2]   $a == $b
    Any      unambiguous Str [3]   $a eq $b
    Any      Any                   die

    [1] Includes junctions, whose overloading distributes the
        smartmatch over their elements in their several ways.

    [2] If $b has an internal numeric representation but no
        internal string representation (or if some putative
        internal flag assures us it was originally a number).

    [3] If $b has an internal string representation but no
        internal numeric representation (or if some theoretical
        inner flag promises us it was initially a string).

The when construct

    Form                  Meaning
    ==================    ==================================
    when (EXPR)  {...}    if ($_ ~~ (EXPR))     {...; break}
    when {BLOCK} {...}    if ($_ ~~ sub{BLOCK}) {...; break}

    No exceptions.
    No special cases.

Note that this proposal still differs slightly from *all* of the various ideas
that were explicitly suggested.

In particular, I'm now proposing to fix the number/string ambiguity by
making *any* ambiguous case fatal, rather than falling back on eq
when we're not sure. So we only do == when we're certain it's a
number, and only do eq when we're certain it's a string, and if we're
not certain, we always die.

In practice, that would mostly only affect isolated cases (and those
cases could still be resolved easily, by explicit coercion or explicit

    $var = 1;      # only a number inside
    say $var;      # now a number and a string inside

    given ($someval) {
        when ( "$var" )   {...}  # expr produces only a string, so always eq
        when ( 0 + $var ) {...}  # expr produces only a number, so always ==
        when ( $var )     {...}  # expr may produce either, so always fatal

        when {$_ == $var} {...}  # always ==
        when {$_ eq $var} {...}  # always eq

    if ($otherval ~~ 1   ) {...}   # number -----> always ==
    if ($otherval ~~ "1" ) {...}   # string -----> always eq
    if ($otherval ~~ $var) {...}   # ambiguous --> always fatal

    if ($otherval == $var) {...}   # d'oh
    if ($otherval eq $var) {...}   # ditto

The point being: you either specify precisely what you mean (with a
typed literal, or with an expression that produces an unambiguously
typed value, or with an explicit operator), or else you accept the
possibility of catastrophic failure in a very limited number of cases.

This approach seems to cover most of the objections and concerns that
have been voiced so far, and seems both simple enough and powerful
enough to be worth considering.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About