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

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

Thread Previous | Thread Next
From:
Ricardo Signes
Date:
August 31, 2012 16:43
Subject:
Re: fixing smartmatch just hard enough (and when, too)
Message ID:
20120831234314.GA32142@cancer.codesimply.com
* Peter Scott <Peter@PSDT.com> [2012-08-31T18:52:23]
> On 8/31/2012 2:56 PM, Ricardo Signes wrote:
> >* Peter Scott <Peter@PSDT.com> [2012-08-31T16:04:53]
> >
> >FC's suggestion was that when have three meanigns:
> >
> >   when (NUM)  { ... } # numeric literal, means $_ == NUM
> >   when (STR)  { ... } # string literal,  means $_ eq STR
> >   when (EXPR) { ... } # other expression, evaluates normally as in "if"
> >
> >Smartmatch (~~) was to be abolished.
> Thank you for the painstakingly patient and polite education.  Now
> light dawns.  Decoupling when and smartmatch.  Is that generally
> agreed now no matter what?

It seems likely.  After all, when already only *usually* means smartmatch.
For example, when($x ~~ $y) is boolean, not "$_ ~~ ($x ~~ y)".  when($x && $y)
means "$_~~$x && $_~~$y" but when(2 && 3) doesn't; it's constant folded.  So,
since when is already "mostly smartmatch," making it "much more often
smartmatch" is, I think, a big improvement.  The special cases we end up with
under this proposal are very few (two, exactly) and not prone to the same sort
of pain.

(For the current exceptions, consult perlsyn and search for "10 exceptional
cases")

> >On the other hand, eliminating the first two tokens in "$_ eq
> >'foo'" or "$_ == 4" in each when statement like that is a win.
> 
> I wonder if restoring just the operator part of that comparison
> would be a suitable compromise?  Because then - if if it can be
> parsed, and maybe it cannot, I have the bliss of ignorance there - I
> would like to write things like:
> 
> when ( < 65    ) { say "Cold"       }
> when { == 98.4 } { say "Tasty"      }
> when { >= 75   ) { say "Hot"        }
> default          { say "Just right" }
> 
> and then the presence of == vs eq would disambiguate the type and I
> could use $BLOOD_TEMPERATURE etc.  [I also thought about 'when ( >=
> 65 && < 75)' but my ignorance isn't *that* blissful.]

I see the temptation.  Binary comparisons are, in fact, one of the existing "10
exceptions."  I think that the complexity isn't worth the win over this
spelling, though:

  when { $_ < 65    } { say "Cold"       }
  when { $_ == 98.4 } { say "Tasty"      }
  when { $_ >= 75   } { say "Hot"        }
  default             { say "Just right" }

Too many questions spring up when I think about operators with no lhs — and
this is something that came up on IRC (with phaylon) and in person (with
Damian).  I get nervous — and I'm not even the guy who'd have to implement the
parsing changes! :-)

> >This means that ~~ has exactly four valid types of rhs, which you
> >agreed were simple and probably memorable.
> 
> Yes, they are brief enough to be memorized.  I just wonder whether
> they are coherent enough to make sense or cause a reaction of "Huh?
> Why not also...?"  Because the place that reaction would be most
> likely to cause damage is here, in three years, when this discussion
> has been forgotten enough for someone to start a "Adding
> functionality to ~~" thread.

I feel pretty confident that they make sense and that anybody could "just know"
how a subroutine, regex, or undef would match something.  Overloaded objects
are "obvious or not" on a case by case basis.

As for the "why not also," having gone through so many posts about it, I would
be sure to write a comprehensive bit of Pod on the matter. :-)

> >When has three behaviors: numeric literal, string literal, and
> >"anything else," where the final case is taken as the rhs to a
> >smartmatch, with the topic as the lhs.
> 
> That last case is mooted for abolition though, right?

No.  The exhaustive set of "when" behaviors would be:

  given ($input) {
    when (1)   { ... } # if $input == 1
    when ('x') { ... } # if $input eq 'x'
    when ($x)  { ... } # if $input ~~ $x
  }

And further demonstrated:

  given ($input) {
    when (undef)  { ... } # if $input ~~ undef
    when ($x + 2) { ... } # if $input ~~ ($x + 2)
    when ($_ > 1) { ... } # if $input ~~ ($_ > 1)
  }

Under FC's proposal, which would eliminate ~~ entirely:

  given ($input) {
    when (1)   { ... } # if $input == 1
    when ('x') { ... } # if $input eq 'x'
    when ($x)  { ... } # if $x
    when (undef)  { ... } # if undef
    when ($x + 2) { ... } # if ($x+2)
    when ($_ > 1) { ... } # if ($_ > 1)
  }

-- 
rjbs

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