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

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

Thread Previous | Thread Next
Damian Conway
August 24, 2012 16:54
Re: fixing smartmatch just hard enough (and when, too)
Message ID:
Hugo wrote:

> This is the bit I'm really not convinced about. I feel there is
> a significant difference between the language that has this:
>   my($value) = ($line =~ /value=(\d+)/);  # yay, we got a number
> and the one that has this:
>   my($value) = ($line =~ /value=(\d+)/);  # yay, we got a number
>   $value += 0;  # RT#314159: oops, *now* we got a number
> The first of these expresses much that to me seems intrinsic to what
> perl is. The second seems to throw out the DWIM with the bathwater.

No-one (I hope!) is proposing that Perl's auto-coercions be eliminated,
or modified in any way. Perish the thought!

All I was saying was that smartmatching works by knowing what type the
RHS argument is (a sub ref, a regex ref, a number, a string, an object)
and then picking the appropriate comparison operator on that basis.

The problem with that is that Perl itself doesn't *always* know what the
RHS argument is. Or, rather, it doesn't remember what the RHS is in a
single specific case: when the RHS is a simple variable that has
previously been autocoerced.

As I'm certain Hugo fully understands (but others may not), that's simply
because, during an auto-coercion, Perl caches the conversion for
efficiency. So when smartmatch looks inside a post-autocoerced variable
it no longer sees a pure IV, UV, NV (in the case of a stored number) or
a pure PV (in the case of a stored string), but rather sees the original
storage replaced by a "dualvar" PVIV, PVUV, or PVNV. Which means the
smartmatching mechanism can no longer tell what kind of value the
original value was.

If the original caching mechanism had been implemented so that
autocoercions installed (say) a PVplusIV (for a string with cached integer
autocoercion) or an IVplusPV (for an integer with cached string
autocoercion), then we would have no problem. Smartmatch would be able
to tell what was "really" in the variable, and what was merely a cached
optimization for repeated autocoercions.

(And, BTW, if that original type information were retained, the weird
history-dependent behaviour of the bitwise operators could likewise be fixed.)

In other words, the current implementation of variables loses type
information as a side-effect of autocoercion. But smartmatch needs that
type information to DWIM in the one special case of a variable as its RHS.

The various positions on this issue seem to be:

    Option 1: In that one case, as smartmatching cannot DWIM, it should
              fail loudly (and we should look at having vars somehow
              preserve knowledge about what type they were originally
              assigned, so that this one problematic case will eventually
              go away).

    Option 2. In that one case, smartmatching should fall back to
              eq-matching, since that's somehow more general.

    Option 4. That one case indicates smartmatching is inherently
              incompatible with Perl and should be removed entirely.

Personally, I still believe Option 1 is the right answer, and that
smartmatching is not some terrible threat to the intrinsic nature of
Perl, but rather an important missing piece of its toolkit. :-)

Perl has plenty of values that DWIM for operators which SWIM;
smartmatching adds an operator that DWIMs for values which SWIM.

And that's not only's also very Perlish. Just in a new way.


Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About