Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Metaprogramming in .NET

“Roslyn” CTP and Nemerle

μετά: after, beyond, self, adjacent

metaprogramming: The classic definition for a metaprogram is “a computer program that writes new computer programs”
by @KevinHazzard and @JasonBock

JavaScript eval() as metaprogramming example

from Metaprogramming in .Net by @KevinHazzard and @JasonBock

Initial state

JavaScript Metaprogramming via Scripting

Simple multiplication

Use Function Dynamicly

Injection values into local execution scope

Injection Values into Local Execution Scope

C# is multiparadigm language

Languages are losing their classifications

Anders Hejlsberg talk about C# 3.0

Compilers are black boxes

Applying this technique leads to a self-hosting compiler.

Roslyn CTP: compiler pipeline, API and services

Compiler as a Service

Metaprogramming by …

Demo #01

Syntax/Semantic tree tree sample from Roslyn

C# code and syntax tree

From Roslyn CTP

public object ReturnNullReferenceType()
{
    return null;
}
Roslyn syntax tree sample

Search for return null;

Func<StatementSyntax, bool> returnNullStatement =
    PredicateBuilder
        .True<StatementSyntax>()
        // all return statements
        .And(s => s is ReturnStatementSyntax)
        // with expression
        .And(s => (s as ReturnStatementSyntax).Expression != null)
        // with expression "null"
        .And(s => (s as ReturnStatementSyntax).Expression.Kind == SyntaxKind.NullLiteralExpression)
            .Compile();

Search for return default(T);

Where T is reference type

ExpressionSyntax expressionSyntax = (statement as ReturnStatementSyntax).Expression;

ISemanticModel semanticModel = await semanticModelAsync;

return expressionSyntax != null &&
 (semanticModel.GetTypeInfo(expressionSyntax).Type == null
     || semanticModel.GetTypeInfo(expressionSyntax).Type.IsReferenceType);

Installation instruction for introspection sample

Advanced samples

Demo #02

Scripting: `eval()`-like for C# using Roslyn and ScriptCS

`eval()`-like for C# using Roslyn

var scripts = new []
    {
        System.Console.ReadLine(),         //fromValue:
        System.Console.ReadLine()          //formula:
    };

var engine = new ScriptEngine();           // create script engine

Array.ForEach(                             // add references to assembiles
    new[] { typeof(object).Assembly, GetType().Assembly },
    @assembly => engine.AddReference(@assembly));

Array.ForEach(                             // import namespaces
    new[] { "System" },
    @namespace => engine.ImportNamespace(@namespace));    

Console.WriteLine(engine.GetType());

var session = engine.CreateSession();      // create session

object resultModel = null;

// INFO: scripts are using same session
foreach(var script in scripts)
{
    resultModel = session                 // process scripts
                    .CompileSubmission<object>(script)
                    .Execute();
}

ScriptCS execution sample

ScriptCS execution sample

Demo #03

Code-as-Data: Roslyn and T4

Roslyn CTP and T4: runtime processing

DTO types description .json
Runtime T4 creates C# code
Roslyn compiles assembly
Script.json
Roslyn creates submission
Input.json
.Net App Domain
Processing

Demo #04

Code-as-Data: Convert code written in one language to another

VB → C# and back again

Note about "Code-as-Data"

Note about "Dynamic" programming

Corner cases

Nemerle

Compile-time metaprogramming using macros

You can think about macros as of a system of compile-time transformations and automatic generation of code with regard to some rules
by Nemerle.org

Nemerle macro: compile- with run- time execution

// Test macros to show difference between compile time and runtime execution
public macro TestMacro(inputAST)
{
    Console.WriteLine("Compile-time execution: '{0}' of type {1}\n", 
                            inputAST, inputAST.GetType());
                            
    <[ Console.WriteLine("Run-time execution: {0} of type {1}\n", 
                            $inputAST, $inputAST.GetType()) ]>;
}

Expected console output during build

nemerle compiletime macro execution

New keyword fault

try
{
    result = body();
}
fault // here is a _new keyword_ `fault` only executed after exceptions
{
    onFault();
}
finally
{
    onFinally();
}

fault macro definition

macro execute(body, actionOnFault, actionOnFinally) 
syntax (
    "try",
        body,
    "fault",
        actionOnFault,
    "finally",
        actionOnFinally) 
{
    <[
        try
        {
            $body;
        }
        catch
        {
            | e is System.Exception => { $actionOnFault; throw; }
        }
        finally
        {
            $actionOnFinally;
        }
    ]>
}

Advanced samples

Note about Nemerle

Use a spacebar or arrow keys to navigate