Chez isn't always the fastest, but it's the fastest so often that I wouldn't look much beyond it if performance were of major importance to me. It's been written about here on HN before, but the next major version of Racket will be based on Chez. Chez will get package management, libraries, and modern tooling of Racket, and Racket will (presumably) be able to capitalize on the performance of Chez.
I've received this criticism of my approach before.
Note I'm talking about not just C code-gen, but human-readable C code-gen. If it's not human-readable, then I agree with you, we might as well generate machine code and become full-time scheme programmers.
But if it's human readable C, as if the code was created by a C programmer with clean coding practices, then it makes a big difference.
You might ask, "but why human readable?"
I think the answer is that as a result, you can work on that C project, try out ideas, pick the one that works best, then go back to scheme to see how you can generate what you just tried out. It's a long-winded way of doing things, but you're doing research, you're not simply taking a hand-written change-set in C and creating the simplest scheme code to generate it (e.g., dumping a sequence of string literals to stdout). You are exploring the higher abstractions of the scheme code, and finding out how the new code that generates new change-set fits in with the rest of the scheme code.
Take 'logging' for example. Logging is orthogonal to a functioning C code. A well written fully functioning 10k lines of C program could easily become 30k-50k lines simply by adding comprehensive logging and not adding a single other feature.
If scheme code-generator has a logging module, it would not generate logging code directly, but it would take the non-logging functionality of the program as input, analyze it, and output logging code as a result. Further more, you could disable logging code-gen, and generate the original 10k lines of code, and then study the C code, and it would help a lot with readability (you're not coming across 10 lines of logging code every 2 or 3 lines of actual code).
Similarly, debuggability. A scheme code could help insert debugging code at relevant points. Heck, we're using scheme as a tool, a machine to help our coding, why not use scheme as an automation agent, i.e., use it to iterate through a debugging process by giving some directions in the beginning and letting it triangulate the exact line in C code which, e.g., causes a segmentation fault.
C code is full of error checks. Every function call is followed by "if (error1) { do_this(); } else if (error2) { do_that(); }". Wish to read the code without error checks? Just re-generate the code with error-checking disabled! Done.
Even more, you use scheme to generate various kinds of data that can be used for analysis. E.g., you wish to visualize the call-graph of the C code? you could generate the graph data file then run it through graphviz. (I know gcc does that already but then what is gcc? an automation tool for your C program! All I'm saying is that all these things can be done in a much better way in scheme)
(again, think of Scheme as a tool and an automation agent, and C code being the actual program!).
Chez isn't always the fastest, but it's the fastest so often that I wouldn't look much beyond it if performance were of major importance to me. It's been written about here on HN before, but the next major version of Racket will be based on Chez. Chez will get package management, libraries, and modern tooling of Racket, and Racket will (presumably) be able to capitalize on the performance of Chez.
Of course if you come from, say Python, performance shouldn't really matter much to you, as pretty much all the schemes are already playing in a different league: http://benchmarksgame.alioth.debian.org/u64q/compare.php?lan...