Hello, it seems I missed P2688! 
This definitely changes some things and must be taken into account.

On Thu, Dec 1, 2022 at 5:24 AM Barry Revzin via Std-Proposals <std-proposals@lists.isocpp.org> wrote:


On Tue, Nov 29, 2022 at 1:04 PM Jason McKesson via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Tue, Nov 29, 2022 at 12:12 PM Михаил Найденов via Std-Proposals
<std-proposals@lists.isocpp.org> wrote:
>
> Hello,
> This is a soft followup of https://lists.isocpp.org/std-proposals/2022/10/4787.php
> which advertised limiting the scope of PM.
>
> In the attached proposal draft a new PM is presented, one with a limited scope and heavy reuse of syntax (no new syntax actually).

Your proposal starts off with this sentence:

> Current proposal aims to be conservative in its goals in order to make it in C++26.

But the importance of that goal presupposes that the current proposals
can't make C++26. I haven't been following anything in the pattern
matching domain much. Is there some reason to believe that syntax is
the primary thing that is holding these proposals back? And I mean
more than just the fact that they introduce new keywords which could
in theory break code. If that's a show-stopping problem, then it will
prevent these proposals from making it into *any* version of C++26.

So what's the evidence that these proposals are stalling out?

I have been following pattern matching pretty closely over the years, so let me chime in. While the design at the moment (the P1371 one, from Michael Park, David Sankel, et. al) still has some subtle and annoying issues to work out (for instance, with exhaustiveness), on the whole it's doing quite well, and I'm not sure that this paper really helps (it also repeatedly references some other PXXXX paper for motivation?).
 
To pick just the first proposal: pattern matching is not a switch, it has different semantics and it is a different feature. Reusing the switch keywords and the syntax around case labels and default, with different semantics, would be a mistake.

Many languages extend switch to account for PM, C# comes to mind, but there are others. I don't see how it is a "different feature", outside not being an expression. Even the fallthrough is just an OR applied to the patterns by default (for better or worse).
Considering, we do want the switch behaviour in some case, it makes sense to reuse the switch building blocks instead of inventing alien new syntax (!{}, noreturn{}) for something that is 95% the same and we can get the rest 5% via other means like attributes [[noreturn]].
 
That's why the existing proposals don't do that. The proposal for handling identifiers vs expressions is not even something I understand - why do I have to write "n= __", and why does "&n= __" affect the mutability? The analogy with lambdas doesn't make much sense to me - this is a very different kind of thing. In the latest suggestion in P2688, we have "x" matching an existing variable vs "let x" introducing a binding, you're suggesting "x" and "x="? Having a postfix differentiator seems like a bad idea. Note that all the patterns in P1371 are prefix and nest from left-to-right, which I think is fairly essential for comprehension (for humans).

Identifiers are a massive problem one way or another. One major problem w/ current solutions is the introduction of a language-inside-the-language by using let or by using is / as, for patterns alone and being part of the language.
This is in contrast to other languages and looks bad. 
This proposal gets around that by reusing existing syntax, most of which is already used in lambdas.

The lambda analogy is important because it is the only place in the language where we introduce identifiers w/o mentioning the type (w/o a hint). Considering, this is exactly what is needed for PM as well, it makes sense to reuse it here as well.

Identifiers also play a major role on how matching by type looks. By having all use of variable identifiers covered by dedicated syntax, we open the possibility to use "naked" ids for types; w/o requiring special syntax like <> and as/is.

Lastly, even in the revised P2688, I still dont see how one can bind an arbitrary pattern, short of using helper functions like `at`:

 <Point> (at!) [let p, let[x, y]]
 
Compared to the proposed

Point p=[x=, y=]

I doubt the parse-ahead will be an issue as it is very short, stopping right away if the char is not space or =. The patterns themselves are always "prefix", with the result being to the right (pattern result)


Ultimately though, I really don't think that what pattern matching needs to succeed are more designs. I think P1371 is an excellent paper, it has wide support, and Michael has some very good suggestions in P2688 that resolve a few issues and also address what to me was one of P1371's shortcomings - the ability to use patterns in a few more important contexts. 

I don't consider this paper an alternative design and I tried to make use of what is already agreed upon.
In fact, some of the P2688 is in the paper as well, like having simple identifiers be used for comparison to existing variables by default, and not doing introduction, like most PM systems do. 
Also, the use of ? for optionals, in place of *, was suggested here and is also in the P2688. 

I do think, we must polish (and simplify) the hell out of  P1371 and that is why I also propose the limit the scope for the initial release (the  https://lists.isocpp.org/std-proposals/2022/10/4787.php paper)
I just don't think some of the advanced stuff is desirable the way it looks (extractors and matchers) and could easily be an iteration. 

Using `switch` is also one such simplification. Even the newly proposed postscript `match` will have parsing problems when multiple arguments are involved.

More interestingly, by updating `switch` we can re-use another already reserved  keyword - case. This would allow us to use patterns outside `switch`, more or less naturally

// if(opt match let ?x)    // 2688
// if(auto *x is _ = opt)  // as is

if(case(?x=) = opt)   // future direction

// if(expr match [0, let foo])    // 2688

if(case [0, foo=] = expr)  // future direction

// or, if we want them postscript

if(opt case ?x=)        // future direction
if(expr case [0, foo=]) // future direction

In any case, I will have to update the paper because I was not aware of 2688.
Thanks for the feedback 


Barry
--
Std-Proposals mailing list
Std-Proposals@lists.isocpp.org
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals