4 ms·
C++ continues its long journey to making its template system an actual usable programming language.
by edflsafoiewq 2y ago
C++ continues its long journey to making its template system an actual usable programming language.
- kubb 2y agoIt's unfortunate that it had to happen by accident, and now new features are reluctantly being pushed through piecemeal. Imagine what it could have been if it was designed for programmability from the start.
- klipt 2y ago> Imagine what it could have been if it was designed for programmability from the start. Circle C++ compiler was designed for that: https://www.circle-lang.org/quickref.html https://www.circle-lang.org/quickref.html
- nxobject 2y agoI do think as well that some deeper scrutiny of semantics with the tools of PL research might have helped ahead of time - some of the most glaring warts like the perfect forwarding problem, or the need for reference collapsing, would have been avoided if the standards committee had taken a more rigorous approach to understanding semantics and their implications. I hope Zig’s comptime will get that level of scrutiny.
- kazinator 2y agoIt would have been a huge, sudden increment in complexity from absolute zero, causing it to be forever written off and ignored as an incomprehensible curiosity looking for a practical application. You have to suck people in with, "hey, you can write these two similar C-like functions under one definition, the correct one of which is automatically deduced and used".
- papichulo2023 2y agoI like to code in cpp as a hobby (computer vision stuff) but avoid template programing like the plague. The part of std is already scary stuff with 50 lines of errors for single typo.
- edflsafoiewq 2y agoIt's actually becoming easier as they make it a real programming language. The infamous template error messages are generally a result of two things: first, too many candidate functions because logic is cobbled together out of a nest of SFINAE overloads, which is ameliorated by moving the logic into normal code with if constexpr, etc; and second, type errors occurring deep in the call/expansion stack because unchecked values keep getting passed on just like in a dynamically typed language (which TMP basically is), which is ameliorated by moving the type checks higher up in the stack with concepts or static_assert.
- mb7733 2y ago> 50 lines of errors for single typo 50? That's it!? I work in a code base where a previous developer went nuts with overloads and I routinely get hundreds of lines of output for a single compiler error.
- npalli 2y ago>The part of std is already scary stuff with 50 lines of errors for single typo. IDE's make this less of a problem.
- dkersten 2y agoI personally quite like templates and constexpr. I don’t do anything too crazy with them, but I like being able to write code that will compile down to efficient code without runtime checks. I tried to write equally generic code in typescript recently and I had to make peace with the fact that I had to pay for either an indirect call through inheritance or a runtime conditional, where in C++ I could use template code and a constexpr if to choose the correct code path at compile time.
- rerdavies 2y agoI code cpp professionally. But I still dread template programming. Pretty much a guarantee that I'm going to end up spending an afternoon wading through horrifyingly inscrutable error messages.
- pjmlp 2y agoAfter C++17, template programming has become relatively easy. You can use enable_if and static_assert, alongside type traits to check the types, and give useful error messages. With C++20 you get concepts lite, which while not being as good as C++0x concepts, still simplify the code a lot, improve error messages, and remove the need for the classical tricks, when used alongside constexpr. No need to go crazy with them.
- pjmlp 2y agoWhich I actually find more approachable than how Rust deals with two macros systems, each with its own mini language. At least, as convuluted as C++ may be, template and compile time programming still rely on C++.
- necubi 2y agoI'm not necessarily going to defend proc macros, which have a lot of problems but are also better than the alternative in many languages (like Go's over-reliance on codegen). Macros-by-example are pretty nice though, even with the special syntax. But in Rust, you don't need to delve into any kind of macro for polymorphism like you do in C++, since Rust has a real generics system. There is vastly more C++ code that instantiates templates than Rust code that uses macros.
- pjmlp 2y agoThere are enough ways to do polymorphism in C++ without touching macros. Given that Rust IO and many crate attributes are macro based, not sure who wins out.
- necubi 2y agoI was a bit unclear there—I was referring to templates, not C++ macros. I believe that concepts in C++20 have improved the situation (although I haven't personally worked with a C++20 codebase and don't know how widely adopted it is in the ecosystem).
- jovial_cavalier 2y agoAm I crazy for thinking this is (mostly) useless? It feels like programming in the last five years has turned into a competition of who can make the most abstract meta programming patterns. I think if you find yourself making use of this feature, you’re probably in a deep hole of your own making. What is an example of a useful function that takes an arbitrary number of arguments each of which has an arbitrary type that isn’t as trivial as the examples given in the article? For super trivial stuff this is useful, and if std used this under the hood to provide std::first_arg or something, that would make sense. But the absence of this language feature doesn’t really seem like it’s holding back 99.9% of users.
- foota 2y agoPeople writing generic libraries need this. As an example, I've seen it used a lot in anything related to logging and monitoring, since these generally need the ability to take arbitrary data types and work with them in different ways. The same is true for database APIs, etc.,.
- deleted 2y ago[deleted]
- HeliumHydride 2y agostd::print is one. You need variadic generics to make it work.
- 112233 2y agoIf this was sarcasm and I missed it, I apologize. Because, how do you use it? How do you add debug printing to try and understand where the bug is? How do you debug even anything? Like, suppose your concept has a composite requires statement that invokes a constexpr predicate of two derived types, and it is not "true" as you expected, so overload resolution picks the wrong function. What is the analog of gdb to use in this situation?