Although, for what it's worth, Java programmers solved this quite some time ago by allowing crude lazy evaluation of the string. Logging calls actually look like:
LOGGER.debug("last node was: {}", node);
Where the parameters are a template string and a varargs of objects. The objects are stringified and substituted into the template only once the logging library determines that the message will actually be used.
In Scala, you just make the parameter to the call a lazy or call-by-name value, and then there's no need to write an explicit template, the language captures the expression which produces the string and defers its execution until it's needed.
Of course, there are many things macros can do which mechanisms like these can't. The choice in language design is between introducing macros, or introducing enough other mechanisms to make macros unnecessary. Introducing macros seems more parsimonious, but given the utter confusion that macros can be used to wreak, it's not a slam dunk.
And, of course, the Scala designers have introduced all these mechanisms and then added macros anyway, because they're crazy.