14 ms·
It's a huge reminder C++ is missing a proper, hygienic, macro system. Too many things that are a pain to do in C++ would be easy with a real macro language. I h
by stelonix 4y ago
It's a huge reminder C++ is missing a proper, hygienic, macro system. Too many things that are a pain to do in C++ would be easy with a real macro language. I have hope we'll get it sometime this decade, seeing all the work on the language since C++11 still happening more than 10 years later.
It's worth nothing that a macro system plus basic reflection is where the real power of macros lies at.
- otabdeveloper4 4y ago> It's a huge reminder C++ is missing a proper, hygienic, macro system. Templates, man.
- smitty1e 4y agoI'm standing by for the announcement that some caffeine-addled Boost metaprogramming madman has implemented the Rust borrow checker as a C++ template, or at least thinks that he may have, when the compilation completes sometime in the 2030s.
- gpderetta 4y agoIt is not like I didn't try...
- steveklabnik 4y agohttps://docs.google.com/document/d/e/2PACX-1vSt2VB1zQAJ6JDMaIA9PlmEgBxz2K5Tx6w2JqJNeYCy0gU4aoubdTxlENSKNSrQ2TXqPWcuwtXe6PlO/pub https://docs.google.com/document/d/e/2PACX-1vSt2VB1zQAJ6JDMa...
- smitty1e 4y agoIt's not clear how much boost.org magic they used. Failing that, a GCC extension could be needful. From the ref: --- Conclusion We attempted to represent ownership and borrowing through the C++ type system, however the language does not lend itself to this. Thus memory safety in C++ would need to be achieved through runtime checks. Example code #include <type_traits> #include <utility> #include <assert.h> #include <stddef.h>
- wyldfire 4y agoThere is a branch of clang with support for "-Wlifetime" which might be a simpler alternative.
- sudosysgen 4y agoWhy use template metaprogramming? You can use compiler extensions for that since the code will be valid either way
- smitty1e 4y agoC++ has the Maximum Pain Rule. Templates it must be.
- gumby 4y agoIn case someone reads this comment as sarcasm: I got into a convo with Stroustrup about this once, back in the 90s. I said one thing I missed was the lack of macros, and he made a glancing comment about the preprocessor which I obviously dismissed and said didn’t even count. He bitterly said, “Yeah, unfortunately when something like that pollutes an ecological niche it becomes impossible to eradicate. The best I could get away with was templates.” A good perspective.
- WalterBright 4y agoBjarne was right, although C++ has been slow to adopt replacements for the preprocessor (such as modules, and conditional compilation).
- chakkepolja 4y agoCan it be used to implement automatic serialization on simple struct / class types?
- aaaaaaaaaaab 4y agoIf you only use std::tuple, then yes xD
- gpderetta 4y agoThere is a nasty trick which uses structured binding to convert an arbitrary aggregate to a tuple. That still doesn't help if you want the fields names.
- chakkepolja 4y agoYou have any link?
- gpderetta 4y agoSomething like this: https://github.com/apolukhin/magic_get https://github.com/apolukhin/magic_get
- chakkepolja 4y agoThanks. This may be useful for me someday.
- otabdeveloper4 4y agoNo, because C++ templates are basically a Lisp, and only things that are list-like can be processed by templates. (Like tuples, for example.)
- gpderetta 4y agoBut there are automated ways to to convert aggregates to tuples.
- stelonix 4y agoTemplates are nice, but they have shortcomings a more generic macro system wouldn't. They also have the issue where the more complex is your task, the more convoluted the code has to look, compilation times also increase and parsers (ergo, IDEs too) have trouble giving meaningful info on parameters. Don't even get me started on template errors because that's an atrocity on another level :(
- eru 4y agoThe problem with no info on parameters and horrible template errors are related: The root cause is that template expansion is duck-typed. 'Concepts' are supposed to fix that, I heard.
- WalterBright 4y agoDon't forget function templates! D can do them, too, but we strongly discourage their use. The trouble is that people use them to create DSLs that are indistinguishable from C++ code. For example: #include <boost/spirit.hpp> using namespace boost; int main() { spirit::rule<> group, fact, term, expr; group = '(' >> expr >> ')'; fact = spirit::int_p | group; term = fact >> *(('*' >> fact) | ('/' >> fact)); expr = term >> *(('+' >> term) | ('-' >> term)); assert( spirit::parse("2*(3+4)", expr).full ); assert( ! spirit::parse("2*(3+4", expr).full ); } https://studylib.net/doc/10029968/text-processing-with-boost---northwest-c---users--group https://studylib.net/doc/10029968/text-processing-with-boost... slide 40 What's C++ and what's regex?
- xigoi 4y agoAren't these just normal parser combinators?
- WalterBright 4y agoA >> means right shift, except when it doesn't in the example.
- eru 4y agoWell, the problem here is the re-use of existing operators. (That's why it's great that Haskell and other languages in that family allow you to define your own operators, instead of eg re-using bit-shifting for IO.)
- WalterBright 4y agoDefining your own operators means combining the lexer with the semantic analysis, which comes with all sorts of complexities.
- eru 4y agoActually, no. At least the way it's handled in Haskell and OCaml avoids this problem. (Btw, parsing C++ is already Turing complete.)
- kazinator 4y agoActually, some of the problem may be with C++ itself. When the C preprocessor is used in a more flexible, dynamic language, you can do surprising things. In the cppawk project, which combines the preprocessor with Awk, I used the preprocessor to create an iteration syntax with a vocabulary of useful clauses that combine together for parallel or cross-product iteration. Furthermore, the clauses are user-definable. https://www.kylheku.com/cgit/cppawk/about/ https://www.kylheku.com/cgit/cppawk/about/ What helps is that you don't have to deal with types and declaration syntax. So many of the ideas in cppawk will not translate back to C or C++, or not without wrecking the syntax with additional arguments and whatnot. The man page for the <iter.h> header has a section on defining a clause; I provided an example of defining a clause that iterates on alpha-numeric string ranges like from "A00" to "Z99". As an experienced Lisp programmer (and implementor), I had to rub my eyes several times to believe I had such a thing working, under such a universally maligned and reviled preprocessor.
- pjmlp 4y agoOther than some more clever hacks, templates alongside constexpr already cover a lot of possibilities.
- Asooka 4y agoYou don't get the guarantees for what code is generated that you do with macros and they take a lot longer to compile. Also you can't just modify the AST of the current scope like you can with macros - pretty much every single time I have to use a macro it's because I need to generate code within the current scope. Fortunately they are usually very short. The two for me fill different niches - for generic type-safe functions, parametrised types, etc. - templates. For text generation - macros. A hygenic macro system that lets you generate AST nodes and gives you access to type information would be absolutely divine, but it doesn't seem like we're getting it. Imagine if we had a script language that had full access to the compiler's internals.
- pjmlp 4y agoI don't need to imagine when we have Circle, and experimental implementations of C++ reflection. That is what is missing piece of the puzzle.
- sumtechguy 4y agoMost of the abuses of #define I have seen, a template or constexpr takes care of. There are still some cases where it is nice. But many times you probably should just write a function/method/template out of it anyway.