> Evidently you are not familiar with how many Lisp compilers work.
It would be better etiquette not to assume such things. A cursory google for my name (available from my HN profile I believe) would reveal that it's very very likely that I am familiar with how Lisp compilers work.
> You don't need an interpreter anywhere, just a compiler.
In Lisp, sure. But Lisp is not Python. Lisp's eval is structured, making it far simpler to compile than Python(/PHP/Perl/Ruby/JavaScript)'s unstructured eval, which takes a string which is may be constructed at run-time. Even so, Python(/etc)'s semantics lazily look up imports, which means that an imported module may be changed at run-time.
The crux of the issue is that in Python the dynamicism is actually used by lots of modules and programs.
> Note that eval(), as much as it makes sense in the C language, can be implemented in C too (inject the text into a stub, compile it into a shared library, dlopen(), dlsym(), call it).
C's dynamic loading has significantly less scope than that of Python or of Lisp. C loads already compiled code, meaning that the C implementation is not required to have a run-time compiler available (the user may decide to compile C code using a compiler already on the system, but that's for the user to implement, not for the C compiler writter).
Furthermore, almost none of the work of the compiler writer is affected by dynamic loading. Sure, it means they might not know all the entry points of some externally exported symbols, or they might not have a complete call-graph, or they might not be able to statically-infer all the run-time types or aliases of some static name. However, this limits the scope of optimization, it does not hamper implementation. And even then it rarely hampers local optimization, which the Python dynamic loading does (see my PhD chapter 6 for a discussion).