develooper Front page | perl.perl5.porters | Postings from September 2015

Re: smartmatch needs your eyes

Thread Previous | Thread Next
From:
Zefram
Date:
September 24, 2015 12:07
Subject:
Re: smartmatch needs your eyes
Message ID:
20150924120644.GA32274@fysh.org
Those pondering smartmatch in Perl 5 may be interested in what I have
learned about smartmatch in Perl 6, from my recent exploration of
that language.  Of course, Perl 6 distinguishes numbers and strings
reasonably clearly, so there's no difficulty having separate matching
rules for them.  But look at some of the other cases.  At first look
it seems that one of the most useful applications of smartmatch is for
testing class membership and subclassing (which due to the bizarre type
system are kind of the same thing):

> 3 ~~ Int
True
> "3" ~~ Int
False
> Int ~~ Numeric
True
> Str ~~ Numeric
False
> Mu ~~ Numeric
False

But ~~$class actually doesn't reliably mean .isa($class).  On some kinds
of value it's just not defined:

> Mu.new ~~ Numeric
X::Multi::NoMatch exception produced no message
  in block <unit> at <unknown file>:1

Technically, for defined objects, $obj~~$class only applies of $obj is
of the Any class, which is the default base class, but a few important
things lie outside it, such as Mu.  Another thing lying outside it is
the Junction class, for objects representing multiple values, and they
automatically distribute over ~~ from the lhs.  Unlike their behaviour
on ordinary method calls:

> ("3"|3) ~~ Numeric
any(False, True)
> ("3"|3).isa(Numeric)
False

So in Perl 6, ~~ can't be relied upon to yield an actual truth value.
But there's an exception to that auto-distribution, for the Junction
class itself.  Just Junction, not any other non-Any classes, not even
the ultimate base class Mu:

> ("3"|3) ~~ Junction
True
> ("3"|3) ~~ Mu
any(True, True)

To be fair, there are some places where an Any type constraint is
implicitly applied, so the Any~~$class behaviour could be relied upon
quite often, provided that one checks that such a type constraint really
does apply to the situation.  But for code that needs to handle any
value at all, ~~$class is an attractive nuisance.  On the whole, rather
than repeatedly check that the type constraints justify it, I'd prefer
to just write .isa($class) everywhere that I want to do a class check.

So my tentative conclusion is that smartmatch in Perl 6 is too complicated
to use comfortably.  It can sometimes be used correctly, but the effort
of doing so exceeds the convenience gained by it.

Which sounds rather like the situation we got into in Perl 5.  It seems
that the Perl 6 folks could benefit from some of our wisdom.  One cannot
truly appreciate smartmatch until one has seen it in its original Perl
5 context.

-zefram

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