32
LinQ Why we have to teach functional programmming Axel T. Schreiner http://www.cs.rit.edu/~ats/talks/linq/ http://www.cs.rit.edu/~ats/cs-2006-1/14_linq.pdf

LinQ - Computer Scienceats/talks/linq/linq.pdf · cs-2006-1 10/30/06 linq-Principles Map a query language to cascading method calls. Implement the necessary methods for IEnumerable,

  • Upload
    others

  • View
    21

  • Download
    0

Embed Size (px)

Citation preview

LinQWhy we have to teach functional programmming

Axel T. Schreinerhttp://www.cs.rit.edu/~ats/talks/linq/

http://www.cs.rit.edu/~ats/cs-2006-1/14_linq.pdf

cs-2006-1 10/30/06 linq-

Principles

Map a query language to cascading method calls.

Implement the necessary methods for IEnumerable, XML- and database-access.

Sugar syntax liberally.

2

cs-2006-1 10/30/06 linq-

What if...

Syntactic sugar patterned after SQL.

3

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( from x in staff where x.phone % 2 == 0 orderby x.last select new { x.first, x.phone });

cs-2006-1 10/30/06 linq-

What if...

Syntactic sugar patterned after SQL.

Actions converted into messages,Expressions converted into functions.

4

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( from x in staff where x.phone % 2 == 0 orderby x.last select new { x.first, x.phone });

cs-2006-1 10/30/06 linq-

What if...

Functional style [Eric Meijer]:

function as arguments,function composition for actions.

Anonymous class new { field ,... }.

5

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( staff .Where(x => x.phone % 2 == 0) .OrderBy(x => x.last) .Select(x => new { x.first, x.phone }));

cs-2006-1 10/30/06 linq-

Typing

6

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( staff .Where(x => x.phone % 2 == 0) .OrderBy(x => x.last) .Select(x => new { x.first, x.phone }));

class C<T> { delegate R Func<R, T> (T arg); C<T> Where (Func<bool, T> predicate); C<T> OrderBy<K> (Func<K, T> keySelector); C<U> Select<U> (Func<U, T> selector);}

cs-2006-1 10/30/06 linq-

Typing

7

class C<T> { delegate R Func<R, T> (T arg); C<T> Where (Func<bool, T> predicate); C<T> OrderBy<K> (Func<K, T> keySelector); C<U> Select<U> (Func<U, T> selector);}

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( staff .Where(x => x.phone % 2 == 0) .OrderBy(x => x.last) .Select(x => new { x.first, x.phone }));

cs-2006-1 10/30/06 linq-

Typing

8

class C<T> { delegate R Func<R, T> (T arg); C<T> Where (Func<bool, T> predicate); C<T> OrderBy<K> (Func<K, T> keySelector); C<U> Select<U> (Func<U, T> selector);}

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( staff .Where(x => x.phone % 2 == 0) .OrderBy(x => x.last) .Select(x => new { x.first, x.phone }));

cs-2006-1 10/30/06 linq-

Typing Pattern

9

class C<T> { delegate R Func<R, T> (T arg); C<T> Where (Func<bool, T> predicate); C<T> OrderBy<K> (Func<K, T> keySelector); C<U> Select<U> (Func<U, T> selector);}

struct Person { string first, last; int phone; }IContainer<Person> staff = ...Console.WriteLine( staff .Where(x => x.phone % 2 == 0) .OrderBy(x => x.last) .Select(x => new { x.first, x.phone }));

cs-2006-1 10/30/06 linq-

Query Expression Pattern

10

from join... introduce iteration variable(s)

fromlet ...where

introduces iteration variable(s)introduces variablefilters

orderby rearranges sequence

selectgroup by

produces flat resultproduces structured result

into join...

produces iteration variable(s) to start over

cs-2006-1 10/30/06 linq-

Query Class Pattern

11

from join...

class C<T> { C<V> Join (...) C<V> GroupJoin (...)

fromlet ...where

C<T> Where (...)

orderby

O<T> OrderBy[Descending] (...) class O<T> : C<T> { O<T>ThenBy[Descending] (...) }

selectgroup by

C<U> Select[Many] (...) C<G<Key,E>> GroupBy (...) class G<Key,E> : C<E> {...}

into join...

cs-2006-1 10/30/06 linq-

from let where ... / Where

13

from x in xs

where f

xs.Where(x => f)

retains only records satisfying a condition.

let x = e

defines name for value.

delegate R Func<R,A> (A a);

IEnumerable<T> Where<T> (IEnumerable<T> container, Func<bool,T> predicate) { foreach (var c in container) if (predicate(c)) yield return c;}

Implementation

public interface Func<R,A> { R f (A a); }public<T> Iterable<T> where (Iterable<T> container, Func<Boolean,T> predicate) { List<T> result = newList(); for (T c: container) if (predicate.f(c)) result.add(c); return result;}

delegate R Func<R,A> (A a);

IEnumerable<T> Where<T> (IEnumerable<T> container, Func<bool,T> predicate) { foreach (var c in container) if (predicate(c)) yield return c;}

Implementation

int[] xs = { 1, 2, 3, 4, 5 };

from x in xs where x % 2 == 0 select x

Where(xs, x => x % 2 == 0)

Use

List<Integer> xs = Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5});where(xs, new Func<Boolean,Integer>() { public Boolean f (Integer x) { return x % 2 == 0; }})

int[] xs = { 1, 2, 3, 4, 5 };

from x in xs where x % 2 == 0 select x

Where(xs, x => x % 2 == 0)

Arrays are not Iterable.

Use

cs-2006-1 10/30/06 linq-

select / Select

16

from x in xs

select f

xs.Select(x => f)

creates new records.

delegate R Func<R,A> (A a);

IEnumerable<U> Select<U,T> (IEnumerable<T> container, Func<U,T> selector) { foreach (var c in container) yield return selector(c);}

Implementation

public interface Func<R,A> { R f (A a); }public<U,T> Iterable<U> select (Iterable<T> container, Func<U,T> selector) { List<U> result = newList(); for (T c: container) result.add(selector.f(c)); return result;

}

delegate R Func<R,A> (A a);

IEnumerable<U> Select<U,T> (IEnumerable<T> container, Func<U,T> selector) { foreach (var c in container) yield return selector(c);}

Implementation

cs-2006-1 10/30/06 linq-

select / Select[Many]

18

from x in xs

select f

xs.Select(x => f)

creates new records.

from x in xs

from y in ys

select f

xs.SelectMany(x => ys.Select(y => f))

creates new records.

delegate R Func<R,A> (A a);

IEnumerable<U> SelectMany<U,T> (IEnumerable<T> container, Func<IEnumerable<U>,T> selector) { foreach (var c in container) foreach (var u in selector(c)) yield return u;}

Implementation➦

public interface Func<R,A> { R f (A a); }public<U,T> Iterable<U> selectMany (Iterable<T> container, Func<Iterable<U>,T> selector) { List<U> result = newList(); for (T c: container) for (U u: selector.f(c)) result.add(u); return result;

}

delegate R Func<R,A> (A a);

IEnumerable<U> SelectMany<U,T> (IEnumerable<T> container, Func<IEnumerable<U>,T> selector) { foreach (var c in container) foreach (var u in selector(c)) yield return u;}

Implementation➦

int[] xs = { 1, 2, 3, 4, 5 };double[] ys = { 6.0, 7.0, 8.0, 9.0, 10.0 };

from x in xs where x > 3 from y in ys where y < 8.0 select new { y, x }

SelectMany(Where(xs, x => x > 3), x => Select(Where(ys, y => y < 8.0), y => new { y, x }))

Use

List<Integer> xs = Arrays.asList(new Integer[]{ 1, 2, 3, 4, 5});final List<Double> ys = Arrays.asList(new Double[]{ 6.0, 7.0, 8.0, 9.0, 10.0 });

selectMany( where(xs, new Func<Boolean,Integer>() { public Boolean f (Integer x) { return x > 3; } }), new Func<Iterable<HashMap<String,Object>>,Integer>() { public Iterable<HashMap<String,Object>> f (final Integer x) { return select( where(ys, new Func<Boolean,Double>() { public Boolean f (Double y) { return y < 8.0; } }), new Func<HashMap<String,Object>,Double>() { public HashMap<String,Object> f (Double y) { HashMap<String,Object> result = new HashMap<String,Object>(); result.put("y", y); result.put("x", x); return result; } }); } })

Teach functional!

A computer scientist invents this...

Action sequence: compositionCondition/selection: lambdas as argumentsNested selections: application of lambda Sorting: compose Comparator based on lambda arguments

No chance to see this in Java [56]...

Teach functional!

A computer scientist invents this...

Action sequence: compositionCondition/selection: lambdas as argumentsNested selections: application of lambda Sorting: compose Comparator based on lambda arguments

No chance to see this in Java [56]...

Teach functional!

A computer scientist invents this...

Action sequence: compositionCondition/selection: lambdas as argumentsNested selections: application of lambda Sorting: compose Comparator based on lambda arguments

No chance to see this in Java [56]...

Teach functional!

A computer scientist invents this...

Action sequence: compositionCondition/selection: lambdas as argumentsNested selections: application of lambda Sorting: compose Comparator based on lambda arguments

No chance to see this in Java [56]...

Teach functional!

A computer scientist invents this...

Action sequence: compositionCondition/selection: lambdas as argumentsNested selections: application of lambda Sorting: compose Comparator based on lambda arguments

No chance to see this in Java [56]...

Teach functional!

A computer scientist invents this...

Action sequence: compositionCondition/selection: lambdas as argumentsNested selections: application of lambda Sorting: compose Comparator based on lambda arguments

No chance to see this in Java [56]...

References

Erik Meijerhttp://research.microsoft.com/~emeijer/

C#: LinQhttp://msdn.microsoft.com/netframework/future/linq/

C# 3.0http://msdn2.microsoft.com/en-us/vcsharp/aa336745.aspx

Java 7: Closureshttp://www.javac.info/closures-v03.html