develooper Front page | perl.perl5.porters | Postings from March 2020

Thoughts on how to provide a dumber version of smart-match

Thread Next
From:
Paul "LeoNerd" Evans
Date:
March 5, 2020 18:03
Subject:
Thoughts on how to provide a dumber version of smart-match
Message ID:
20200305180326.15884572@shy.leonerd.org.uk
[TL;DR - how to progress a new major syntax feature]

Oh boy, it's everyone's favourite (mis)feature - smartmatch. I have
some thoughts.

The CPAN module Switch::Plain, by (the currently-AWOL) MAUKE, provides
two simple and nice control-flow statements `sswitch` and `nswitch`,
whose semantics are hopefully obvious enough from the simple examples:

  sswitch($name) {
    case "Bob": { ... }
    case "Frank": { ... }
  }

  nswitch($val) {
    case 5: { ... }
    case 10: { ... }
  }

  -- https://metacpan.org/pod/Switch::Plain

As compared the disaster that remains smartmatch and given/when, these
seem nicely simple and also easy to read, reason about and implement.
The clarity and simplicity of them comes primarily from the fact that
the opening keyword specifies whether matching shall be done as strings
(for `sswitch`) or numbers (for `nswitch`). There is no guessing about
such weird cases as

  case "1.0"

This got me thinking...

The trouble with smartmatch is that it is expected to guess the
comparison semantics just by looking at the values at run-time. If only
the programmer could explicitly state in source code which operator
would be in effect, then things would be much nicer.

I'm not 100% happy with the syntax yet, but what I have in mind is
something like the following:

  use feature 'match';

  match ($name) on eq {
    case "Bob": { ... }
    case "Frank": { ... }
  }

  match ($val) on == {
    case 5: { ... }
    case 10: { ... }
  }

We can now also use some other infix predicate operators here, such as

  match ($str) on =~ {
    case m/^A pattern/: { ... }
    case m/^Another regexp/: { ... }
  }

These could be seen as "trivial" rewrites of the common if/elsif/...
chaining, with a `default` case at the end becoming an `else`. In fact,
an initial implementation could do exactly that. It would need to
allocate a pad temporary for the controlling expression, in order to
ensure side-effects of evaluation happen exactly once, but otherwise
the rewrite and semantics here should be quite obvious.

This syntax idea is also the main motivation for why I wanted to add
`isa` as a real infix operator - this now becomes as easy:

  match ($thing) on isa {
    case A::Derived::Class { ... }
    case A::Different::Class { ... }
    case Base::Class { ... }
  }

As I said above though - I'm not 100% happy with the exact syntax, but
that's not what I want to discuss in this thread. I will *NOT* be
entering into discussions of that level of detail in this email thread
at this time. That will come later...

Instead, this email thread is a meta-question on how I should proceed
to discuss and develop this idea. I have considered writing this as a
CPAN module named, probably, Syntax::Keyword::Match, but so far I have
resisted primarily because I already have now 4 other keyword modules
that are trying to add major new "probably should be core one day"
features and I am loathe to add a fifth quite yet:

  * Syntax::Keyword::Try
  * Syntax::Keyword::Dynamically
  * Future::AsyncAwait
  * Object::Pad

This is for two reasons:

  1) Already I have some three-way intersections between possibly three
     different syntax modules all adding semantics, and writing tests
     between them all to ensure things work as expected is getting
     tricky.

  2) I don't want to maintain an ever-growing set of "fancy perl"
     syntax modules only accessible to XS-capable users who install
     from CPAN. I want some of this in core.

I would therefore instead like to work out how we can progress and
experiment on this idea - a (bounded!) discussion on the syntax,
followed by some real concrete implementation and actual battle-testing
for real in some real code - entirely as core syntax. This is as much
an experiment for me as it is for everyone else; to see if I can add
this kind of thing in that manner. 

What can people suggest as a way forward on project-managing this?

-- 
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/

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