Early on in my programming career, I implemented all sorts of beautiful magic, but I was alone. Later, I realized that beautiful magic was keeping me alone. Now, much later in my career, I program mostly like a novice. I don't write clever code, I unroll powerful one liners into boring for loops, and I use all sorts of temporary variables to make intent perfectly clear, because I want and need as much help as I can get. Confusing contributors for some wanky obsession with "terseness" or "elegance" is a good indication of either a great team, or someone that works alone.
So, I guess "simplicity in understanding".
Most of them just were not conscious of the consequences of their behavior. E.g this behavior is typical of someone that programs for a living but does not debug her own code, because someone else in the company does. So she is isolated from the consequences of her actions.
For making them understand it is as easy as making the debugger people to program and the programming people to debug for a while.
Nothing like making people miserable suffering from bad source code they have themselves created for making them understand.
Then you give them solutions for their misery and they learn pretty fast.
Experienced C programmers tend to avoid the trap of using heavy macros because they have learned. But at the same time they look for alternatives that make them more productive with some king of real metaprogramming.
What can I say? Everything goes well, nothing critical has appeared soon, my coworkers are able to understand the code.
Regarding macro-based eDSLs, I would not resort to them for needs other than abstractions to be considered as a part of the language (ADTs, interfaces, etc.), since they are like languages on their own; when you try to understand/contribute to eDSL-based code, you have to understand its syntax and semantics, aside from how does it actually solve a particular problem in the problem domain.
In fact, as for now, I don't see much need in something like Metalang99 except for Datatype99 & Interface99 (and probably my feature request to libmprompt [1]).
For example, I think x-macros can be super useful and a consistent way to define certain data structures.
But using macros to define your own special DSL and make C code not look like C code is pretty nasty.
[1]: https://hirrolot.github.io/posts/extend-your-language-dont-a...
github.com/glouw/ctl
Check CTL/vec.h, for instance
I don't have a ton of experience w/ C, but the large projects I've seen appear to have a tendency to avoid heavy macro usage (e.g. using `void *` for hashmap implementations instead of reaching for macros, for example). I see macros appear more frequently among those that prioritize machiavellian cleverness, often under the pretext of squeezing performance: code written by (g|x)ooglers, for example.
I'm curious what more experienced C developers think of jumping into projects with heavy usage of macro-based DSLs, especially the syntax-bending variety being suggested here. Does it get in the way of contributing? Or of reasoning about performance? Etc.