310 likes | 328 Views
Learn about the ROX Triangle of Doom, a powerful data model and query syntax for working with objects, relations, and SQL. Explore features such as selecting, filtering, mapping, and aggregating data, as well as LINQ queries and monads.
E N D
The ROX TriangleOf Doom XML Objects Relations
SQL = data model + query syntax Select Name, Age From CustomersWhere City = "Seattle" Table of rows
XQuery/XPath = data model + query syntax From $C In CustomersWhere $C/City = "Seattle"Return<CustName={$C/Name}> { $C/Age }</Cust> Set of nodes
Objects = data model + query syntax Foreach C In Customers If C.City="Seattle"R.Add(New With {C.Name, C.Age})End IfNext Collection of objects
LINQ = Queries Over Arbitrary Collections of Arbitrary Values
T (T Bool) T Filtering 2 2 0 3 X Mod 2 = 0 0 3 6 5 6 5 1 1 4 4
Mapping T (T S) S 2 4 X * 2 0 3 0 6 6 5 12 10 1 2 4 8
Aggregating T (S, (S,T) S) S 2 Sum 0 3 6 5 21 1 4 T ((T,T) T) T
Observation Many ways to skin a cat several different choices for "basis" functions. Need other operations Sorting, grouping, … Independent of collection type Independent of element type S, TIndependent of function type (mostly)
Monads ! A container type ℳ<T> A function type ST A constructor ℳ<T> Unit<T>(T src) ℳ<T> SelectMany<S,T> (ℳ<S> src, Sℳ<T> f) A composer
Monads ! IEnumerable<T> IQueryable<T> ℳ<T> Func<S,T>Expr<Func<S,T>> ST ℳ<T> Unit<T>(T src) ℳ<T> SelectMany<S,T> (ℳ<S> src, Sℳ<T> f) Standard Query Pattern(generics not expressive enough)
LINQ Project == monad comprehensions in C# & VB VB 9 C# 3.0 … StandardQueryOperators DLinq(relational) XLinq(xml) LINQ Framework
C# 3.0 and Visual Basic 9 Facilitate LINQ Using general purpose language constructs Without changing the CLR
Features • Local Type Inference • Object & Collection Initializers • Anonymous Types • Lambda Expressions • Query Comprehensions • Extension Methods • Expression Trees • Simplified Properties • Partial Methods • Deep XML Support (VB) • Nullable Types (VB) Enables Language Extensions via libraries
Local Type Inference No unification Dim X As String Dim X = "Hello OOPSLA" X = New Button() Dim B As Object = New Button()B.Foo() Cannot assign to non-convertible type ~~~~~~~~~~~ Opt-in Late Binding
Object Initializers Class Line S As Point E As PointEnd Class Class Point X AsInteger Y AsIntegerEnd ClassDim L = New Line With { .S = New Point With { X := 0, Y := 1 }, .E = New Point With { X := 47, Y := 11 } }
Extension Methods Dim Contacts = _ Customers.Where(P).Select(R) Module MyExtensions<Runtime.CompilerServices.Extension()> _ Function Where(Of T)( _ [Me] As IEnumerable(Of T), _ P As Func(Of T, Boolean)) _As IEnumerable(Of T) … End Module Just CA
Lambda Expressions Dim F As Func(OfInteger, Boolean) =_Function(X) X > 10 Dim H = Function(X) X > 10 G As Func(Of Integer, Boolean)
LINQ on Objects standard rich collection library with deep language support
Lazy evaluation! IEnumerable<double>xs; try { xs = from x innew []{ 0,1,2 }select x/x; } catch(Exception e) { … } var bomb = xs.First();
Joins var xs = new[] {1,2,3,4,5}; var ys = new[] {11,12,13,14,15}; var zs = xs.Join(ys,x => x%2 == 0, y=> y%2 == 0, (x,y) => new {x,y}); foreach(var z in zs){ Console.WriteLine("x={0}, y={1}",z.x, z.y); } var rs = xs.GroupJoin(ys,x => x%2 == 0, y => y%2 == 0, (a,b) => new {x=a, ys=b}); foreach(var r in rs){ Console.WriteLine("x={0}",r.x); foreach(var y in r.ys) Console.WriteLine("y={0}",y); } }
Expression trees Expression<Func<int,int>> f = x => x+1; Console.WriteLine(f); Func<int,int> g = f.Compile(); Console.WriteLine(g(3));
IQueryable Parallel implementation of all IEnumerable extensions, however, they take Expression trees as arguments static IQueryable<T> Where<T>( this IQueryable<T> src, Expression<Func<T, bool>> p); Standard implementation builds expression tree representing itself
IQueryable interface IQueryable : IEnumerable { Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; } } interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable {}
IQueryable static IQuerable<T> AsQueryable<T> (this IEnumerable<T> scr); Default implementation of IQueryable
var xs = new [] {1,2,3, 4, 5, 6 }; IQueryable<int> ys = xs.AsQueryable(); var zs = ys.Where(x => x > 2); var e = zs.Expression; Console.WriteLine(e); foreach(var z in zs) { Console.WriteLine(z); } System.Int32[].Where(x => GT(x, 2))
IQueryProvider interface IQueryProvider { IQueryable CreateQuery (Expression e); IQueryable<T> CreateQuery<T> (Expression e); object Execute(Expression e); T Execute<T> (Expression e); }