Very nice writeup, and I appreciate that it shows how to do this in languages other than Lisp (where it’s trivial). The examples in C are especially nice, because C has such a limited macro system - it shows that with a bit of effort, you can always produce a nice API.
Those C libraries do look impressive, but the downside of clean looking code is that the library has taken over (#defined) common words like “match”, “interface”, “of”. Now if you try to use any of those identifiers as variables, function names, enum constants … you’ll end up with syntax errors. Probably some very weird ones that seem to have nothing to do with your code.
In my current C++ codebase, we’ve run into some bizarre compile errors on Windows that turned out to stem from some Windows API defining “min” and “max” as macros. So any time we used the std::min or std::max functions, all hell broke loose. We had to undefine those symbols to fix it. (I’ve seen similar issues in macOS code due to an ancient Carbon header defining some common word as a constant.)
There’s a reason for the old K&R style of giving all preprocessor macros ALL_CAPS names, even if it’s ugly!