develooper Front page | perl.perl5.porters | Postings from November 2017

Re: Revisiting smart match

Thread Previous | Thread Next
From:
Ricardo Signes
Date:
November 27, 2017 16:04
Subject:
Re: Revisiting smart match
Message ID:
20171127160416.GB1688@debian
* Zefram <zefram@fysh.org> [2017-11-24T08:45:07]
> Apparently people wanted non-smartmatch conditions enough to make "when"
> attempt to guess what they meant.

I don't think we're doing ourselves any favors by looking to the original
v5.10.0 design of smartmatch/given/when as something built based on what people
would use in practice.

My feelings about given/when have never been very strong.  I've generally been
much more interested in smartmatch itself.  That said, I think that this is one
(maybe -the- one) place I'd chime in on the given/when changes proposed.

I've thought of the rhs of a smart match as best being a stand-in for a
predicate function.  given/when is explicitly performing tests at each branch,
so I'm not sure we're doing the right thing to just evaluate a when's
condition as a boolean expression.  I think it comes down to this:

  Are people better served by always saying they're using ~~ when they use it,
  or by being encouraged to use specific matchers?

The original design was trying to do a third option: we should intuit what the
user meant through a set of rules and exceptions.  I think we probably all
agree that it didn't work and can't be made to usefully work.

It does drag attention back to the exemplar of the problem:

  # fig 0
  given ($input) {
    when ("string") { die "A" }
    when (90210)    { die "B" }
    when ($matcher) { die "C" }
  }

The behavior under the current proposal (all three always would match, so only
the first runs) is clearly wrong.  Let's call this programmer error, which it
would be, but it's not great.

Is it better for the user to write:

  # fig 1
  given ($input) {
    when ($_ eq "string") { die "A" }
    when ($_ == 90210)    { die "B" }
    when ($_ ~~ $matcher) { die "C" }
  }

...or...

  # fig 2
  given ($input) {
    when (mstr("string")) { die "A" }
    when (mnum(90210))    { die "B" }
    when ($matcher)       { die "C" }
  }

...or, to go full Chrysostomos...

  # fig 3
  given ($input) {
    when { $_ eq "string" } { die "A" }
    when { $_ == 90210    } { die "B" }
    when ($matcher)         { die "C" }
  }

Three, here, is a special form of two:  you could just as easily use mstr() to
produce an eq-based matcher, but if you don't want to make a custom matcher,
you can just write an arbitrary expression for either laziness or speed.

> So there's good cause for "when" to support ordinary truth-value
> conditions.  Given that it does support that, there's no actual need
> for shorter syntax for smartmatching; that's at most a nice-to-have.

I agree with the fact that we can get away without the shorter syntax.  I just
want to say that if we say, "Okay, everybody, at long last smartmatch and given
and when are usable, and this is how you use them," then we're setting the
precedent for how people are going to expect to read and write this code, and
also how they're going to think about what a "when" condition *is*,
conceptually.

I think the version you provide is okay.  I don't think it's what I'd pick, but
I don't think it's bad.  Mostly, I wanted to make sure I said something here so
that later, if I was annoyed, I would know I'd sung out at the time so that the
thing could be considered.

Thanks for your work on this long-suffering part of the language!

-- 
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