Front page | perl.perl5.porters |
Postings from August 2017
Re: Revisiting smart match
From: Sawyer X
August 2, 2017 07:58
Re: Revisiting smart match
Message ID: email@example.com
This is just my initial response.
On 08/01/2017 06:48 PM, Zefram wrote:
> Sawyer X wrote:
>> * LHS overloading breaks a faulty autodie API
> My recollection is that it's *removing* LHS overloading that would break
> a promoted API.
Yes, indeed. This is what I had meant. The word "removal" is missing to
complete "LHS overloading removal." Sorry for the confusion.
> Regardless, LHS overloading needs to die, because its
> behaviour is too surprising: it breaks the usability of any RHS type
> against which LHS overloading could apply, but its existence doesn't
> actually dissuade people from using such RHS types, so it just creates
> bugs. The type of match to perform needs to be fully determined by
> the RHS.
I cannot see a reason to keep it. However, since I rarely know the
entire picture, I'm wondering if anyone has a valid reason.
> Going even further, for comprehensibility we want the matching rules to
> be fully disjoint. It's no good having one rule for numbers on the RHS
> and another for strings, because too many things are both. It's even
> problematic to have a rule for coderefs on the RHS, because a sub might
> be blessed into a class with smartmatch overloading. The rule could
> be restricted to references to unblessed subs, but even that's a bit
> confusing, as it'll lead to people assuming that any sub can be used as
> a smartmatch object with semantics involving calling it. And then what
> about objects with a calling overload? And so on.
I generally agree. When it comes to strings or numbers it becomes
tricky, see below.
> Almost every proposed matching rule runs into some form of the above
> confusion, because of Perl's pervasive use of "what type do you *want*
> me to be?" semantics. This is why the list of matching rules needs to
> be very short.
> So, my suggestion for the ruleset:
> 0: RHS overloading
> 1: undef on the RHS: !defined($lhs)
My instinct would have been throwing a warning under "use warnings
'undef'", since comparing to undef is often a mistake, not realizing the
variable did not receive a value. I can understand comparing directly to
"undef" though, but that opens the door to inconsistencies to the user:
"$new_value = undef; $value ~~ $new_value;" warning while "$value ~~
undef" not warning.
I don't have a strong opinion here though.
> 2 (optional): plain string (defined, non-glob, non-regexp, non-ref
> scalar) on the RHS: $lhs eq $rhs
This is tricky. "eq" feels more common but I cannot see it as
necessarily less arbitrary than ==.
> 3: anything else: croak "invalid smartmatcher"
> The Regexp class should overload smartmatch to perform a regexp match.
> MooseX::Types metaobjects should overload smartmatch to perform a type
> membership test.
> Also, there's a distinction to be made between the runtime semantics
> of smartmatch and the parsing of the operator. The above rules are
> runtime ones. Currently, the smartmatch operator modifies things a
> bit: for example, an array (as in "@foo ~~ $bar" or "$foo ~~ @bar")
> gets implicitly enreferenced. That's not a great rule. I think it
> would be better for ~~ to just apply scalar context to both operands.
Question is, what does it break?
> There's further complication about the when() construct, which is
> inconsistent in how it uses the result of evaluating the expression
> inside the parens. Sometimes it treats the result as a truth value,
> directly governing whether to execute its block, and sometimes it treats
> the result as a smartmatcher, against which to implicitly match $_.
> The decision is based on the top-level operator of the expression.
> This is just confusing and should be ditched.
I haven't though of this problem.
> If you want smartmatching
> with no extra typing, change the parens: when() can treat the expression
> result as a truth value while when treats it as a smartmatcher.
> We could add if while we're at it.
Hmm... how much would that confuse people? Probably quite a bit. Feels