http://clhs.lisp.se/Body/f_cmp.htm
In fact, with the package system ASDF, you can recompile (incrementally) an entire package at runtime. This is a single blocking function call; something like:
(asdf:operate 'asdf:compile-op :my-package)
I have a web project where any request in dev mode triggers a system recompilation only if the git revision of the working tree is new.
(my-handler :did-recompile (when (revision-is-new) (recompile) t))
That recompiles the system including MY-HANDLER, and right after RECOMPILE returns, the new version of MY-HANDLER from the working tree will be active.
The way Common Lisp lets me do that as a ten minute hack feels like living in the future... except of course it's pretty old technology!
Edit: I realize this is not really what you are talking about as "self-modifying code." Having full access to the compiler at runtime is a good first step for doing some of what you want, though. And with S-expressions, constructing and manipulating "ASTs" is ridiculously straightforward.
All the pieces are there.
Of course the JITer will not perform the same level of optimizations as the fullblown code generator, but then you can just call that if you like.
The new JIT engine does support SIMD [1]. And C# can generate SIMD code using various libraries (I think MS has one, and I know Mono does).
And various people have shown how to do fullblown x86 assembly code generation and execution from within C#, but it's fragile.
[1] http://blogs.msdn.com/b/dotnet/archive/2014/04/07/the-jit-fi...
float[] floats = new float[1000];
float factor = 1.01f;
int index = 0;
while (index < 1000)
{
floats[index++] *= factor;
}
...becomes...00007ff8`80a804a9 488d549010 lea rdx,[rax+rdx*4+10h]
00007ff8`80a804ae c4e17a1002 vmovss xmm0,dword ptr [rdx]
00007ff8`80a804b3 c4e17a590524000000 vmulss xmm0,xmm0,dword ptr [00007ff8`80a804e0]
00007ff8`80a804bc c4e17a1102 vmovss dword ptr [rdx],xmm0
This is in VS 2013, compiled with DEBUG off, prefer x86 off, and 'any cpu' as the target.
- Use the new RyuJIT
- Make use of 64 bits CPU
- Use the vector and matrix classes from System.Numerics
Unless you're optimising for size, SMC'ing little pieces is definitely going to be slower. But e.g. in loops that do a few hundred iterations, saving a cycle or two by getting rid of some opaque predicates quickly adds up and the cache/pipeline-flushing overhead (few hundred cycles at most) becomes insignificant.
After all, as the parent comment says, a JIT is basically SMC'ing huge blocks of code, and it's definitely faster than the equivalent alternative of a bytecode interpreter.
See the LLVM "Kaleidoscope" tutorials from the LLVM docs. They implement a simple toy compiler with a JIT-based REPL. Basically you use the LLVM framework to build a program and then run it through the compiler pipeline and get a callable function pointer to your newly compiled function(s), optimized for the CPU architecture you're running on.
Even if that remotely made any sense, which i don't think it does... c code compiles to the end target of all jits anyway, you just have some if statements or use pointers to other executable code that you swap around. Not only do you get the executable code as efficable as any jit, its constant with no jit cost. Its called c programming.
What OP wants is a way to get the advantage of ahead-of-time compilation for the 99% of the code that benefit from it, and the advantages of JIT for the remaining 1% (or even less).
However, I'm not sure how feasible that would be.
How much it would help performance in practice I couldn't say.
... then the high-level language isn't expressing self-modifying; the compiler is doing it to optimize the code while preserving the abstract meaning that is free of self-modifying.