Program graph rewriting is of course more complex, but can be better defined with regards to acceptable inputs and more defensive as opposed to letting the next step of compiler or interpreter handle it.
The other problem is that most IDEs don't offer an expand macro (or similar) option for the rewritten parts (or I haven't seen them doing that), so observing what the final code looks like requires additional steps. In some ways its similar to functions, but most languages have functions that have a well defined input/output structure whereas macros can do some unexpected things depending on the inputs.