7 ms·
Show HN: Match(it): A C++17 pattern-matching library with lots of good stuffs
A lightweight single-header pattern-matching library for C++17 with macro-free APIs.
Try it at https://godbolt.org/z/8YMr8Kz8j https://godbolt.org/z/8YMr8Kz8j
- synergy20 4y agoThought 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 4y agoPattern 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 https://en.wikipedia.org/wiki/Pattern_matching
- synergy20 4y agoNot a CS major, thanks for the link!
- dymk 4y agoWhat 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 4y 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++.
- dymk 4y agoI say that because I would hate to be the person that has to ramp up a junior engineer on a project that uses a library like this. I've written my fair share of code like this, and while you and I might grok it (and probably have a fun time figuring out how it works in the process), most people will hit a brick wall the moment they have to debug the 1000 line error that Clang or GCC will give you when there's a type error. This is the kind of thing that belongs in language-feature land (so you get tooling support, reasonable compiler errors, etc), not library-land.
- Longhanks 4y ago> This is the kind of thing that belongs in language-feature land (so you get tooling support, reasonable compiler errors, etc), not library-land. Again bringing up my STL example: This is just not how C++ runs. I’ve seen my fair share of std::__v1::basic_string<char, char_traits<char>, DefaultAllocator<>> errors. Some would argue a string type should be language-level, and they might be right, but the committee disagrees.
- dymk 4y agoRight, well, I think we can agree the committee makes some weird calls sometimes with respect to language design. We only got concepts and coroutines (relatively) recently, and they're still kind of warty. `std::range` is beautiful and I'd still only use it sparingly. The C++ language, in my experience, is a language best served as a safe subset with "magic" and advanced features eschewed as much as possible. The C++ STL has a lot of templated code in it (obviously), but at least the amount of weird tricks, such as template recursion, is fairly small (ignoring newer additions like `std::range`). And even then, compiler errors can make an experienced engineer's eyes water. At least you can paste most errors into Google and find a relevant StackOverflow post about how to fix it. Involving a library like this, though - best of luck, the engineer is on their own.
- gpderetta 4y agoThat alternative history is currently being implemented by the Circle compiler.
- jokoon 4y agoI 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 4y agoThere has been a proposal to add pattern matching to C++ for nearly a decade now https://www.stroustrup.com/OpenPatternMatching.pdf 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.
- UncleOxidant 4y agoWouldn't it be very similar to Rust? (or OCaml - but without the automatic memory management)
- amazing42 4y agoActually this library (match(it)) is more similar to Racket. You can see there are lots of patterns borrowed from Racket pattern matching, say app pattern and ooo pattern.
- pclmulqdq 4y agoThe regex library in the STL was quite a lesson for the C++ maintainers. They will probably not allow anything similar any time soon.
- tialaramex 4y agoAlthough the phrase "pattern matching" is involved these are completely different features. Also, unlike for regular expressions what you actually want here is typically a language feature, even if a bunch of the lifting is done in your standard library. In particular you probably want a keyword (or in several C++ pattern matching proposals, more than one) and new behaviour not just a few functions and constants. You could think of this as a bit like "switch" but on the other hand if your insight into switch is that it's basically a computed go-to wearing fancy dress then no, not that, the thing ordinary people use switch for.
- hkalbasi 4y agoNot super useful without ADTs, but nice! I hope someday ADT and pattern matching find their way to the c++ language.
- amazing42 4y agoSadly lvariant did not get into C++ language. The library supports pattern matching against std::variant/std::any and class inheritance as a replacement.
- deleted 4y ago[deleted]
- olvy0 4y agoInteresting - 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 4y agoStrangely, 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?
- colatkinson 4y agoI wonder if it hit some max execution time heuristic or something like that. As a quick test, I added a static_assert() that depends on the returned value, which seems to force complete evaluation to happen at compile time. With that, all 3 compilers generate the expected single-instruction implementation: https://godbolt.org/z/onMannzM5 https://godbolt.org/z/onMannzM5
- fooker 4y agoWow, I didn't know you could #include a remote file in compiler explorer.
- amazing42 4y agoYeah, that is super cool feature of compiler explorer compared to other online compiler.
- fouronnes3 4y agoVery nice looking. Can you pattern match std::variant?
- amazing42 4y agoYeah. That is supported.
- bhedgeoser 4y agoRust version: const fn factorial(n: u128) -> u128 { match n { 0 => 1, _ => n * factorial(n-1) } } fn main() { dbg!(factorial(20)); }
- amazing42 4y agoThe 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.
- deleted 4y ago[deleted]
- rowanG077 4y agoPlease, please, please don't make fetching a library part of your cmake include process.