coding with linq, patterns & practices
DESCRIPTION
LINQ ja koodauskäytännöt (Finnish) http://www.youtube.com/watch?v=OFQltnLESOg Coding with LINQ, Patterns & Practices (English) http://www.youtube.com/watch?v=YAha8tQyVHE Slides: http://www.slideshare.net/thorium/coding-with-linq-patterns-practices --- LINQ:lle refaktorointi (Finnish) http://www.youtube.com/watch?v=2wpqydogdPw Refactoring to LINQ (English) http://www.youtube.com/watch?v=1gX0piE3xbk F#-koodaus (Finnish) http://www.youtube.com/watch?v=WgVcJitKUZ8 Coding F# (English) http://www.youtube.com/watch?v=OA-zLw7xJm4 Source code: https://github.com/Thorium/DemoTRANSCRIPT
Coding with LINQ, Patterns & Practices
LINQ & Functional ways
© Tuomas Hietanen (LGPLv3)
LINQ (Monads)
• Two types of functions
– Queries and Aggreagtes
QUERY: - returns another container of the same type
AGGREGATE: - returns result
(Wrapper) Wrapped type, In this case IEnumerable<T>
© Tuomas Hietanen
LINQ SELECT = LIST.MAP (Query)
MAP function:
IEnumerable< > IEnumerable< >
© Tuomas Hietanen
LINQ WHERE= LIST.FILTER (Query)
FILTER function:
IEnumerable< > IEnumerable< >
© Tuomas Hietanen
LINQ AGGREGATE= LIST.FOLD (Aggregate)
FOLD function:
IEnumerable< >
© Tuomas Hietanen
Other Aggregates (to make things easier)
Function Aggregate function
LIST.SUM Add every to
LIST.COUNT Add (+1) to
LIST.MAX Select bigger of or
...
© Tuomas Hietanen
LINQ SELECTMANY - Not pure, has many overrides
SELECT function:
IEnumerable< >
© Tuomas Hietanen
LINQ SELECTMANY - Not pure, has many overrides
SELECT function:
© Tuomas Hietanen
Old Legacy Way New C#, LINQ F#
var result = new List<T>(); foreach(var x in xs){ result.Add(...); ... }
var result = from x in xs select … //same as var result = xs.Select(x=>...);
let result = List.map (fun x -> ...) xs
foreach(var x in xs){ if(x=...){...} }
var result = from x in xs where … //same as var result = xs.Where(x=>...);
let result = List.filter(fun x -> ...) xs
var result = new T(); foreach(var x in xs){ result = ...; ... }
//many ways, based on var result = xs.Aggregate(…);
//many ways, based on let result = List.fold (fun f -> ...) xs //also supports unfold
foreach(var x in xs){ foreach(var y in ...){ .... } }
var result = from x in xs from y in … select … //same as var result = xs.SelectMany(...);
//SelectMany is not pure, so depends on situation. E.g. List.collect, or seq {...} let result = List.collect (fun x -> ...) xs © Tuomas Hietanen
Do use lists!
• Don’t return Null. Prefer throw InvalidOperationException on error and Enumerable.Empty<T>() on case of empty list
• Don’t modify collections, do use new ones list.RemoveAt(0)
newlist = list.Where(interestingItems => ...)
• Use IEnumerable<T> not List<T> or IList<T> – It is the baseclass and default for LINQ
– You can always say .toList() to evaluate the lazy collection.
© Tuomas Hietanen
Safe class design, avoid side effects
• Don’t reuse variables x = x + 1 y = x + 1
• Avoid global and class variables. Use method parameters – Better for function composition
• Don’t overcapuslate layers or class structures – No coding for fun: Focus on the functionality
• Declarative programming. – ”yield return” is ok in some cases, but not really
declarative.
• Also old design practices do still apply (=> FxCop).
© Tuomas Hietanen
F# list vs seq
• List is F# default
– Linked list
– Good for recursive methods
• Seq is IEnumerable<T>
– Lazy evaluation
– Good for .NET interop
© Tuomas Hietanen