There's no real difference between a FEXPR, and a macro that calls eval or apply during expansion. The real meaning of "banishing" FEXPRs is that we actually get something extra: guaranteed-non-macro functions that behave according to a predictable pattern (evaluate arguments, pass them in, return a value.) Functions are basically a codified Lisp design-pattern, while macros (or FEXPRs, as they may be) are the real core of Lisp's abstraction mechanism, and really what make Lisp, Lisp.
It's just the same with Smalltalk: functions take lambdas as arguments, not primitive or composite values. "Receives values" is simply a design pattern.
That's a pretty good explanation; if it's accurate, I wonder why no one else explains it that way.
In Smalltalk, I thought arguments are always evaluated unless they're blocks. Is that wrong? Or is it that, at a lower level, everything's a block, and functions are implemented on top of that as something that always evaluates args?
No, you're right—arguments are always evaluated unless they're blocks in the full Smalltalk design we have today. However, like I said, this is a codified design pattern—the language could get away without doing it while still retaining the "core Smalltalk conceit" of everything being a message sent to an object. This is basically what the io language does—it's basically a Smalltalk at its core, but with less cruft.
It's just the same with Smalltalk: functions take lambdas as arguments, not primitive or composite values. "Receives values" is simply a design pattern.