Slide 1

Slide 1 text

GENERADORES EN JAVASCRIPT Sergio Arbeo

Slide 2

Slide 2 text

AGENDA Conozcámonos Un poco de Nodejs Conceptos básicos Generadores Hasta luego, callback hell Presente y futuro.

Slide 3

Slide 3 text

CONOZCÁMONOS Sergio Arbeo Matemático, troll. Programador Ruby y CoffeeScript, entre otros. CodeCantor, ConectaLab Profesor de Rails avanzado en IronHack

Slide 4

Slide 4 text

¿Y VOSOTROS? Nivel JavaScript: Bajo Medio Alto

Slide 5

Slide 5 text

¿Y VOSOTROS? Nivel Node: ¿Mande? Lo uso como herramienta externa Hago mis pinitos Trabajo a diario Odio el callback hell

Slide 6

Slide 6 text

NODE.JS

Slide 7

Slide 7 text

NODE HISTORIA Creado por Ryan Dahl en 2009 Basado en y Primer drama hace unos meses Liderada actualmente por Timothy J. Fontaine Google v8 libuv

Slide 8

Slide 8 text

NODE: CARACTERÍSTICAS Asíncrono Un único hilo. Soporte para generadores de harmony en la versión inestable.

Slide 9

Slide 9 text

PRIMER EJERCICIO 1. Crea dos ficheros desde la terminal: a . t x t y b . t x t . 2. Crea un script en Node que lea los dos ficheros y los imprima en orden inverso al leído. 3. Os interesa el módulo f s y el método r e a d F i l e . 4. Cinco minutillos.

Slide 10

Slide 10 text

PRIMER EJERCICIO: SOLUCIÓN v a r f s = r e q u i r e ( ' f s ' ) ; f s . r e a d F i l e ( " a . t x t " , " u t f 8 " , f u n c t i o n ( e r r , d a t a ) { i f ( e r r ) t h r o w e r r ; v a r f i r s t F i l e = d a t a ; f s . r e a d F i l e ( " b . t x t " , " u t f 8 " , f u n c t i o n ( e r r , d a t a ) { i f ( e r r ) t h r o w e r r ; v a r s e c o n d F i l e = d a t a ; c o n s o l e . l o g ( s e c o n d F i l e ) ; c o n s o l e . l o g ( f i r s t F i l e ) ; } ) ; } ) ;

Slide 11

Slide 11 text

PRIMER EJERCICIO: COROLARIOS 1. Callbacks, el camino a la asincronicidad. 2. No es fácilmente extrapolable a N ficheros.

Slide 12

Slide 12 text

PRIMER EJERCICIO: GENERALIZADO Utiliza a s y n c para generalizar fácilmente el ejercicio anterior a tantos ficheros como haga falta. Recomendación del día: a s y n c . m a p .

Slide 13

Slide 13 text

PRIMER EJERCICIO: GENERALIZADO v a r f s = r e q u i r e ( ' f s ' ) ; v a r a s y n c = r e q u i r e ( ' a s y n c ' ) ; v a r r f = f u n c t i o n ( f i l e n a m e , c b ) { r e t u r n f s . r e a d F i l e ( f i l e n a m e , " u t f 8 " , c b ) ; } ; a s y n c . m a p ( [ " a . t x t " , " b . t x t " , " c . t x t " ] , r f , f u n c t i o n ( e r r , d a t a ) { i f ( e r r ) { t h r o w e r r ; } f o r ( v a r i = d a t a . l e n g t h - 1 ; i > = 0 ; i - - ) { c o n s o l e . l o g ( d a t a [ i ] ) ; } } ) ;

Slide 14

Slide 14 text

PRIMER EJERCICIO: CONCLUSIONES Node plano: difícil leer N ficheros. async: no eliminas completamente el callback hell.

Slide 15

Slide 15 text

META Poder escribir código, manteniendo la asincronicidad, lo más parecido a: v a r f s = r e q u i r e ( ' f s ' ) v a r a F i l e = f s . r e a d F i l e ( ' a . t x t ' , ' u t f 8 ' ) ; v a r b F i l e = f s . r e a d F i l e ( ' b . t x t ' , ' u t f 8 ' ) ; c o n s o l e . l o g ( b F i l e ) ; c o n s o l e . l o g ( a F i l e ) ;

Slide 16

Slide 16 text

GENERADORES

Slide 17

Slide 17 text

GENERADORES: DEFINICIÓN A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values. Generators, also known as semicoroutines, are a special case of (and weaker than) coroutines. Wikipedia

Slide 18

Slide 18 text

CORRUTINA: DEFINICIÓN Components that generalize subroutines to allow multiple entry points for suspending and resuming execution at certain locations. Wikipedia

Slide 19

Slide 19 text

GENERADOR: EJEMPLO v a r q u e e n = f u n c t i o n * ( ) { y i e l d " J o h n D e a c o n " ; y i e l d " F r e d d i e M e r c u r y " ; y i e l d " B r i a n M a y " ; y i e l d " R o g e r T a y l o r " ; } ; f o r ( v a r p o f q u e e n ( ) ) { c o n s o l e . l o g ( p ) ; } Usad n o d e - - h a r m o n y

Slide 20

Slide 20 text

GENERADOR: CARACTERÍSTICAS Funciones con estrella y i e l d keyword Usado como un iterador

Slide 21

Slide 21 text

ARGUMENTOS EN GENERADORES: EJERCICIO Escribid un generador que, dado otro generador y una función, devuelva un generador m a p . 1. Cread un generador que devuelva una lista de valores (ej. números del 1 al 5). El último elemento tiene que devolverse con return. 2. Usad n e x t ( ) para obtener el siguiente valor de un generador. 3. Cread un generador m a p . 4. Imprimid el resultado usándolo como iterador.

Slide 22

Slide 22 text

ARGUMENTOS EN GENERADORES: SOLUCIÓN v a r m a p G e n = f u n c t i o n * ( g e n , f n ) { i f ( i s G e n e r a t o r ( g e n ) ) { g e n = g e n ( ) ; } v a r c u r r e n t = g e n . n e x t ( ) ; w h i l e ( ! c u r r e n t . d o n e ) { y i e l d f n ( c u r r e n t . v a l u e ) ; c u r r e n t = g e n . n e x t ( ) ; } r e t u r n c u r r e n t . v a l u e ; } ; v a r i s G e n e r a t o r = f u n c t i o n ( o b j ) { r e t u r n o b j & & o b j . c o n s t r u c t o r & & ' G e n e r a t o r F u n c t i o n ' = = o b j . c o n s t r u c t o r . n a m e ; }

Slide 23

Slide 23 text

ARGUMENTOS EN GENERADORES: CONCLUSIONES n e x t devuelve un objeto con dos claves: v a l u e y d o n e y i e l d para la ejecución del generador, dejándola suspendida y i e l d hace que la respuesta de n e x t tenga d o n e : f a l s e r e t u r n hace que la respuesta de n e x t tenga d o n e : t r u e ¿Qué pasa con el último valor de un generador al usarlo como iterador?

Slide 24

Slide 24 text

YIELD ES UNA PALABRA CLAVE v a r a r r g e n = f u n c t i o n * ( a r r ) { a r r . f o r E a c h ( f u n c t i o n ( e l ) { y i e l d e l ; } ) ; } ; v a r s e q = a r r g e n ( [ 1 , 2 , 3 ] ) ; c o n s o l e . l o g ( s e q . n e x t ( ) ) ; c o n s o l e . l o g ( s e q . n e x t ( ) ) ; c o n s o l e . l o g ( s e q . n e x t ( ) ) ;

Slide 25

Slide 25 text

YIELD ES UNA PALABRA CLAVE g e n - t 3 c h f e s t / y i e l d _ e x a m p l e . j s : 3 y i e l d e l ; ^ ^ S y n t a x E r r o r : U n e x p e c t e d i d e n t i f i e r a t e x p o r t s . r u n I n T h i s C o n t e x t ( v m . j s : 6 9 : 1 6 ) a t M o d u l e . _ c o m p i l e ( m o d u l e . j s : 4 3 2 : 2 5 ) a t O b j e c t . M o d u l e . _ e x t e n s i o n s . . j s ( m o d u l e . j s : 4 6 7 : 1 0 ) a t M o d u l e . l o a d ( m o d u l e . j s : 3 4 9 : 3 2 ) a t F u n c t i o n . M o d u l e . _ l o a d ( m o d u l e . j s : 3 0 5 : 1 2 ) a t F u n c t i o n . M o d u l e . r u n M a i n ( m o d u l e . j s : 4 9 0 : 1 0 ) a t s t a r t u p ( n o d e . j s : 1 2 3 : 1 6 ) a t n o d e . j s : 1 1 2 8 : 3

Slide 26

Slide 26 text

YIELD ES UNA PALABRA CLAVE E n u m e r a t o r . n e w d o | y | [ 1 , 2 , 3 ] . e a c h d o | x | y < < x e n d e n d . l a z y

Slide 27

Slide 27 text

MÚLTIPLES PUNTOS DE ENTRADA 1. Cread una sucesión de Pell: 1. El primer elemento es 0. 2. El segundo elemento es 1. 3. El elemento n es 2 veces el (n-1)-ésimo más el (n-2)-ésimo. 4. El elemento inicial es 1. 2. ¿Qué ocurre si pasáis un parámetro a n e x t ? 3. Modificad el generador del primer punto para que se pueda resetear.

Slide 28

Slide 28 text

MÚLTIPLES PUNTOS DE ENTRADA v a r p e l l = f u n c t i o n * ( ) { v a r a = 0 , b = 1 , c = 0 ; w h i l e ( t r u e ) { y i e l d b ; c = a ; a = b ; b + = c + b ; } } ;

Slide 29

Slide 29 text

MÚLTIPLES PUNTOS DE ENTRADA SOLUCIÓN 3 v a r p e l l = f u n c t i o n * ( ) { v a r a = 0 , b = 1 , c = 0 ; w h i l e ( t r u e ) { v a r r e s u l t = y i e l d b ; i f ( r e s u l t ) { a = 0 ; b = 1 ; } e l s e { c = a ; a = b ; b + = c + b ; } } } ;

Slide 30

Slide 30 text

EJECUCIÓN DE PELL v a r p e l l = f u n c t i o n * ( ) { v a r a = 0 , b = 1 , c = 0 ; w h i l e ( t r u e ) { v a r r e s u l t = y i e l d b ; i f ( r e s u l t ) { a = 0 ; b = 1 ; } e l s e { c = a ; a = b ; b + = c + b ; } } } ; v a r s e q = p e l l ( ) ; c o n s o l e . l o g ( s e q . n e x t ( ) ) ; / / 1 c o n s o l e . l o g ( s e q . n e x t ( ) ) ; / / 2 c o n s o l e . l o g ( s e q . n e x t ( ) ) ; / / 5 c o n s o l e . l o g ( s e q . n e x t ( t r u e ) ) ; / / ?

Slide 31

Slide 31 text

ÚLTIMO EJERCICIO Crea una función e a c h C o n s 2 que, dado un generador, devuelva dos valores consecutivos. Por ejemplo: El generador original devuelve 1, 2, 3, 4, 5, 6... e a c h C o n s 2 devolverá [ 1 , 2 ] ,[ 2 , 3 ] ,[ 3 , 4 ] ,...

Slide 32

Slide 32 text

ÚLTIMO EJERCICIO v a r e a c h C o n s 2 = f u n c t i o n * ( g e n ) { i f ( i s G e n e r a t o r ( g e n ) ) { g e n = g e n ( ) ; } v a r a = g e n . n e x t ( ) , b = g e n . n e x t ( ) ; w h i l e ( ! b . d o n e ) { y i e l d [ a . v a l u e , b . v a l u e ] ; a = b ; b = g e n . n e x t ( ) ; } ; } ;

Slide 33

Slide 33 text

ÚLTIMO EJERCICIO v a r s q r t 2 = m a p G e n ( e a c h C o n s 2 ( p e l l ) , f u n c t i o n ( a r r ) { r e t u r n ( a r r [ 0 ] + a r r [ 1 ] ) / a r r [ 1 ] ; } ) ;

Slide 34

Slide 34 text

RESUMIENDO Son muy parecidos a corrutinas. Se pueden usar como un iterador. y i e l d es una keyword Son .

Slide 35

Slide 35 text

ELIMINANDO EL INFIERNO DE CALLBACKS

Slide 36

Slide 36 text

CONTINUACIÓN A continuation is a program frozen in action: a single functional object containing the state of a computation. When the object is evaluated, the stored computation is restarted where it left off. , Paul Graham On Lisp

Slide 37

Slide 37 text

IDEA La idea es utilizar un generador como una continuación. Para ello necesitaremos una función a la que llamaremos c u o r e que nos permitirá escribir código como el siguiente: c u o r e ( f u n c t i o n * ( ) { v a r f i r s t F i l e = y i e l d r e a d F i l e ( ' a . t x t ' ) ; v a r s e c o n d F i l e = y i e l d r e a d F i l e ( ' b . t x t ' ) ; c o n s o l e . l o g ( s e c o n d F i l e ) ; c o n s o l e . l o g ( f i r s t F i l e ) ; } ) ( ) ;

Slide 38

Slide 38 text

THUNKS Denominaremos thunk a una función que devuelve otra función cuyo único argumento es un callback. Escribid un thunk de f s . r e a d F i l e . Debe: 1. Admitir un único argumento, el nombre de archivo. 2. Devolver una función que admita como argumento un callback. 3. La función del retorno, al ser llamada con un callback, deberá llamar a f s . r e a d F i l e con el nombre de archivo pasado, ' u t f 8 ' y el callback.

Slide 39

Slide 39 text

THUNKS v a r f s = r e q u i r e ( ' f s ' ) ; v a r r e a d F i l e = f u n c t i o n ( f i l e n a m e ) { r e t u r n f u n c t i o n ( c b ) { f s . r e a d F i l e ( f i l e n a m e , ' u t f 8 ' , c b ) ; } ; } ;

Slide 40

Slide 40 text

CUORE SEMPLICE Implementad una función c u o r e : 1. Debe manejar dos thunks. 2. No debe manejar los errores.

Slide 41

Slide 41 text

CUORE SEMPLICE v a r c u o r e = f u n c t i o n ( g e n ) { r e t u r n f u n c t i o n ( ) { g e n = g e n ( ) ; g e n . n e x t ( ) . v a l u e ( f u n c t i o n ( e r r , d a t a ) { g e n . n e x t ( d a t a ) . v a l u e ( f u n c t i o n ( e r r , d a t a ) { g e n . n e x t ( d a t a ) ; } ) ; } ) ; } ; } ;

Slide 42

Slide 42 text

CUORE SEMPLICE v a r r f = r e a d F i l e ; c u o r e ( f u n c t i o n * ( ) { v a r f i r s t F i l e = y i e l d r f ( ' a . t x t ' ) ; v a r s e c o n d F i l e = y i e l d r f ( ' b . t x t ' ) ; c o n s o l e . l o g ( s e c o n d F i l e ) ; c o n s o l e . l o g ( f i r s t F i l e ) ; } ) ( ) ;

Slide 43

Slide 43 text

MUNDO REAL

Slide 44

Slide 44 text

CO Escrito por TJ Holowaychuk Acepta más tipos desde el yield: 1. Promesas 2. Array 3. Objetos 4. Generadores 5. Funciones generadoras Existen wrappers para ciertos módulos para que funcionen con c o Para todo lo demás, thunkify.

Slide 45

Slide 45 text

CO: EJEMPLO v a r f s = r e q u i r e ( ' c o - f s ' ) ; v a r c o = r e q u i r e ( ' c o ' ) ; c o ( f u n c t i o n * ( ) { v a r f i r s t F i l e = y i e l d f s . r e a d F i l e ( ' a . t x t ' , ' u t f 8 ' ) ; v a r s e c o n d F i l e = y i e l d f s . r e a d F i l e ( ' b . t x t ' , ' u t f 8 ' ) ; c o n s o l e . l o g ( s e c o n d F i l e ) ; c o n s o l e . l o g ( f i r s t F i l e ) ; } ) ( ) ;

Slide 46

Slide 46 text

PRESENTE Y FUTURO

Slide 47

Slide 47 text

NODE Disponible en la versión inestable usando - - h a r m o n y .

Slide 48

Slide 48 text

NODE There are interesting language features that we can use to extend Node APIs . , Timothy J Fontaine Node.js and the Road Ahead

Slide 49

Slide 49 text

CHROME Para poder usar generators (probado en Canary): 1. Ir a 2. Activar el apartado chrome://flags

Slide 50

Slide 50 text

FIREFOX En Firefox 27 no hace falta hacer nada.

Slide 51

Slide 51 text

FACEBOOK REGENERATOR es un compilador de ES6 con generadores a ES5 (kinda cool). Facebook Regenerator

Slide 52

Slide 52 text

BONUS ROUND¿?

Slide 53

Slide 53 text

KOA: UN EJEMPLO v a r k o a = r e q u i r e ( ' k o a ' ) ; v a r a p p = k o a ( ) ; a p p . u s e ( f u n c t i o n * ( n e x t ) { c o n s o l e . l o g ( ' A n t e s ' ) ; y i e l d n e x t ; c o n s o l e . l o g ( ' D e s p u é s ' ) ; } ) ; a p p . u s e ( f u n c t i o n * ( ) { t h i s . b o d y = " M i m a m á m e m i m a " ; } ) ; a p p . l i s t e n ( 4 2 4 2 ) ;

Slide 54

Slide 54 text

KOA EJERCICIO Utiliza t h i s . c o o k i e s . g e t ( n a m e ) y t h i s . c o o k i e s . s e t ( n a m e , v a l u e ) para añadir un texto a la respuesta.

Slide 55

Slide 55 text

KOA EJERCICIO SOLUCIÓN a p p . u s e ( f u n c t i o n * ( n e x t ) { y i e l d n e x t ; v a r b a c k = t h i s . c o o k i e s . g e t ( ' m a j o ' ) ; i f ( b a c k ) { t h i s . b o d y + = " \ n G r a c i a s p o r v o l v e r . " } t h i s . c o o k i e s . s e t ( ' m a j o ' , t r u e ) } ) ;

Slide 56

Slide 56 text

¿PREGUNTAS?

Slide 57

Slide 57 text

GRACIAS, MAJOS @Serabe