Your SlideShare is downloading. ×
0
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Mixing functional and object oriented approaches to programming in C#
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Mixing functional and object oriented approaches to programming in C#

2,037

Published on

0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
2,037
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
49
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • Lazy evaluation
  • Go faster!!!
  • origins of functional programming are found in lambda calculation/maths
  • functions that take in a function or return a function. Need to have first class functions in the language to do that. We have that with all the LINQ methods - select, where, and so on.
  • the whole premise of functional programming with side effect free functions assumes that we have immutable data. We can't achieve this idiomatically in C# because the language isn't really designed for it. I want to put an example of how immutability is easy in F#, can that go in this section?
  • iterators in C# do this with yield keyword It's not necessary to have lazy evaluation to be functional but it's a characteristic of some functional languages.
  • seems quite obvious but the most extreme guideline to follow is that we shouldn't need to store anything in variables. Look at the data as a whole if we don't store any intermediate values then we truly do have some data that we are passing through different filters and applying some transformation
  • it's quite like the pipes and filters architectural pattern in fact. This is the way that we can combine functions on the unix command line.
  • what is CPS?   is where we pass in a function that represents the rest of the program which will be called with the result of another function.
  • what is CPS?   is where we pass in a function that represents the rest of the program which will be called with the result of another function.
  • what is CPS?   is where we pass in a function that represents the rest of the program which will be called with the result of another function.
  • the idea is that the rest of the program is contained in the continuation so we don't need to come back to the call site.
  • the idea is that the rest of the program is contained in the continuation so we don't need to come back to the call site.
  • the idea is that the rest of the program is contained in the continuation so we don't need to come back to the call site.
  • Encapsulates the state but over complicates the program flow perhaps
  • Encapsulates the state but over complicates the program flow perhaps
  • Transcript

    • 1. Mixing Functional and Object Oriented approaches to programming in C# Mike Wagg & Mark Needham
    • 2. C# 1.0
    • 3. http://www.impawards.com/2003/posters/back_in_the_day.jpg
    • 4. int[] ints = new int[] {1, 2, 3, 4, 5}  
    • 5. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if (i % 2 == 0) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 6. int[] ints = new int[] {1, 2, 3, 4, 5}  
    • 7. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if (i >3) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 8. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if ( i % 2 == 0 ) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 9. int[] Filter(int[] ints) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if ( i > 3 ) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 10. interface IIntegerPredicate { bool Matches(int value); }
    • 11. class EvenPredicate : IIntegerPredicate { bool Matches(int value) { return value % 2 == 0; } }
    • 12. class GreaterThanThreePredicate : IIntegerPredicate { bool Matches(int value) { return value > 3; } }
    • 13. int[] Filter(int[] ints, IIntegerPredicate predicate) {     ArrayList results = new ArrayList();     foreach (int i in ints)     { if (predicate.Matches(i)) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 14. int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints, new EvenPredicate()); int[] greaterThanThree = Filter(ints, new GreaterThanThreePredicate());
    • 15. interface IIntegerPredicate { bool Matches(int value); }
    • 16. bool delegate IntegerPredicate(int value);
    • 17. bool Even(int value) { return value % 2 == 0; }
    • 18. bool GreaterThanThree(int value) { return value > 3; }
    • 19. int[] Filter(int[] ints, IntegerPredicate predicate) {     ArrayList results = new ArrayList();     foreach (int i in ints)     {                 if (predicate(i)) { results.Add(i); }     }     return results.ToArray(typeof(int)); }
    • 20. int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints,  new IntegerPredicate(Even)); Int[] greaterThanThree = Filter(ints,  new IntegerPredicate(GreaterThanThree));
    • 21. C# 2.0  
    • 22. Inference int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints,  new IntegerPredicate(Even)); Int[] greaterThanThree = Filter(ints,  new IntegerPredicate(GreaterThanThree));
    • 23. Inference int[] ints = new int[] {1, 2, 3, 4, 5 }; int[] even = Filter(ints, Even); Int[] greaterThanThree = Filter(ints, GreaterThanThree); The compiler can infer what the type of the delegate is so we don’t have to write it.
    • 24. Generics delegate bool IntegerPredicate(int value);
    • 25. Generics delegate bool Predicate<T> (T value);
    • 26. Generics int[] Filter(int[] ints, IntegerPredicate predicate) { ArrayList results = new ArrayList(); foreach (int i in ints) { if (predicate(i)) { results.Add(i); } } return results.ToArray(typeof(int)); }
    • 27. Generics T[] Filter<T>(T[] values, Predicate<T> predicate) { List<T> results = new List<T>(); foreach (T i in value) { if (predicate(i)) { results.Add(i); } } return results.ToArray(); }
    • 28. Generics IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> predicate) { List<T> results = new List<T>(); foreach (T i in value) { if (predicate(i)) { results.Add(i); } } return results; }
    • 29. Iterators IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> predicate) { List<T> results = new List<T>(); foreach (T i in value) { if (predicate(i)) { results.Add(i); } } return results; }
    • 30. Iterators IEnumerable<T> Filter<T>(IEnumerable<T> values, Predicate<T> predicate) { foreach (T i in value) { if (predicate(i)) { yield return i; } } }
    • 31. Anonymous Methods IEnumerable<int> greaterThanThree = Filter(ints, GreaterThanThree);
    • 32. Anonymous Methods IEnumerable<int> greaterThanThree = Filter(ints, delegate(int value) { return value > 3; });
    • 33. Anonymous Methods int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, delegate(int value) { return value > minimumValue; }); Anonymous methods add support for closures. The delegate captures the scope it was defined in.
    • 34. C# 3.0  
    • 35. Lambdas int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, delegate(int value) { return value > minimumValue; });
    • 36. Lambdas int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, value => value > minimumValue);
    • 37. More Type Inference int minimumValue = 3; IEnumerable<int> greaterThanThree = Filter(ints, value => value > minimumValue);
    • 38. More Type Inference int minimumValue = 3; var greaterThanThree = Filter(ints, value => value > minimumValue);
    • 39. Extension Methods int minimumValue = 3; var greaterThanThree = Filter(ints, value => value > minimumValue);
    • 40. Extension Methods int minimumValue = 3; var greaterThanThree = ints.Filter(value => value > minimumValue);
    • 41. Anonymous Types var anonymous = new { Foo = 1, Bar = “Bar” }
    • 42. LINQ
    • 43. LINQ New delegates in System namespace Action<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc.
    • 44. LINQ New delegates in System namespace Action<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc. System.Linq Extension methods Where, Select, OrderBy etc.
    • 45. LINQ New delegates in System namespace Action<T>, Action<T1, T2>, Func<TResult>, Func<T1, TResult> etc. System.Linq Extension methods Where, Select, OrderBy etc.   Some compiler magic to translate sql style code to method calls
    • 46. LINQ var even = ints.Where(value => value % 2 == 0)   var greaterThanThree = ints.Where(value => value > minimumValue)   or var even = from value in ints                   where value % 2 == 0                   select value   var greaterThanThree = from value in ints                                         where value > minimumValue                                                   select value                                       
    • 47. A (little) bit of theory
    • 48. http://www.flickr.com/photos/stuartpilbrow/2938100285/sizes/l/
    • 49. Higher order functions
    • 50. Immutability
    • 51. Lazy evaluation
    • 52. Recursion & Pattern Matching
    • 53. Transformational Mindset We can just pass functions around instead in most cases - find an example where it still makes sense to use the GOF approach though.
    • 54. Input -> ??? -> ??? -> ??? ->  Output
    • 55. http://www.emt-india.net/process/petrochemical/img/pp4.jpg
    • 56. So why should you care?
    • 57. Functional can fill in the gaps in OO code  
    • 58. Abstractions over common operations means less code and less chances to make mistakes
    • 59. So what do we get out of the box?
    • 60. Projection
    • 61.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>  people.Select(person =&gt; person.Name) </li></ul><ul><li>  </li></ul><ul><li>  </li></ul>
    • 62.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.SelectMany(person =&gt; person.Pets) </li></ul>
    • 63. Restriction  
    • 64.   <ul><li>         </li></ul><ul><li>  </li></ul><ul><li>people.Where(person =&gt; person.HasPets) </li></ul><ul><li>  </li></ul>
    • 65. Partitioning  
    • 66.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Take(5) </li></ul>
    • 67.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Skip(5) </li></ul>
    • 68.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>             people.TakeWhile(person =&gt;  </li></ul><ul><li>                             person.Name != &amp;quot;David&amp;quot;) </li></ul>
    • 69.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>             people.SkipWhile(person =&gt;  </li></ul><ul><li>                                 person.Name != &amp;quot;David&amp;quot;) </li></ul>
    • 70. Set  
    • 71.   <ul><li>people.Select(person =&gt; person.Name) </li></ul><ul><li>.Distinct() </li></ul>
    • 72.   <ul><li>  people.Union(someOtherPeople) </li></ul><ul><li>  </li></ul>
    • 73.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Intersect(someOtherPeople) </li></ul>
    • 74.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Except(someOtherPeople) </li></ul>
    • 75. Ordering and Grouping  
    • 76.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.OrderBy(person =&gt; person.Name) </li></ul><ul><li>  </li></ul><ul><li>  </li></ul>
    • 77.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.GroupBy(person =&gt; person.Name) </li></ul>
    • 78. Aggregation  
    • 79.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Count() </li></ul>
    • 80.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Select(person =&gt; person.Age) </li></ul><ul><li>.Sum() </li></ul>
    • 81.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Select(person =&gt; person.Age) </li></ul><ul><li>.Min() </li></ul>
    • 82.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Select(person =&gt; person.Age) </li></ul><ul><li>.Max() </li></ul>
    • 83.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>people.Select(person =&gt; person.Age) </li></ul><ul><li>.Average() </li></ul>
    • 84.   <ul><li>Things can get more complex </li></ul>
    • 85.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>       people.Select(person =&gt; person.Age) </li></ul><ul><li>             .Aggregate(0, (totalAge, nextAge) =&gt;  </li></ul><ul><li>                     nextAge % 2 == 0  </li></ul><ul><li>                         ? nextAge + totalAge  </li></ul><ul><li>                         : totalAge) </li></ul>
    • 86.   <ul><li>  </li></ul><ul><li>  </li></ul><ul><li>        people.Join(addresses,           </li></ul><ul><li>                person =&gt; person.PersonId,   </li></ul><ul><li>                 address =&gt; address.PersonId,      </li></ul><ul><li>                (person, address) =&gt; new {  </li></ul><ul><li>                                         person, address}) </li></ul>
    • 87. We can just pass functions around instead in most cases - find an example where it still makes sense to use the GOF approach though.
    • 88. &nbsp;
    • 89.   <ul><li>  </li></ul>public class SomeObject { private readonly IStrategy strategy; public SomeObject(IStrategy strategy) { this.strategy = strategy; } public void DoSomething(string value) { strategy.DoSomething(value); } }
    • 90.   <ul><li>  </li></ul>public class Strategy : IStrategy { public void DoSomething(string value) { // do something with string } }
    • 91.   <ul><li>  </li></ul>public class SomeObject { private readonly Action&lt;string&gt; strategy; public SomeObject(Action&lt;string&gt; strategy) { this.strategy = strategy; } public void DoSomething(string value) { strategy(value); } }
    • 92.   <ul><li>Hole in the middle pattern </li></ul>
    • 93.   <ul><li>  </li></ul>public class ServiceCache&lt;Service&gt; { protected Res FromCacheOrService            &lt;Req, Res&gt;(Func&lt;Res&gt; serviceCall, Req request) {      var cachedRes = cache.RetrieveIfExists( typeof(Service), typeof(Res), request);   if(cachedRes == null)   { cachedRes = serviceCall(); cache.Add(typeof(Service), request, cachedRes); }      return (Res) cachedRes; } }
    • 94.   <ul><li>  </li></ul>public class CachedService : ServiceCache&lt;IService&gt; { public MyResult GetMyResult(MyRequest request) {           return FromCacheOrService(()                   =&gt; service.GetMyResult(request), request); } }
    • 95.   <ul><li>Passing functions around </li></ul>
    • 96. <ul><li>  </li></ul>private void AddErrorIf&lt;T&gt;(Expression&lt;Func&lt;T&gt;&gt; fn, ModelStateDictionary modelState, Func&lt;ModelStateDictionary, Func&lt;T,string, string, bool&gt;&gt; checkFn) { var fieldName = ((MemberExpression)fn.Body).Member.Name; var value = fn.Compile().Invoke(); var validationMessage = validationMessages[fieldName]); checkFn.Invoke(modelState)(value, fieldName, validationMessage); } AddErrorIf(() =&gt; person.HasPets, modelState, m =&gt; (value, field, error) =&gt; m.AddErrorIfNotEqualTo(value,true, field, error)); AddErrorIf(() =&gt; person.HasChildren, modelState, m =&gt; (value, field, error) =&gt; m.AddErrorIfNull(value, field, error));
    • 97.   <ul><li>Continuation Passing Style </li></ul>
    • 98. <ul><li>  </li></ul>static void Identity&lt;T&gt;(T value, Action&lt;T&gt; k) { k(value); }
    • 99. <ul><li>  </li></ul>Identity(&amp;quot;foo&amp;quot;, s =&gt; Console.WriteLine(s));
    • 100. <ul><li>  </li></ul>Identity(&amp;quot;foo&amp;quot;, s =&gt; Console.WriteLine(s)); as compared to var foo = Identity(“foo”); Console.WriteLine(foo);
    • 101. <ul><li>  </li></ul>public ActionResult Submit(string id, FormCollection form) {    var shoppingBasket = CreateShoppingBasketFrom(id, form);      return IsValid(shoppingBasket, ModelState,          () =&gt; RedirectToAction(&amp;quot;index&amp;quot;, &amp;quot;ShoppingBasket&amp;quot;, new { shoppingBasket.Id} ),   () =&gt; LoginUser(shoppingBasket,                  () =&gt;                  {                    ModelState.AddModelError(&amp;quot;Password&amp;quot;, &amp;quot;User name/email address was incorrect - please re-enter&amp;quot;);                      return RedirectToAction(&amp;quot;index&amp;quot;, &amp;quot;&amp;quot;ShoppingBasket&amp;quot;, new { Id = new Guid(id) });                 }, user =&gt;                  {                    shoppingBasket.User = user;                      UpdateShoppingBasket(shoppingBasket);                      return RedirectToAction(&amp;quot;index&amp;quot;, &amp;quot;Purchase&amp;quot;,    new { Id = shoppingBasket.Id }); }         )); }
    • 102. <ul><li>  </li></ul>private RedirectToRouteResult IsValid(ShoppingBasket shoppingBasket,                                       ModelStateDictionary modelState,                                        Func&lt;RedirectToRouteResult&gt; failureFn,                      Func&lt;RedirectToRouteResult&gt; successFn) {   return validator.IsValid(shoppingBasket, modelState) ? successFn() : failureFn(); }   private RedirectToRouteResult LoginUser(ShoppingBasket shoppingBasket,                                                                  Func&lt;RedirectToRouteResult&gt; failureFn,                                                                Func&lt;User,RedirectToRouteResult&gt; successFn) { User user = null; try { user = userService.CreateAccountOrLogIn(shoppingBasket); }   catch (NoAccountException) { return failureFn(); }   return successFn(user); }
    • 103. <ul><li>  </li></ul>http://www.thegeekshowpodcast.com/home/mastashake/thegeekshowpodcast.com/wp-content/uploads/2009/07/wtf-cat.jpg
    • 104. So what could possibly go wrong?   http://icanhascheezburger.files.wordpress.com/2009/06/funny-pictures-cat-does-not-think-plan-will-fail.jpg
    • 105. Hard to diagnose errors  
    • 106. var people = new [] { new Person { Id=1, Address = new Address { Road = &amp;quot;Ewloe Road&amp;quot; }}, new Person { Id=2}, new Person { Id=3, Address = new Address { Road = &amp;quot;London Road&amp;quot;}} }; people.Select(p =&gt; p.Address.Road); 
    • 107. Null Reference Exception on line 23
    • 108. http://www.flickr.com/photos/29599641@N04/3147972713/
    • 109. public T Tap(T t, Action action)  {     action();     return t; }
    • 110. people     .Select(p =&gt; Tap(p, logger.debug(p.Id))     .Select(p =&gt; p.Address.Road); 
    • 111. Readability  
    • 112. Lazy evaluation can have unexpected consequences  
    • 113.   <ul><li>        IEnumerable&lt;string&gt; ReadNamesFromFile()         {             using(var fileStream = new FileStream(&amp;quot;names.txt&amp;quot;, </li></ul><ul><li>                                                         FileMode.Open))             using(var reader = new StreamReader(fileStream))             {                 var nextLine = reader.ReadLine();                 while(nextLine != null)                 {                     yield return nextLine;                     nextLine = reader.ReadLine();                 }             }         } </li></ul>
    • 114.   <ul><li>        IEnumerable&lt;Person&gt; GetPeople()         {             return ReadNamesFromFile() </li></ul><ul><li>                     .Select(name =&gt; new Person(name));         } </li></ul>
    • 115.   <ul><li>      IEnumerable&lt;Person&gt; people = GetPeople();           foreach (var person in people)      {          Console.WriteLine(person.Name);      }       </li></ul><ul><li>     Console.WriteLine(&amp;quot;Total number of people: &amp;quot; + </li></ul><ul><li>                                     people.Count()); </li></ul>
    • 116. Encapsulation is still important  
    • 117.   <ul><li>Total salary for a company </li></ul><ul><li>  </li></ul><ul><li>company.Employees.Select(employee =&gt; </li></ul><ul><li>                                             employee.Salary)  </li></ul><ul><li>                                 .Sum() </li></ul><ul><li>This could lead to duplication </li></ul><ul><li>What if we add rules to the calculation? </li></ul><ul><li>Who should really have this responsibility? </li></ul><ul><li>.Sum() </li></ul>
    • 118. Linq isn&apos;t the problem here, it&apos;s where we have put it  
    • 119. Company naturally has the responsibility so encapsulate the logic here
    • 120. <ul><li>class Company </li></ul><ul><li>{ </li></ul><ul><li>    public int TotalSalary </li></ul><ul><li>    { </li></ul><ul><li>        get  </li></ul><ul><li>        { </li></ul><ul><li>            return employees.Select(e =&gt; </li></ul><ul><li>                                     e.Salary).Sum(); </li></ul><ul><li>        } </li></ul><ul><li>    } </li></ul><ul><li>} </li></ul>
    • 121. Sometimes we need to go further  
    • 122. If both Company and Division have employees do we duplicate the logic for total salary?
    • 123. IEnumerable&lt;T&gt; and List&lt;T&gt; make collections easy but sometimes it is still better to create a class to represent a collection
    • 124.   <ul><li>class EmployeeCollection </li></ul><ul><li>{ </li></ul><ul><li>    private List&lt;Employee&gt; employees; </li></ul><ul><li>  </li></ul><ul><li>     public int TotalSalary </li></ul><ul><li>    { </li></ul><ul><li>        get </li></ul><ul><li>         { </li></ul><ul><li>            return employees.Select(e =&gt; e.Salary).Sum(); </li></ul><ul><li>         } </li></ul><ul><li>    } </li></ul><ul><li>} </li></ul>
    • 125. In conclusion…  
    • 126.  
    • 127. Mike Wagg mikewagg.blogspot.com [email_address] Mark Needham markhneedham.com [email_address]

    ×