Sunday, April 5, 2015

Versioned Runtime Environment

In an effort to make Abstraction adaptable to multiple versions of .NET, I've been analyzing the various versions against each other and aim to create two things:

  1. An XML document and schema that can be used to translate known identities between the versions so binding to a given type can be done in a version independent manner.
    1. To achieve this requires knowledge of the .NET assemblies and their identities.  
    2. I could encode common concepts within .NET through code, but this is an error prone task due to the version of the library not often matching that of the framework.  
      1. The Visual Basic libraries are a good example.
  2. A statically typed set of libraries that expose the members to allow expressions to be easier to compose on the framework dependent types.
    1. This will require a lot of effort on my part.  Each library will have its own accompanying expr library.  mscorlib will have mscorlib.expr.dll  This can be viewed as overkill but the simplicity it offers can't be beat.
    2. One such example is Console.WriteLine(string), there would then be two ways in which you could construct this:
      1. writeLineExp = "Console".Fuse("WriteLine").Invoke(myStringExpression);
      2. writeLineExp = ConsoleExp.WriteLine(myStringExpression);
    3. The difference above isn't obvious, whereas the fuse method will emit the correct code, the ConsoleExp.WriteLine will avoid typing errors because it utilizes the compiler to understand the structure of the document.  The Fuse method is also disadvantaged by refactoring, since you can very easily emit incorrect code by a refactor that is done carelessly.
    4. The latter would also be easier to bind to the types because they would be baked into the expression assembly.
Right now I'm formalizing the XSD that will maintain the logical representation of the type model.  The resulted file will likely be pretty large (1.8MB for outline with no members, this will skyrocket once members are added in, I suspect somewhere around 18-25MB), hoping compression will help with that some.

Do note that evaluating every version of the framework through isolating the identity resolution  per runtime version takes quite a bit of memory.  Right now it takes about 2.2GB of memory to do the analysis.  Once the XML file is generated, if I'm writing a language service, I can use the ExtensionAttribute and adapt to the version without the annoying effort that it requires today.  The automated process is more accurate and nearly 100% accurate whereas doing it by hand is tiresome and relies on 'Helper' classes that define common types: this is what I want to stay away from.

There'll likely be two versions of the metadata:
  1. Limited to Libraries and Types
    1. This is basically finished now, I just need to review it to make sure that types have a unique version for each breaking change, anything missing means I'm missing a library of that version.
  2. Full Metadata - Libraries, Types and Members.
    1. This will be used to automate the expression model system. This tool will not be for your average programmer, but programmers who specialize in:
      1. Writing code that writes code (tools which generate code to inject into standard MS Build processes)
      2. Writing code that writes libraries directly (compilers)