top | item 32496168

Show HN: Match(it): A C++17 pattern-matching library with lots of good stuffs

85 points| amazing42 | 3 years ago |github.com

A lightweight single-header pattern-matching library for C++17 with macro-free APIs.

Try it at https://godbolt.org/z/8YMr8Kz8j

44 comments

order

dymk|3 years ago

What a neat concept. It never ceases to amaze me what people can arm-bar C++ into doing through typesystem, metaprogramming, and operator overloading shenanigans.

I hope I never see this in a production codebase, though!

On a kind of related note, I want to see an alternate history where C++ had support for Rust-ish proc macros, or Racket-ish macros. What would that language even look like? There'd probably be no need to hack existing C++ language semantics to add new features, you'd "just" generate the code that the meta-language lowers to.

Longhanks|3 years ago

> I hope I never see this in a production codebase, though!

Why? Looks completely readable, easy to understand to me.

Do you also hope to never see the STL in production? Because internally, that thing is high level unreadable C++.

gpderetta|3 years ago

That alternative history is currently being implemented by the Circle compiler.

olvy0|3 years ago

Interesting - in the godbolt.org link, looks like both GCC and Clang optimize the code to run at compile time, so the resulting function is just "mov eax, 24".

But MSVC latest instead generates the full runtime code and function call.

phoe-krk|3 years ago

Strangely, clang 13+ seems to have regressed - it emits runtime code as well, whereas clang 12 has just "mov eax, 24".

Should this be reported anywhere?

fooker|3 years ago

Wow, I didn't know you could #include a remote file in compiler explorer.

amazing42|3 years ago

Yeah, that is super cool feature of compiler explorer compared to other online compiler.

hkalbasi|3 years ago

Not super useful without ADTs, but nice! I hope someday ADT and pattern matching find their way to the c++ language.

amazing42|3 years ago

Sadly lvariant did not get into C++ language. The library supports pattern matching against std::variant/std::any and class inheritance as a replacement.

jokoon|3 years ago

I hope this will become part of C++ one day.

Although if the C++ committee manages to add this without deprecating other things, I would be impressed.

corysama|3 years ago

There has been a proposal to add pattern matching to C++ for nearly a decade now https://www.stroustrup.com/OpenPatternMatching.pdf Shame it never got in. With language support for matching, sum types and product types it would be a completely different language.

synergy20|3 years ago

Thought it's about regex matching for switch-case, turns out it's very different, interesting though, is this an idea borrowed from Rust? Not sure if I'm going to use it or not.

klyrs|3 years ago

Pattern matching has quite a long history[1]; it's been around in some form since 1957. It's been enjoying a bit of a renaissance lately; I suspect that's a result of Haskell's popularity but I don't really know.

[1] https://en.wikipedia.org/wiki/Pattern_matching

fouronnes3|3 years ago

Very nice looking. Can you pattern match std::variant?

amazing42|3 years ago

Yeah. That is supported.

bhedgeoser|3 years ago

Rust version:

const fn factorial(n: u128) -> u128 { match n { 0 => 1, _ => n * factorial(n-1) } }

fn main() { dbg!(factorial(20)); }

amazing42|3 years ago

The godbolt link is only a simple sample.

Rust does not support view pattern (called in Haskell) or app pattern (called in Racket). And that has been implemented in this library.

rowanG077|3 years ago

Please, please, please don't make fetching a library part of your cmake include process.

amazing42|3 years ago

Thanks for bringing this up. Now you can use cmake find_package with it.