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

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

Thread Previous | Thread Next
From:
demerphq
Date:
August 22, 2012 05:25
Subject:
Re: fixing smartmatch just hard enough (and when, too)
Message ID:
CANgJU+WX9sCDrZnmUKw6=vDHRDGL9fmmoq-_=yT4hvkO_sLHkQ@mail.gmail.com
On 22 August 2012 13:44, Damian Conway <damian@conway.org> wrote:
> I've found the discussion in this thread (and the newline thread it
> has spawned) extremely useful. Thank-you to everyone who has
> contributed.
>
> 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
> specification):
>
>     $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.

It seem to me that the problem here is that the flag you speak of is
currently theoretical. IOW, any case where a string was numified, or a
num stringified would end up being ambiguous, and I think this happens
a lot more than you seem to suggest.  For instance, simply _printing_
a numeric var upgrades it from a SvIV or SvNV to a SvPVIV or SvPVNV.

$ perl -MDevel::Peek -e'my @s=qw(2foo 2 2.0 bar); $x= 0+$_ for @s;
Dump $_ for @s'
SV = PVNV(0x202f080) at 0x202fd80
  REFCNT = 2
  FLAGS = (POK,pIOK,pNOK,pPOK)
  IV = 2
  NV = 2
  PV = 0x2046c90 "2foo"\0
  CUR = 4
  LEN = 8
SV = PVIV(0x2041cb0) at 0x202ffc0
  REFCNT = 2
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 2
  PV = 0x2054b70 "2"\0
  CUR = 1
  LEN = 8
SV = PVNV(0x202f100) at 0x204bda0
  REFCNT = 2
  FLAGS = (NOK,POK,pIOK,pNOK,pPOK)
  IV = 2
  NV = 2
  PV = 0x2059bb0 "2.0"\0
  CUR = 3
  LEN = 8
SV = PVNV(0x202f120) at 0x204bdb8
  REFCNT = 2
  FLAGS = (POK,pIOK,pNOK,pPOK)
  IV = 0
  NV = 0
  PV = 0x2059c60 "bar"\0
  CUR = 3
  LEN = 8

$ perl -MDevel::Peek -e'my @n=(0,1,1.2,0e0); $x= "$_" for @n; Dump $_ for @n'
SV = PVIV(0x1953cb0) at 0x1941d80
  REFCNT = 2
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 0
  PV = 0x1958c80 "0"\0
  CUR = 1
  LEN = 8
SV = PVIV(0x1953cc8) at 0x1941fc0
  REFCNT = 2
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 1
  PV = 0x196ec70 "1"\0
  CUR = 1
  LEN = 8
SV = PVNV(0x1941080) at 0x195dd90
  REFCNT = 2
  FLAGS = (NOK,POK,pNOK,pPOK)
  IV = 0
  NV = 1.2
  PV = 0x1961570 "1.2"\0
  CUR = 3
  LEN = 40
SV = PVNV(0x19410a0) at 0x195dda8
  REFCNT = 2
  FLAGS = (NOK,POK,pNOK,pPOK)
  IV = 0
  NV = 0
  PV = 0x1967bc0 "0"\0
  CUR = 1
  LEN = 40


Yves


-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

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