Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Pragmatic metaprogramming

487 views

Published on

Do not repeat yourself, we teach every fledgling software developer. It makes sense as with growing code redundancy the maintenance cost increase. Simple tools such as functions or loops are a great ways to reduce code redundancy but in our quest to avoid code redundancy we sometimes indulge into complexity. Complex code is also costly to maintain. I will demonstrate, using real-world examples, how one can adopt metaprogramming to minimize code redundancy as well keeping the code simple enough for my mom to understand it.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Pragmatic metaprogramming

  1. 1. Pragmatic MetaProgramming Mårten Rånge SWETUGG 10:50
  2. 2. Mårten Rånge @marten_range
  3. 3. Pragmatic MetaProgramming
  4. 4. DNRY Do Not Repeat Yourself
  5. 5. Loops are great x += 1; x += 2; x += 3; x += 4; x += 5; x += 6; x += 7; x += 8; x += 9; x += 10;
  6. 6. Loops are great for (var iter = 1; iter < 11; ++iter) { x += iter; }
  7. 7. Functions are great var z1 = t*(y1 – x1) + x1 var z2 = t*(y2 – x2) + x2 var z3 = t*(y3 – x3) + x3
  8. 8. 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);
  9. 9. 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) }
  10. 10. Repeating myself AnException Exception
  11. 11. 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) }
  12. 12. Repeating myself exception AnException of int*string
  13. 13. Repeating myself public class MyViewModel : INotifyPropertyChanged { int m_myProperty = 0; public int MyProperty { get { return m_myProperty; } set { m_myProperty = value OnRaisePropertyChanged ("MyProperty") } } void OnRaisePropertyChanged (string propertyName); }
  14. 14. Repeating myself int MyProperty
  15. 15. Repeating myself public class MyViewModel : INotifyPropertyChanged { int m_myProperty = 0; public int MyProperty { get { return m_myProperty; } set { m_myProperty = value OnRaisePropertyChanged ("MyProperty") } } void OnRaisePropertyChanged (string propertyName); }
  16. 16. 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), }; }
  17. 17. 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), }; }
  18. 18. Repeating myself Customer long Id string FirstName string LastName
  19. 19. 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), }; }
  20. 20. Code duplication increases maintenance cost
  21. 21. Looking for answers  Reflection  LINQ Expression Trees  Dynamic IL
  22. 22. 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
  23. 23. public Customer ReadCustomer (IDataReader dr) { return new Customer { Id = dr.GetInt64 (0), FirstName = dr.GetString (1), LastName = dr.GetString (2), }; }
  24. 24. 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
  25. 25. Complex code increases maintenance cost
  26. 26. Looking for answers Powerful Simple concept Language agnostic Exit strategy Lightweight
  27. 27. T4
  28. 28. 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
  29. 29. class Example { <# for (var iter = 0; iter < 10; ++iter) { #> public int X<#=iter#> = <#=iter#>; <# } #> } T4
  30. 30. 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
  31. 31. Demo.001 Getting started with T4
  32. 32. Betty Holberton Merge Sort Generator (1951)
  33. 33. Repeating myself public class MyViewModel : INotifyPropertyChanged { int m_myProperty = 0; public int MyProperty { get { return m_myProperty; } set { m_myProperty = value OnRaisePropertyChanged ("MyProperty") } } void OnRaisePropertyChanged (string propertyName); }
  34. 34. Repeating myself public class MyViewModel : INotifyPropertyChanged { int m_myProperty = 0; public int MyProperty { get { return m_myProperty; } set { m_myProperty = value OnRaisePropertyChanged () } } void OnRaisePropertyChanged ([CallerMemberName]string name = null); }
  35. 35. Repeating myself int MyProperty
  36. 36. Repeating myself public class MyViewModel : INotifyPropertyChanged { int m_myProperty = 0; public int MyProperty { get { return m_myProperty; } set { m_myProperty = value OnRaisePropertyChanged ("MyProperty") } } void OnRaisePropertyChanged (string propertyName); }
  37. 37. Demo.002 Generating view model classes
  38. 38. T4 Powerful Simple concept Language agnostic Exit strategy Lightweight
  39. 39. Carnelian
  40. 40. class Example { <# for (var iter = 0; iter < 10; ++iter) { #> public int X<#=iter#> = <#=iter#>; <# } #> } T4
  41. 41. class Example { @@> for iter in 0..10 public int X@@=iter=@@ = @@=iter=@@; @@> end } Carnelian
  42. 42. Demo.003 Carnelian
  43. 43. Carnelian Powerful Simple concept Language agnostic Exit strategy Lightweight
  44. 44. Start small
  45. 45. class Example { <# for (var iter = 0; iter < 10; ++iter) { #> public int X<#=iter#> = <#=iter#>; <# } #> } T4 is ASP/PHP for code
  46. 46. T4 saved me
  47. 47. Mårten Rånge @marten_range
  48. 48. T4 T4 Addin http://t4-editor.tangible-engineering.com/ T4 Blog http://www.olegsych.com/ T4Include http://github.com/mrange/t4Include/
  49. 49. ”The CORRECT Way to Code a Custom Exception Class” http://bit.ly/1AsJ0UH
  50. 50. Vad tyckte du om sessionen? svara på vägen ut

×