develooper Front page | perl.perl5.porters | Postings from June 2022

disabling smartmatch and when()?

Thread Next
Dave Mitchell
June 20, 2022 13:45
disabling smartmatch and when()?
Message ID:

A while back, we collectively agreed that the smartmatch operator
and the when() keyword (which sometimes uses smartmatch under the hood),
had fundamental design flaws, and we retrospectively made
~~/given/when/break experimental in 5.18.0 (nine years ago!).

Since then we have failed to reach a consensus as to how these should be
fixed, or indeed whether they should removed altogether. This is an
unhappy state of affairs.

I propose that right now (so appearing in 5.38.0), we disable C<~~> and
when(), and possibly C<given> and C<break> too. Any attempt to use them
will give a meaningful compile-time error (as opposed to a plain syntax

This will provide two positive outcomes. First, it will force users to
stop using it. Second, it provides an air-gap for if and when we introduce
the new and improved smart-match operator - i.e. rather the behaviour just
changing in one release, there is a clear demarcation between the old and
new behaviour, with people who test their new code on old releases getting
a clear signal, in that their code won't even compile on 5.38 ..5.44 say.

Important note: please, PLEASE, don't turn this thread into yet another
discussion on how to revamp smartmatch: if you want to discuss that,
start a new thread (and read all the old threads about it first). This
thread is purely to discuss whether and how to disable smartmatch until
something better comes along (which could in theory be included in 5.38 if
the other hypothetical thread bears fruit).

So I think that at a minimum, the use of C<~~> and <when() should give
meaningful compile-time errors. The main issue is whether we should also
disable C<given> and C<break> too. Also, whether 'C<use feature 'switch'>
should be an error or warning too.

Any opinions?

Lastly, here's a handy summary history of what happened to smartmatch and
the switch feature in various perl releases.



C<~~> and the given/when/break keywords were added.
The new keywords need C<use feature 'switch'>, while C<~~> doesn't.

<given($foo) { ...}> is like C<for($foo) {...}>, except that it assigned
C<$foo> to a localised  C<$_> rather than aliasing it: so modifying C<$_>
within the block didn't change C<$foo>. (If a lexical C<$_> is in scope,
then that is the variable which was assigned to.)

C<when ($foo)> is interpreted as C<when($ ~~ $foo)>, with some exceptions
for common cases where it acts directly as a boolean, e.g.
C<when(defined($foo))>, C<when(/foo/)> etc.

The arguments to C<~~> were treated as commutative, i.e. C<$a ~~ $b>
and C<$b ~~ $a> gave the same result.


5.10.1 / 5.12.0

Major changes were made to smartmatch; in particular, it is no longer
commutative; instead, the action is based largely on the type of the RHS.
For example this matches in 5.10.0 but not in 5.10.1:

    /foo/ ~~ "foo"

More cases were added where when()'s argument is treated as a boolean,
rather than as the argument to a smartmatch:

    when (/^=begin/ .. /^=end/) { ... }
    when ((expr1 // expr2) { ... }



-DM smartmatch resolution tracing added.



Bug fix: C<~~> now correctly handles the precedence of Any~~Object, and is
not tricked by an overloaded object on the left-hand side.

Pod for smartmatch fixed and moved to perlop



The following all became retrospectively experimental:
    lexical $_ 

when() changed to be like for() in that it now aliases C<$_> to the
value rather than copying.



lexical $_ is removed.



During development, zefram merged a major 'simplify smartmatch' branch,
but this was quickly reverted as it was decided that a consensus hadn't
been reached.

"Emacs isn't a bad OS once you get used to it.
It just lacks a decent editor."

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