Introducción a las Expresiones Lambda | 3
Lambda CalculusAlonzo Church (Junio 14, 1903 – Agosto 11, 1995)
Matemático y lógico norteamericano quien hizo grandes contribuciones a lógica matemática y a las fundaciones dela teoría computacional. Es más conocido por su tesisdel cálculo lambda (~1930-1950).
λf. λs.(f (s s)) λf. λx.xλe1. λe2.λec.((c e1) e2)
Introducción a las Expresiones Lambda | 4
Lisp (1958)
(filter (lambda (n) (= (remainder n 2) 0)) (list 1 2 3 4 5 6 7 8 9))
Introducción a las Expresiones Lambda | 5
SML (1973)
open Listfilter (fn n => n mod 2 = 0) [1,2,3,4,5,6,7,8,9]
Introducción a las Expresiones Lambda | 6
Haskell (1990)
filter (\n -> n `mod` 2 == 0) [1,2,3,4,5,6,7,8,9]
Introducción a las Expresiones Lambda | 7
Python (1991)
filter ( (lambda n: n % 2 == 0), [1,2,3,4,5,6,7,8,9])
Introducción a las Expresiones Lambda | 8
JavaScript (1994)
[1,2,3,4,5,6,7,8,9].filter( function(n) {
return n % 2 === 0;});
Introducción a las expresiones Lambda | 10
Scala (2003)
List(1,2,3,4,5,5,6,7,8,9) filter(n => n % 2 == 0)
Introducción a las Expresiones Lambda | 11
C# (since 3.0 / 2007)
Enumerable.Range(1, 9) .Where(n => n % 2 == 0);
Introducción a las Expresiones Lambda | 12
Java (since 8.0 / 2013 – y 55 años después)
asList(1,2,3,4,5,6,7,8,9) .stream() .filter(n -> n % 2 == 0);
Programación de Orden Superior| 14
Filter
fun even(n) = n mod 2 = 0fun odd(n) = n mod 2 <> 0
filter(even, [1,2,3,4,5]) //[2,4]filter(odd, [1,2,3,4,5]); //[1,3,5]
filter(fn n => n mod 5 = 0, [1,2,3,4,5]) //[5]
Programación de Orden Superior| 15
Predicateinterface Predicate<T> { public boolean test(T t);}
static <T> List<T> filter(Predicate<T> pred, List<T> source) { List<T> destiny = new ArrayList<>(); for(T item : source) { if(pred.test(item)) { //! destiny.add(item); } } return destiny;}
Programación de Orden Superior| 16
Filter
filter(new Predicate<Integer>() { @Override public boolean test(Integer n) { return n % 2 != 0; } }, asList(1,2,3,4,5)); //1,3,5
filter( n -> n % 2!=0, asList(1,2,3,4,5)); //1,3,5
Programación de Orden Superior | 17
Map
fun square(n) = n * nfun fact(n) = if n = 0 then 1 else n * fact(n-1)
map(square, [1,2,3,4,5]) //[1,4,9,16,25]map(fact, [1,2,3,4,5]); //[1,2,6,24,120]
Programación de Orden Superior | 18
Function
interface Function<T,R> { public R apply(T t);}
static <T,R> List<R> map(Function<T,R> func, List<T> source) { List<R> destiny = new ArrayList<>(); for(T item : source) { R value = func.apply(item); //! destiny.add(value); } return destiny;}
Programación de Orden Superior | 19
Map
map(new Function<Integer, Integer>() { @Override public Integer apply(Integer n) { return n * n; } }, asList(1,2,3,4,5)); //1,4,9,16,25
map(n -> n * n, asList(1,2,3,4,5)); //1,4,9,16,25
Funciones de Orden Superior | 20
Reduce
fun sum(x, y) = x + yfun prod(x, y) = x * y
reduce(sum, 0, [1,2,3,4,5]) //15reduce(prod, 1, [1,2,3,4,5]); //120
reduce(fn (a,b) => a ^ b, “”, [“h”, “o”, “l”, “a”]) //“hola”
Funciones de Orden Superior | 21
Binary Operator
interface BinaryOperator<T> { public T apply(T left, T right);}
static <T> T reduce(BinaryOperator<T> oper, T seed, List<T> source) { for(T item : source) { seed = oper.apply(seed, item); //! } return seed;}
Funciones de Orden Superior | 22
Reduce
reduce(new BinaryOperator<Integer>() { @Override public Integer apply(Integer left, Integer right) { return left + right; } } ,0, asList(1,2,3,4,5)); //15
reduce((left,right) -> left + right, 0, asList(1,2,3,4,5)); //15
Programación de Orden Superior | 23
Consumer
interface Consumer<T> { public void accept(T t);}
static <T> void forEach(Consumer<T> consumer, List<T> source) { for(T item : source) { consumer.accept(item); //! }}
Programación de Orden Superior | 24
forEach
List<Integer> numbers = asList(1,2,3,4,5,6,7,8,9);
forEach( new Consumer<Integer>() { @Override public void accept(Integer n) { System.out.println(n); } }, numbers);
forEach( n -> { System.out.println(n); }, numbers);
Funciones de Orden Superior | 25
Evaluación Estrictapublic static int calculateX() { //algunos cálculos… return 0;}
public static int calculateY() { //cálculo pesado… return 1;}
public static int calculate(int x, int y) { if(x <= 0) return 0; else return x + y;}//…calculate( calculateX(), calculateY() ); //!
Funciones de Orden Superior | 27
Evaluación Perezosapublic static int calculate(Supplier<Integer> thunkOfX, Supplier<Integer> thunkOfY) { int x = thunkOfX.get(); if(x <= 0) return 0; else return x + thunkOfY.get();}
calculate( new Supplier<Integer>() { @Override public Integer get() { return generateX(); } }, new Supplier<Integer>() { @Override public Integer get() { return generateY(); } });
Programación de Orden Superior | 28
Evaluación Perezosa
public static int calculate(Supplier<Integer> thunkOfX, Supplier<Integer> thunkOfY) { int x = thunkOfX.get(); if(x <= 0) return 0; else return x + thunkOfY.get();}
calculate( () -> generateX() , () -> generateY() );
Programación de Orden Superior | 29
Interfaces Funcionales
Predicate<T>
Function<T,R>
BinaryOperator<T>
Comparator<T
>Consumer<T>
Supplier<T>
Runnable
Callable<T>ActionListener<T>
Programación de Orden Superior | 30
Sintaxis Lambda
Interfaz Funcional
Firma del Método Sintaxis de la Expresión Lambda
Predicate<T> public boolean test(T t) n -> n % 2 != 0
BinaryOperator<T> public T apply(T l, T r) (x,y) -> x + y
Supplier<T> public T void get() () -> “Hola Mundo!”
Consumer<T> public void accept(T t) s -> { System.out.println(s); }
Runnable public void run() () -> { System.out.println(“Hola”); }
Programación de Orden Superior | 31
Streams
List<Integer> numbers = asList(-1,-2,-3,-4,-5,-6,-7,-8,-9);
int sum = numbers.stream() .map(n -> Math.abs(n)) .filter(n -> n <= 5) .reduce(0, (x, y) -> x + y); //15
Referencias de Métodos | 33
Referencia Estática
static class IntPredicates { public static boolean isOdd(Integer n) { return n % 2 != 0; } public static boolean isEven(Integer n) { return n % 2 == 0; } public static boolean isPositive(Integer n) { return n >= 0; } public static boolean isPrime(Integer n) { … }}List<Integer> numbers = asList(1,2,3,4,5,6,7,8,9);
List<Integer> odds = filter(IntPredicates::isOdd, numbers);List<Integer> evens = filter(IntPredicates::isEven, numbers);
interface Predicate<Integer> { public boolean test(Integer n);}
Referencias de Métodos | 34
Referencia de ConstructorList<String> digits = asList("1","2","3","4","5");List<Double> myDoubles = map(Double::new, digits);
class Jedi { private String name; private int power;
public Jedi(String name) { this(name, 10); }
public Jedi(String name, int power){ this.name = name; this.power = power; } //getters & setters}
List<String> names = asList("Jacen Solo","Jaina Solo","Anja Gallandro");List<Jedi> jedis = map(Jedi::new, names);
interface Function<String,Jedi> { public Jedi apply(String name);}
interface Function<String,Double> { public Dobule apply(String name);}
Referencias de Métodos | 35
Referencia de Instancia ArbitrariaList<Jedi> jedis = asList(new Jedi("Obi-wan", 80), new Jedi("Anakin", 25), new Jedi("Yoda", 500));
List<String> jedis = map(Jedi::getName, jedis);
class Jedi {
private String name; private int power;
public Jedi(String name, int power){ this.name = name; this.power = power; }
public String getName() { return this.name } //getters & setters}
interface Function<Jedi,String> { public String apply(Jedi jedi);}
Referencias de Métodos | 36
Referencia de Instancia EspecíficaList<String> names = asList("Obi-wan","Ankin","Yoda");forEach(System.out::println, names);
interface Consumer<String> { public void accept(String s);}
interface Consumer<Integer> { public void accept(Integer n);}
public static class Offset { private int offset;
public Offset(int offset){ this.offset = offset; }
public void printWithOffset(int number) { System.out.print(" " + (number + offset)); }}
Offset byTen = new Offset(10);Offset byFive = new Offset(5);
forEach(byTen::printWithOffset, asList(1,2,3)); //11 12 13forEach(byFive::printWithOffset, asList(1,2,3)); //6 7 8
Nueva API de Streams | 38
Ejemplo 1
List<Jedi> jedis = asList(new Jedi("Obi-wan", 80), new Jedi("Anakin", 25), new Jedi("Yoda", 500));
jedis.stream() .filter(j -> j.getPower() >= 50) .map(Jedi::getName) .forEach(System.out::println);
Nueva API de Streams | 39
Ejemplo 2List<Jedi> jedis = asList(new Jedi("Obi-wan", 80), new Jedi("Anakin", 25), new Jedi("Yoda", 500));
int sumOfAges = jedis.stream() .map(Jedi::getAge) // .filter(age -> age >= 50) .reduce(0, (x, y) -> x + y); //580
List<Integer> numbers = asList(-1,-2,-3,-4,-5,-6,-7,-8,-9);int sum = numbers.stream() .map(Math::abs) .filter(n -> n <= 5) .reduce(0, (x, y) -> x + y); //15
Nueva API de Streams | 40
Evaluación Perezosa
int[] nats = new int[19_999_999];for(int i=0; i < nats.length; i++) { nats[i] = i;}
IntStream primes = Arrays.stream(nats) .filter(Predicates::isPrime);
Nueva API de Streams | 41
Corto Circuito #1
int[] nats = new int[19_999_999];for(int i=0; i < nats.length; i++) { nats[i] = i;}
IntStream primes = Arrays.stream(nats) .filter(Predicates::isPrime);
OptionalInt firstPrime = primes.findFirst(); //!1if(firstPrime.isPresent()){ System.out.println(firstPrime.getAsInt()); //!2}
Nueva API de Streams | 42
Corto Circuito #2
int[] nats = new int[19_999_999];for(int i=0; i < nats.length; i++) { nats[i] = i;}
IntStream primes = Arrays.stream(nats) .filter(Predicates::isPrime);primes.limit(10) //! .forEach(System.out::println); //2,3,5,7,11…29
Nueva API de Streams | 43
Paralelismo
IntStream primes = Arrays.stream(nats) .parallel() //! .filter(Predicates::isPrime); OptionalInt maxPrime = primes.max(); if(maxPrime.isPresent()) { System.out.println(maxPrime.getAsInt()); //19999981}
Métodos Predeterminados
Métodos de Extension | 46
interface Warrior {
public default String fight() { return "Warriors fight"; }}
Escogiendo El Más Específico
Métodos de Extension | 47
interface Warrior {
public default String fight() { return "Warriors fight"; }}
interface Ninja extends Warrior {
public default String fight() { return Warrior.super.fight() + " and ninjas fight too"; }}
Lidiando con el Conflicto
Métodos de Extension | 48
interface Ninja extends Warrior {
public default String fight() { return Warrior.super.fight() + " and ninjas fight too"; }}
interface Samurai extends Warrior {
public default String fight() { return "Samurais are the best warriors"; }}
Paralelismo | 50
Ley de Moore
La ley de Moore es la observación de que a través de la historia de la computación el número de transistores en los circuitos integrados se duplica aproximadamente cada 2 años.
Ciclos de Reloj
Paralelismo | 51
Fuente: Herb Sutter (http://www.gotw.ca/publications/concurrency-ddj.htm)
Herb Sutter (Dr.Dobb’s, Marzo 2005)
Comenzando hoy, el almuerzo gratis del desempeño se terminó […] Si queremos que nuestras aplicaciones se beneficien de progresos en rendimiento exponencial en los nuevos procesadores, tendrá que ser mediante aplicaciones concurrentes bien escritas. Y eso se dice más fácil de lo que realmente es, porque no todos los problemas son inherentemente paralelizables y porque la programación concurrente es difícil.
Paralelismo| 52
La Revolución del ParalelismoMauriece Herlihy & Nir Shavit (2008)
La industria de la computación está sufriendo otra revolución, o al menos un vigoroso estremecimiento […] Los fabricantesprincipales de chips han dejado de intentar que los procesadores sean más veloces […] en su lugar están recurriendo a las arquitecturas multinúcleo […] haciendo la computación más efectiva por medio de explotar el paralelismo.
[…] esto tendrá un efecto profundo en la manera en comodesarrollamos el software […] Los avances en tecnologíaimplicarán mayor paralelismo y no mayores velocidades dede los ciclos de reloj.
Paralelismo | 54
¿Qué Queremos?
Programación de Orden Superior
Expresiones Lambda & Closures
InmutabilidadEvaluación Tardía
Evaluación de Corto-CircuitoParalelismo
Gracias
https://github.com/edalorzo/jdk8-preview
http://blog.informatech.cr/author/edalorzo
http://www.slideshare.net/edalorzo
Grupo de Usuarios de Java Costa Rica
[email protected]://www.linkedin.com/in/edalorzo
Oracle Day 2013http://jdk8.java.net/lambda/