10 comments

  • dymk 589 days 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 589 days 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 589 days ago
        I 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 589 days 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 589 days ago
            Right, 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.

            • UncleMeat 588 days ago
              I wouldn't even say "kind of warty." I think that Titus Winters was spot on a few years ago that he predicted that concepts are unrefactorable in sufficiently large codebases.
        • spkm 589 days ago
          It's my impression that people tend to underestimate "junior engineers" in the C++ world. I'm always impressed at conferences that there are so many young people holding presentations about really advanced topics.

          IMHO this "no junior will ever understand that" attitude comes mostly from older folks who learned C++ as C with classes and to whom even the STL is a work of the devil.

          • dymk 589 days ago
            Those people giving talks at conferences are the best of the best. 99.99% of people who write C++ have no interest in the arcane depths of the language, and would rather things "just work" over having a library that does something cool, but hard to debug when things go pear shaped.
            • Kranar 589 days ago
              Not all, the people giving talks are just people who happen to be interested and curious.

              This idea that only the best of the best are able to be curious and learn the nature of the tools they use at a very deep level is misguided and furthermore promotes a kind of anti-intellectualism.

              It's also a large part of why I think many developers get burned out, imagine working in a culture with other engineers where people are kind of pressured to only do boring work, stick to boring features, only write code in a very narrow manner that satisfies the lowest common denominator using the same old boilerplate over and over again and keep doing that for a decade or longer versus an engineering culture that values people being inquisitive, breaking out of their comfort zone, writing interesting libraries that abstract out common patterns and eliminates painful repetition, and who appreciate the inherent complexity of challenging problems instead of treating it like some arcane voodoo that only the select few can understand.

              It makes me so damn glad I run my own company.

        • Kranar 589 days ago
          It's interesting you mention junior engineers. My experience is the complete opposite, it's people who have been programming for many years who hate learning stuff like this and want to stick to their comfortable way of programming, whereas those who have programmed for fewer years enjoy learning about this and actually have fun doing so.

          Perhaps unsurprisingly the author of this library looks to have only a few years of experience themselves.

          • dymk 589 days ago
            It may be fun, yes, but I've found that experienced engineers aren't eschewing libraries like this because they hate fun and learning new things.

            Rather, it's because experience has taught them that the looks-cool slightly-magical stuff like this is hard to maintain once a codebase reaches a certain size, and maintainable code is boring and obvious.

        • kubb 589 days ago
          You think a junior can't understand how this library works and use it safely?
          • dymk 589 days ago
            In my experience, which was introducing engineers at Facebook to "fancy" C++ stuff, no.
            • pclmulqdq 589 days ago
              In my experience at G introducing modern C++, the most senior engineers had the biggest problems with it. Junior engineers hated the cryptic errors a lot more, though.
              • spkm 589 days ago
                TBF, everyone hates these cryptic errors :)
                • zen_1 589 days ago
                  I still remember (well, have screenshotted) this amazing error I encountered in my first exposure to C++. I was writing code for an assignment implementing my own vector container from scratch, and got "no suitable user-defined conversion from "CSXXX::vector::r_iterator" to "CSXXX::vector::r_iterator" exists".

                  Thank you GCC for telling me that I'm missing a copy/move constructor (can't remember which it was). Clear as mud as always. At least with the several pages of template instantiation errors you can scroll to the top where useful information can sometimes be found.

                • amazing42 588 days ago
                  That is true. Hopefully, adding more static_assert to the lib can fail the compiler early and give more instructive error message.
      • UncleMeat 588 days ago
        I'm mixed on this. On the one hand, I agree with you. Well isolated systems can be messy internally without causing trouble. On the other hand, error messages. STL has famously awful error messages. I do want to know what the compiler will spit out when I've got a syntax error or a type error when using one of these constructions. Because teaching people new to C++ what "you stuck a non-movable type in std::vector" error messages look like is not a trivial task.
      • formerly_proven 589 days ago
        > Do you also hope to never see the STL in production? Because internally, that thing is high level unreadable C++.

        SGI/HP STL isn't nearly as bad as modern implementations, though they all __share _Weird ____identifier names, mostly because of C/C++ identifier rules (_[A-Z] and anything with __ are reserved for the implementation, everything else might just be #define'd to rick-roll by whatever program is including you).

        • robbintt 589 days ago
          The Define problem seems like low hanging fruit for a linter/formatter.
    • gpderetta 589 days ago
      That alternative history is currently being implemented by the Circle compiler.
  • olvy0 589 days 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 589 days 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?

      • colatkinson 589 days ago
        I 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

  • fooker 589 days ago
    Wow, I didn't know you could #include a remote file in compiler explorer.
    • amazing42 588 days ago
      Yeah, that is super cool feature of compiler explorer compared to other online compiler.
  • hkalbasi 589 days ago
    Not super useful without ADTs, but nice! I hope someday ADT and pattern matching find their way to the c++ language.
    • amazing42 589 days 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 589 days 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 589 days 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.
      • pclmulqdq 589 days ago
        The regex library in the STL was quite a lesson for the C++ maintainers. They will probably not allow anything similar any time soon.
        • tialaramex 589 days ago
          Although 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.

      • UncleOxidant 589 days ago
        Wouldn't it be very similar to Rust? (or OCaml - but without the automatic memory management)
        • amazing42 589 days ago
          Actually 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.
  • synergy20 589 days 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 589 days 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

      • synergy20 589 days ago
        Not a CS major, thanks for the link!
  • fouronnes3 589 days ago
    Very nice looking. Can you pattern match std::variant?
    • amazing42 589 days ago
      Yeah. That is supported.
  • bhedgeoser 589 days ago
    Rust version:

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

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

    • amazing42 589 days 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 589 days ago
    Please, please, please don't make fetching a library part of your cmake include process.
    • amazing42 588 days ago
      Thanks for bringing this up. Now you can use cmake find_package with it.