> But in the given example, shouldn't the compiler be able to see, via a simple analysis, that this function is only being applied to lists of numbers?
No, that's the beauty and curse of dynamic languages such as the Scheme mentioned here. Of course, you could do special optimizations, such as inlining bindings that never get used out of scope or defining special functions that don't operate on real Lisp data structures but plain C structures, but they add extra complexity and duplicated logic to the compiler. I'm sure those kind of optimizations would be out of scope of this article.
> in practice I have not seen any optimisation that would take that Scheme-compiled C program and turn it into one a C programmer would write
Obviously Scheme code is going to look different than C code, they're different languages. I think the point being made was that it's okay to emit some C code that's a little extra verbose, doing things like defining extra vars and such, knowing that the compiler will simplify many such things.
> There's also the question "why even generate 'superfluous stuff' if it's going to disappear anyway?"
To keep the compiler's implementation simple and understandable. The more complex output it has to produce, the harder it is to read/write/debug.
No, that's the beauty and curse of dynamic languages such as the Scheme mentioned here. Of course, you could do special optimizations, such as inlining bindings that never get used out of scope or defining special functions that don't operate on real Lisp data structures but plain C structures, but they add extra complexity and duplicated logic to the compiler. I'm sure those kind of optimizations would be out of scope of this article.
> in practice I have not seen any optimisation that would take that Scheme-compiled C program and turn it into one a C programmer would write
Obviously Scheme code is going to look different than C code, they're different languages. I think the point being made was that it's okay to emit some C code that's a little extra verbose, doing things like defining extra vars and such, knowing that the compiler will simplify many such things.
> There's also the question "why even generate 'superfluous stuff' if it's going to disappear anyway?"
To keep the compiler's implementation simple and understandable. The more complex output it has to produce, the harder it is to read/write/debug.