Tuesday, April 28, 2009

LINQ - the mathematical aspect

One of my colleague remarked that LINQ is "VERY SIMILAR" to TSQL. However, he also cursed that why the LINQ guys have implemented it "reversely".
What he meant that why the Select is reversed…

SQL query will be

   1: Select Name from Employee where sal > 80000 




LINQ





   1: var q = from emp in Employee



   2:         where emp.sal > 80000



   3:         Select emp;




I cant help but giving him references to Korth & Sudarshan and mathematical Projections…



That also reminded me of taking a quick tour of algebra which i am posting over here.. hope it helps in rekindling some old memories…:D



Koncepts first..



Technorati Tags:


Idempotent: when the operation (on function)is performed the result remains unchanged, no matter how many times it gets performed. For example, the number 1 is an idempotent of multiplication: 1 × 1 = 1, also max(x, x) = x. More info over here. Think stability.



Closure: the smallest object that both includes the object as a subset and possesses some given property. E.g.: x + y = z; where x,y,z are Natural numbers . adding two natural numbers to get another natural number. This operation may go on for ever.


However consider x-y=z. Here if we consider x=2, y=1 then



2-1=1. Which is NOT Closure (from one end) as the above function may produce negative values. e.g. given x=1 and y=2… which yields 1-2 = –1.



Think anonymous functions or inner classes. Because of closure property the inner class . function may access the members of the enclosing class.



THINK IQueryable<T> of LINQ. It provides for domain-level closure.



The combination of above two Idempotent and closure makes algebra complex and LINQ a great fun!!!



Because of the above two we have function composition, in which output of function may be linked to input of other and so on..



IQueryables can be combined together to create new IQueryables that also yield sequences of T. LINQ is closed on both levels. It’s closed at the level of the entities that it is retrieving, but it’s also closed at the level of the functions it uses to represent queries.



Interestingly speaking, NON closure of any function have given birth to new concepts… like NON- closure of substraction of NATURAL numbers gave birth to concept of WHOLE NUMBERS..



Associativity: The composition of functions is always associative. That is, if f, g, and h are three functions with suitably chosen domains and codomains, then f ∘ (gh) = (fg) ∘ h. Since there is no distinction between the choices of placement of parentheses, they may be safely left off.



The above three concept along with concept of Inversibility provides an base of MONAD (Category theory) and thus functional programming. Quoting wiki:



If F and G are a pair of adjoint functors, with F left adjoint to G, then the composition G \circ F is a monad. Therefore, a monad is a functor from a category to itself. If F and G are inverse functors the corresponding monad is the identity functor.



in C# 3.0 queries are actually monad comprehensions in disguise.



using Lambdas




   1: var r = 1.ToIdentity()



   2:          .SelectMany(x => 2.ToIdentity(), (x, y) => x + y);



   3:  



   4: Console.WriteLine(r.Value);








using LINQ





   1: var r = from x in 1.ToIdentity()



   2:         from y in 2.ToIdentity()



   3:         select x + y;








Now; coming back to original question:  why the Select is reversed in LINQ..



Actually LINQ to objects queries are analogous to the relational algebra and therefore they are not as much declarative in nature as they are a specification of a series of operations.



1.  Each query clause is evaluated independently of the previous clauses.  Only the binding information flows between them. (Idempotent) :D



2.  The clauses are evaluated in order, hinting at imperative evaluation. (Closure) :D



therefore, the performance of LINQ is based upon the order of clauses.



As it is evident from the above discussion that LINQ works in a fashion that output of one function is input to another… In above LINQ example select clause is used AFTER from clause. Which means output from from is fed into select for filtering and projection of results.



You can refer more from here.



Do let me know your thoughts/ suggestions on same.



Happy LINQing… :D





Technorati Tags:

No comments: