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

Re: Revisiting smart match

Thread Previous | Thread Next
From:
Sawyer X
Date:
August 2, 2017 07:58
Subject:
Re: Revisiting smart match
Message ID:
138882d4-e157-e9da-a4cf-eff8be207063@gmail.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
too confusing.

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