Pragmatic metaprogramming

Post on 15-Jul-2015

209 views 2 download

Transcript of Pragmatic metaprogramming

Pragmatic MetaProgrammingMårten Rånge

SWETUGG 10:50

Mårten Rånge

@marten_range

Pragmatic MetaProgramming

DNRYDo Not Repeat Yourself

Loops are great

x += 1;x += 2;x += 3;x += 4;x += 5;x += 6;x += 7;x += 8;x += 9;x += 10;

Loops are great

for (var iter = 1; iter < 11; ++iter){

x += iter;}

Functions are great

var z1 = t*(y1 – x1) + x1var z2 = t*(y2 – x2) + x2var z3 = t*(y3 – x3) + x3

Functions are great

double Lerp (this double t, double x, double y){

return t*(y – x) + x;}

var z1 = t.Lerp (x1, y1);var z2 = t.Lerp (x2, y2);var z3 = t.Lerp (x3, y3);

Repeating myself

[Serializable]public class AnException : Exception{

public AnException ();public AnException (string message);public AnException (string message, Exception exc);protected AnException (

SerializationInfo info, StreamingContext context);

[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]

public override void GetObjectData (SerializationInfo info, StreamingContext context)

}

Repeating myself

AnException Exception

Repeating myself

[Serializable]public class AnException : Exception{

public AnException ();public AnException (string message);public AnException (string message, Exception exc);protected AnException (

SerializationInfo info, StreamingContext context);

[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]

public override void GetObjectData (SerializationInfo info, StreamingContext context)

}

Repeating myself

exception AnException of int*string

Repeating myself

public class MyViewModel : INotifyPropertyChanged{

int m_myProperty = 0;public int MyProperty{

get { return m_myProperty; }set{

m_myProperty = valueOnRaisePropertyChanged ("MyProperty")

}}

void OnRaisePropertyChanged (string propertyName);}

Repeating myself

int MyProperty

Repeating myself

public class MyViewModel : INotifyPropertyChanged{

int m_myProperty = 0;public int MyProperty{

get { return m_myProperty; }set{

m_myProperty = valueOnRaisePropertyChanged ("MyProperty")

}}

void OnRaisePropertyChanged (string propertyName);}

Repeating myself

class Customer {

public long Id ; public string FirstName; public string LastName ;

}public Customer ReadCustomer (IDataReader dr){

return new Customer{

Id = dr.GetInt64 (0),FirstName = dr.GetString (1),LastName = dr.GetString (2),

};}

Repeating myself

class Customer {

public long Id ; public string FirstName; public string LastName ;

}public Customer ReadCustomer (IDataReader dr){

return new Customer{

Id = dr.GetInt64 (0),FirstName = dr.GetString (1),LastName = dr.GetString (2),

};}

Repeating myself

Customer

long Id string FirstNamestring LastName

Repeating myself

class Customer {

public long Id ; public string FirstName; public string LastName ;

}public Customer ReadCustomer (IDataReader dr){

return new Customer{

Id = dr.GetInt64 (0),FirstName = dr.GetString (1),LastName = dr.GetString (2),

};}

Code duplication increases maintenance cost

Looking for answers

Reflection

LINQ Expression Trees

Dynamic IL

Adding complexity

Trading compile-time errors for run-time errors

Hard to get enough test coverage

Hard to understand

No exit strategy

Risky to change

Limited

public Customer ReadCustomer (IDataReader dr){

return new Customer{

Id = dr.GetInt64 (0),FirstName = dr.GetString (1),LastName = dr.GetString (2),

};}

Adding complexity

Trading compile-time errors for run-time errors

Hard to get enough test coverage

Hard to understand

No exit strategy

Risky to change

Limited

Complex code increases maintenance cost

Looking for answers

Powerful

Simple concept

Language agnostic

Exit strategy

Lightweight

T4

class Example{

public int X0 = 0;public int X1 = 1;public int X2 = 2;public int X3 = 3;public int X4 = 4;public int X5 = 5;public int X6 = 6;public int X7 = 7;public int X8 = 8;public int X9 = 9;

}

T4

class Example{<# for (var iter = 0; iter < 10; ++iter) { #>

public int X<#=iter#> = <#=iter#>;<# } #>}

T4

class Example{

public int X0 = 0;public int X1 = 1;public int X2 = 2;public int X3 = 3;public int X4 = 4;public int X5 = 5;public int X6 = 6;public int X7 = 7;public int X8 = 8;public int X9 = 9;

}

T4

Demo.001Getting started with T4

Betty Holberton

Merge Sort Generator (1951)

Repeating myself

public class MyViewModel : INotifyPropertyChanged{

int m_myProperty = 0;public int MyProperty{

get { return m_myProperty; }set{

m_myProperty = valueOnRaisePropertyChanged ("MyProperty")

}}

void OnRaisePropertyChanged (string propertyName);}

Repeating myself

public class MyViewModel : INotifyPropertyChanged{

int m_myProperty = 0;public int MyProperty{

get { return m_myProperty; }set{

m_myProperty = valueOnRaisePropertyChanged ()

}}

void OnRaisePropertyChanged ([CallerMemberName]string name = null);}

Repeating myself

int MyProperty

Repeating myself

public class MyViewModel : INotifyPropertyChanged{

int m_myProperty = 0;public int MyProperty{

get { return m_myProperty; }set{

m_myProperty = valueOnRaisePropertyChanged ("MyProperty")

}}

void OnRaisePropertyChanged (string propertyName);}

Demo.002Generating view model classes

T4

Powerful

Simple concept

Language agnostic

Exit strategy

Lightweight

Carnelian

class Example{<# for (var iter = 0; iter < 10; ++iter) { #>

public int X<#=iter#> = <#=iter#>;<# } #>}

T4

class Example{@@> for iter in 0..10

public int X@@=iter=@@ = @@=iter=@@;@@> end

}

Carnelian

Demo.003Carnelian

Carnelian

Powerful

Simple concept

Language agnostic

Exit strategy

Lightweight

Start small

class Example{<# for (var iter = 0; iter < 10; ++iter) { #>

public int X<#=iter#> = <#=iter#>;<# } #>}

T4 is ASP/PHP for code

T4 saved me

Mårten Rånge

@marten_range

T4

T4 Addinhttp://t4-editor.tangible-engineering.com/

T4 Bloghttp://www.olegsych.com/

T4Includehttp://github.com/mrange/t4Include/

”The CORRECT Way to Code a Custom Exception Class”

http://bit.ly/1AsJ0UH

Vad tyckte du om sessionen?

svara på vägen ut