My experience with M4 is using it to write SELinux policy. The reference policy (which serves as a baseline to build build custom policy on top of) is essentially a DSL implemented with M4. Its actually a good language, and looks a lot like how we would have designed it if we were actually going to write it properly [0]. However, debugging it when something goes wrong (eg, what should be a syntax error) is atrocious. I'm sure it is great if you stick to using it for macros. However, at this point, I view it in the same light as Microsoft Excel: good at what it does, but too powerful for its own good. If your not careful, it will grow until you wish you had been using a proper programming language from the begging.
[0] Except for the backtick as opening quote. Objectively, I think this is a good design decision for any language, but it takes a lot of getting used to.