* program compilation, where the object system can declare parts as non-extensible
* a runtime compiler, which can compile methods
See for example for a recent attempt to statically compile methods and handing the types to the optimizing compiler (which also uses type inference):
Racket is a beautiful thing.
CLISP also can use a JIT - it uses GNU Lightning for runtime native code generation (https://www.gnu.org/software/lightning/).
Anyway the Racket JIT seems to be a bit limited:
> The JIT compiler works incrementally as functions are applied, but the JIT compiler makes only limited use of run-time information when compiling procedures, since the code for a given module body or lambda abstraction is compiled only once. The JIT’s granularity of compilation is a single procedure body, not counting the bodies of any lexically nested procedures.
A generic `f` will probably be similar to the Common Lisp one. However, as soon as you use `f` in a context where types are known (e.g. if you use multimethods to overload a function that calls `f`), it will be specialized and JIT-compiled for the specific type (int, float, matrix, ...), with no extra work for the programmer.