@dawkot To put it simply, what Araq says is: in the first case, the macro operates directly on procA at compile time so it behaves as expected but in the second case, it actually operates on p argument (which has no implementation as it's not an actual procedure, therefore its implementation is nil) and then you provide procA as a value of p argument at runtime. But what was done at compile time remains the same so the runtime argument passing is irrelevant.
What you need is a template, as templates' arguments are passed at compile time rather than runtime: import macros macro procImplRepr(p: proc): string = p.symbol.getImpl.repr proc procA = discard template procB(p: proc): string = p.procImplRepr echo procA.procImplRepr echo procB(procA) # both print the same value