Comment by rfgplk

1 day ago

I've developed a style that I legitimately call Heterodox C++ (mainly due to the popularity of Orthodox C++), it is effectively a purely functional & metaprogramming heavy style of C++. Quite the opposite of this, not everyones cup of tea, and it won't fit into every codebase but it is incredibly powerful. The template metaprogramming C++ offers is the most powerful of any imperative language, and (subjective opinion) is second only to Lisp, but few people make use of it. With some of C++26 features you can almost even replicate most of Rusts safety features in pure C++ (via function tagging + reflection)

> The template metaprogramming C++ offers is the most powerful of any imperative language

I'm curious what languages you're comparing to here. Feels like it's only slightly more expressive than pure generics, but I admittedly haven't done much template metaprogramming myself. How does it compare to, say, Zig's comptime?

  • I’ll preface this by saying I mostly use C++ and have just basic experience in Zig, but as far as I understand comptime is much more procedural than C++ templates which are more declarative. With templates you get quite good pattern matching through the compiler’s machinery, for instance through template specialisation, while Zig, in my understanding, requires these to be handled manually in code. Personally, comptime feels like constexpr/consteval in C++ but with the ability to interact with the type system itself. The significant downside of C++ metaprogramming is that sometimes many features interact weakly and feel very much tacked on top of each other while Zig’s looks more cohesive. Perhaps someone with more Zig experience can weigh in.

    • > The significant downside of C++ metaprogramming is that sometimes many features interact weakly and feel very much tacked on top of each other while Zig’s looks more cohesive.

      spot on, in my experience. nothing in zig triggers my lite OCD.

Yuck. I'm sure your compile times suck and code is not readable (my subjective opinion as well). There's nothing worse than a ten-mile long lambda in C++. To each there own, however. C++ is four languages in one after all. :)

Templates are really amazing, once you learn the patterns there's basically a template version and a runtime version of things (policy types, etc.). All of that is great.

Legibility and understanding are in my opinion the most important aspect of any programming language, so Orthodox C++ is superior for maintainable code.

The problem with metaprogramming-heavy C++ codebases is always compilation times and obtuse error messages...

Template metaprogramming is sometimes very useful to get around C++'s language restrictions, but I tend to use it sparingly.

  • > obtuse error messages

    With concepts and constexpr-if and consteval it's increasingly less of a problem

  • I've been using C++ for about 20 years and I've yet to see these scary template error messages people always complain about. Yeah, they're long, but they contain all the information you need to fix the issue, which is damn near always at the deepest point in the call stack that you still control.

C++ template metaprogramming is in some ways more powerful than Common Lisp macros, because it works at the type level: you can generate new types and dispatch into separate implementations by type. In contrast, Common Lisp type declarations are not available at macro expansion time unless you implement a full source-to-source translator in macros.