:>> Proxying and genclass haven't been attempted yet.
:> Can you guess how long they should take to implement?
Probably not too long. I cannot do a straight conversion of
core_proxy.clj and genclass.clj as I did with other bootstrap files --
the code is heavily dependent on the ASM bytcode library. I'll have
to recode all that in System.Reflection.Emit. That will take some
work. If I move it to the front of the queue, it could be done in a
week or two.
:> Why is it important that the MSIL is similar to the JVM bytecode?
:> Shouldn't the compiler use techniques specific for performance on
the
:> CLR?
It's important in that it means that the generated MSIL is not
completely junk, in that I'm not missing any important optimizations,
that I'm taking full advantage of type hints, avoiding reflection,
etc.. The JVM bytecodes are an important check for me. What's
interesting is that the methods used to generate the IL in the each
implementation are very different. The two implementations generate
AST from the clojure source that are pretty much identical. From the
ASTs, the JVM implementation generates bytecodes using the ASM
bytecode library--essentially, it's close to hand-generated. Rich and
company have that code pretty finely tuned. The CLR implementation
transforms the ASTs into DLR-Expression-Tree-Version-2 expressions.
The DLR code handles compiling those expressions into either dynamic
methods or into static methods for saving in assemblies. The DLR
expression compiler should be generating decent MSIL. I think the
closeness of the results are encouraging.
The JVM implementation does pull some tricks, such as nulling method
arguments before tail calls or storing some temp values on the stack,
that I can't figure out how to duplicate with ExpressionTrees. Also,
the expression tree compiler can only generate static methods.
Clojure functions are instances of a class implementing the IFn
interface. I have to hand-code the class definitions and code the
'invoke' instance methods to call out to static methods in a base
class. That adds an extra method call in many places. Whether all
these little things add up to some of the performance differences is
beyond my knowledge or the granularity of the profiling tools at my
disposal. Unless some MSIL expert surfaces to give advice, I'll be
spending time hand-coding some alternatives to benchmark certain
constructs to see what works better. Worst case, I will end up
discarding the MSIL and doing the MSIL generation myself.
:> It'd be much easier to play with if you provide a precompiled
:> executable :)
I thought about that. Adding assembilies of my code as a download is
easy enough. However, to get the thing running, you also need vjslib
from the J# Redistributatable library plus DLLs generated from the DLR
source -- care to advise me about the legal ramifications of me doing
that directly? :)
:> Keep up the good work! I hope to someday use ClojureCLR for real
:> projects, so I can have all the functional, concurrent goodness of
:> Clojure in .NET.
I think that day is not too far off.