μετά: 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
Simple multiplication
Injection values into local execution scope
Languages are losing their classifications
Anders Hejlsberg talk about C# 3.0
LINQ
, Rx
DLR
, microORM
Applying this technique leads to a self-hosting compiler.
From Roslyn CTP
public object ReturnNullReferenceType() { return null; }
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();
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
IEnumerable<T>
or IQuerable<T>
new
in constructor[Attribute]
compositionDateTime.Now()
Demo #02
eval()
`-like for C# using Roslynvar 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
Demo #03
Code-as-Data: Roslyn and T4
Note about "Code-as-Data"
Note about "Dynamic" programming
DynamicMethod
dynamic
keyword supportasync/await
keywordsYou 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
// 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()) ]>; }
fault
try { result = body(); } fault // here is a _new keyword_ `fault` only executed after exceptions { onFault(); } finally { onFinally(); }
fault
macro definitionmacro execute(body, actionOnFault, actionOnFinally) syntax ( "try", body, "fault", actionOnFault, "finally", actionOnFinally) { <[ try { $body; } catch { | e is System.Exception => { $actionOnFault; throw; } } finally { $actionOnFinally; } ]> }
Note about Nemerle
dynamic
keyword not supportedasync/await
keywords for Nemerle 1.1 and .NET 4.0.Use a spacebar or arrow keys to navigate