In general, `foo' is not known at the call site or `foo' is defined in some other module, for which no compile-time information is available.
Why? It is just as good as procedure inlining. In R6RS the compiler can know an imported bindings won't be altered at runtime; in R7RS we need to interact with some implementation-specific convention. In either way, the compiler can keep information about the bound value; only the "constantness" of the binding is needed to look it up.
In R7RS, macro is the only portable way to declare such "constantness" (by which I mean the compiler knows
the binding of an identifier won't be altered). An implementation may have other means (Gauche has a few).
define/kw macro may hide such differences.