This graph shows how many times the word ______ has been mentioned throughout the history of the program.
En una prueba técnica me dijeron que implementara un yield.
¡Ostras!
¡Ostras!
¡Qué grande eso!
¿Sabéis lo que es un yield?
¿Sabéis lo que es una función generadora?
Esa está muy, muy, muy interesante.
Podríamos empezar con esta.
Podríamos empezar con esta.
A ver si...
Yo hace mucho tiempo que, por ejemplo, no hago un yield.
Lo puedo probar.
¿Lo queréis y lo practicamos un poco?
Mira, yo tengo aquí run.js.
¿Vale?
Aquí normalmente aparece la consola.
Vamos a poner la consola.
Aquí, show todo el output.
¿Sabéis lo que es una función generadora y todo esto?
¿Lo domináis?
¿No sabéis de qué estoy hablando?
A ver, comentadme si sabéis lo que es.
Si os pilla un poco de nuevas.
Intentar hacer un yield que genere la sucesión de Fibonacci.
¡Hostia!
A ver.
La verdad es que primero debería hacer un yield porque realmente no sabría hacer.
No se me ocurre ahora cómo lo podré hacer el Fibonacci con una generadora.
Pero lo podemos mirar.
Vamos a hacer primero, si os parece, una función generadora.
Y luego hacemos lo de que haga la de Fibonacci, si queréis.
Y así veis lo que es una generadora.
Yo, sinceramente, no preguntaría esto en una entrevista técnica.
Una función generadora, para crearla, hay que primero utilizar el asterisco.
Y luego aquí pongamos que le vamos a llamar contar cosas.
Vamos a llamarle contar cosas.
Esto hace que sea una función generadora.
¿Qué es lo interesante de una función generadora?
Esto es bastante interesante.
Las funciones generadoras, lo que puedes hacer es que cada vez que tú la ejecutes, te devuelva una cosa diferente.
De forma que yo, cuando llame a esta función aquí, lo que me devuelvo aquí sea una cosa, lo que me devuelvo aquí sea otra cosa.
Es bastante interesante.
Ahora, no se puede ejecutar y esto devolverte ya directamente el valor, sino lo que tienes que hacer aquí es utilizar el NEC.
O sea, decirle que quieres ir a la siguiente.
Cuando es generadora es porque tú cada vez que la llamas, como ejecuta una cosa diferente, lo que puedes hacer es ir a la siguiente ejecución que te va a hacer.
Justamente, las funciones generadoras se utilizan para la SinkAwait.
Mucha gente cree que en realidad utiliza las promesas, pero no es así.
Al final, lo que utiliza por detrás son funciones generadoras.
Por ejemplo, vamos a hacer aquí una constante que sea, yo qué sé, emojis.
Le vamos a poner un array.
Este es el típico ejemplo.
Vamos a ver si me sale.
Yo, claro, ¿por qué creo que no está muy bien preguntar sobre funciones generadoras en JavaScript?
Porque en tu día a día, a no ser que utilices Reduxagas, que no creo que sea vuestro caso, o bueno, sí que puede ser vuestro caso,
pero tampoco es que sea muy típico.
Pero bueno, en Reduxagas es verdad que se utiliza.
Pero más allá de eso, no suele tener un gran, digamos, no suele tener un buen caso de uso.
Estoy intentando pensar, pero es que incluso en lo de Fibonacci, ¿no?
Lo de Fibonacci al final lo puedes hacer de otras formas.
Así que no sé hasta qué punto tiene sentido.
¿Qué se puede hacer aquí?
Podríamos, por ejemplo, aquí, podríamos hacer un loop.
El loop este de for, si tienes let i que sea cero, este sea el loop más normal.
Luego vamos probando qué cosas puede tener, ¿vale?
Pero aquí creo que uno puede ver lo que tiene de interesante la función de generadoras.
Aquí vamos a decir i más más.
Y aquí lo que vamos a decirle es yield.
Y vamos a devolver el emoji que está en la posición i.
Como veis, estoy haciendo un yield.
El yield lo que quiere decir no es un return de toda la vida, ¿no?
Sino que lo que dice aquí es, vale, detén la ejecución de esta función.
La detiene.
Esto lo que hace es detener la ejecución de la función.
Y lo que hace es que el valor este que le estás poniendo aquí es lo que devuelve al llamar este generador.
Pero está deteniendo la ejecución.
Esto es súper interesante porque al detener aquí la ejecución, este for que estás viendo aquí no sigue haciéndolo, no sigue ejecutando.
Está detenida la ejecución de la función, pero ha devuelto ya este valor.
¿Cómo lo podemos ver aquí?
Pues este en el count things, este que hemos hecho aquí.
Pues si yo ahora aquí, podríamos poner aquí it, de iterator, ¿no?
Count things.
Y ahora hago punto next.
Esto debería, ¿veis?
Nos devuelve el valor y nos dice si ha terminado ya la función de ejecutarse.
En este caso nos está diciendo, nos devuelve el valor, que si os fijáis es el primero.
Y luego me dice, ¿esto ha terminado?
No, no ha terminado.
A partir de aquí lo que puedes hacer es volver a llamar.
Aquí tenéis it, que bueno, ¿le puedo llamar it o cómo le podríamos llamar a esto?
Que sería un poquito más claro.
Seguramente, a ver, esto sería más que it, de iterator, sería un generator, ¿no?
O generator, o sea, es un generador ya.
Entonces, llamamos a este generador, le decimos next y ya te da la siguiente.
Podríamos volver a llamarlo, le decimos next y ya la siguiente.
¿Veis que ha cambiado el valor?
Esto es porque cuando vuelves a llamarlo esto, lo que te está haciendo es la siguiente ejecución.
Entonces, vuelve a ejecutarse, vuelve a recuperar el control de la función y la vuelve a ejecutar.
Es bastante interesante, ¿no?
Y ahora aquí igual, next, pam, otra vez.
¿Y ahora qué pasa si le doy al next?
Vale, pues aquí ya me dice que el valor es undefined y que ya ha terminado de ejecutar la función.
A partir de aquí, claro, aquí se pueden hacer verdaderas virguerías.
Se pueden hacer cosas bastante potentes.
De hecho, esto de que sea en un loop, esto ni siquiera realmente es necesario.
Porque una vez que tú sabes esto, lo que podríamos hacer, por ejemplo, esto sería más manual,
pero puedes hacer yield emojis primero del 0, emojis del 1, yield emojis del 2.
Por ejemplo, esto lo podríamos hacer así.
De forma que cada vez que se ejecute, ¿veis? Vamos devolviendo cada una de las cosas y tal.
O sea, que en realidad lo que estamos haciendo es detener la ejecución y hasta que no llamas no te devuelve la siguiente.
Esto es lo que sería una función generadora.
Y a ver, es lo que os digo es que es difícil muchas veces detener el modelo mental,
de encontrarle una funcionalidad en concreto.
Porque, claro, cuando realmente lo vas a utilizar, siempre puedes ver otro tipo de funcionalidad.
Lo que sí que puede ser interesante es si tienes aquí diferentes pasos.
Que digas, por ejemplo, primero voy a hacer una cosa, que sea enseñar en la consola una cosa.
Y cuando haces el yield, como lo que hace es parar la ejecución de esto,
pues en realidad puedes tomar el resultado, por ejemplo, llamar a una API.
Podrías llamar a una API, hacer un yield del resultado de la API y con ese resultado podrías hacer una cosa
y luego hasta que no estuvieses preparado no hacer el next para ver cómo sigue esta función.
Esto a veces puede ser interesante para hacer validaciones.
Primero haces una llamada a la API, validas que está correctamente.
Si correctamente ha funcionado, pues podrías llamar al next.
Y si no, lo que puedes hacer es obviar eso y hacer una cosa totalmente diferente
para evitar que se haga la siguiente llamada.
Esto está bastante bien y te puede ayudar en el tema este de controlar mejor el flujo de ejecución de tu función.
Pero ya os digo, en el día a día yo no creo que esto se vea muchísimo, ¿vale?
El hacer una función generadora.
De hecho, por ejemplo, ahora me habéis dicho esto del Fibonacci.
Y lo del Fibonacci, a ver, lo puedo pensar, no se me ocurre muy bien,
pero entiendo que el Fibonacci, por ejemplo, depende cómo lo queráis hacer,
pero entiendo que el Fibonacci, esto puede ser una prueba técnica,
pero ya os diría que sería de un nivel bastante alto, ¿vale?
De una persona que tenga un nivel bastante alto.
Yo, por ejemplo, nunca jamás he hecho un Fibonacci con función generadoras
y vais a ver que me va a costar porque el modelo mental es un poco complejo, ¿no?
Pero entiendo que lo que se quiere hacer, esto que lo he guardado en una constante,
en realidad esto podríais hacerlo también llamando a la misma función, ¿eh?
Esto, por ejemplo, si vais haciendo aquí en lugar de Generator,
lo hacemos aquí directamente y llamamos al Fibonacci y con la función,
esto debería funcionar bien.
A ver, la función, para el que no sepa qué es Fibonacci,
¿quién no sabe qué es Fibonacci? Que levante la mano.
Vamos a repasarlo para que lo tengamos por aquí.
Fibonacci. Este es un típico problema que se suele utilizar un montón.
A ver, voy a leeros a ver qué me estáis comentando.
¿Tiene algún método hasnext? Buena pregunta.
Vamos a ver. Vamos a ver si tiene el método hasnext.
Al final se lo puedes, se lo podrías hacer tú.
A ver, Generator JavaScript.
Pero lo que puedes mirar realmente es si el don está en false,
porque si está en false deberías tener un siguiente directamente.
A ver, porque al final lo que podrías hacer, a ver, hasnext, hasnext, next.
Vale, sí, tienes next, te ves, tienes el value, el don.
Esto, mira, esto también está muy interesante.
Es que al final tú cuando devuelves esto, ves que al crear este iterador,
bueno, esto es para crear un iterador a mano.
Esto sería crear un iterador a mano.
El generador al final, que además son iteradores,
es que esto es muy interesante, ¿vale?
El generador te crea una función que es iterable.
Esto es JavaScript un poco avanzado, pero esto realmente está muy bien que lo sepáis.
Porque al final iterables tenéis un montón, ¿no?
Por ejemplo, un array es algo iterable, un set, un map, son tipos que son iterables.
Con una función generadora podéis hacer que también sea iterable.
Y eso está genial.
Ahora lo podríamos intentar con el Fibonacci cuando lo terminemos.
¿Ves? Es un objeto, es iterable, se define cómo se itera.
Y las generadoras se define cómo se itera, porque como tiene un punto next,
pues puedes iterarlo y vas a poder decir siempre internamente JavaScript
va a poder ejecutar este método next para saber qué es lo siguiente que viene, ¿vale?
Esto es muy, muy, muy interesante, ¿eh?
Porque pensad que podéis hacer vosotros mismos objetos iterables.
Esto también puede ser una prueba.
Aquí se hace un iterador.
Esto está muy, muy interesante.
Crear un iterador.
Imaginad que os dicen, tienes que crear una estructura de datos que sea iterable,
pero no puedes utilizar arrays, ni maps, ni objects, o sea, tienes que crearlo tú.
Pues tendrías que crear esta función de aquí, crear un iterador.
Aquí, claro, le tendrías que pasar el arreglo o no, no tiene por qué.
Al final puedes hacer un iterador, pasarle un número y que sea tantas veces iterables
como las veces que tú le has dicho.
¿Veis?
Y aquí, en lugar de arreglo.length, le decís las veces que se tiene que iterar
y le tenéis que devolver el value y si es done, y ya tendrías el iterable.
Y esto le podéis hacer un for que funciona.
Bueno, no solo un for por el índice, sino, por ejemplo, un for of.
Ahora lo haremos, ¿vale?
Para que lo veáis más claro.
Pero, bueno, que eso lo hace muy interesante.
Porque las funciones generadoras son iterables.
Y eso lo hace, mira, aquí, por ejemplo, ves un for of del valor y su iterable.
Y el iterable este lo puede hacer justamente de la función generadora.
Así que, bueno, ves los integrados.
El string es iterable, el array, los objetos, el map y el set.
Perfecto.
Sintasi espera los objetos iterables.
Claro, lo que esperan es que puedas hacer un punto next y ya está.
¡Wow!
Esto, mira, esto no lo he usado yo en mi vida.
En mi vida.
Pero esto lo que hace justamente es como automáticamente
que cada vez que devuelva, ejecutes este generador,
te devuelva primero la A, luego la B, luego la C.
Pero esto no lo he usado en mi vida.
Ya veis, generadores avanzados.
Hemos empezado por todo lo alto.
O sea, hemos empezado por todo lo alto.
No sé hasta qué punto esto os lo podéis encontrar en una...
Ah, mira, aquí está el Fibonacci.
Aquí está el Fibonacci.
Pues mira, yo no hubiera empezado así.
Yo lo que hubiera empezado, entiendo, ¿eh?
No sé cómo...
F1, 1, 2...
Primero os explico qué es Fibonacci porque esto es una prueba
que suelen hacer mucho en las entrevistas técnicas.
Esta sí que os pueden decir de
Crea un Fibonacci con JavaScript, ¿vale?
Esto sí que os lo pueden decir.
Y es súper típico.
Es un problema muy, muy, muy recurrente.
Sobre todo por tema de algoritmia, ¿no?
Y cómo funciona el Fibonacci.
Fibonacci al final es una sucesión, ¿no?
En la que primero empiezas por 0 y luego tienes el 1.
Y luego lo que hace es sumar el primer elemento y el anterior.
O sea, empiezas por 0, 1, y luego sería 1 más 0, 1.
Luego 1 más 1, 2.
2 más 1, 3.
3 más 2, 5.
Y así iría, ¿vale?
Esto se suele solucionar bastante bien con un tema de recursividad, ¿vale?
Haciendo recursividad, que si queréis lo podemos intentar también,
aunque a ver cómo la lío aquí con el tema del Fibonacci también,
con la recursividad.
Con un tema de recursividad.
Vamos a probarlo.
Esto no lo hago yo desde la universidad, ¿eh?
No lo hago desde la universidad.
Pero, bueno, puede ser que os la pidan y vamos a ver.
Fibonacci.
Lo vamos a hacer primero con recursividad,
porque también os lo pueden pedir en una entrevista.
Y a partir de ahí ya vamos viendo cómo lo hacemos.
Lo más importante de una función recursiva es tener una cláusula de escape
para evitar justamente que os puedan, bueno, claro,
que os haga un bucle infinito.
Así que lo más importante siempre sería decir tener una cláusula de escape.
Entonces, en Fibonacci aquí lo que le vamos a poner es pasarle un número.
La n lo que va a indicar es cuántos números vamos a tener que sumar.
O sea, tenemos el 0, 1, 2, 3, 4, 5.
Imagínate 5, ¿no?
Pues me debería devolver justamente el 5.
Si le digo que quiero la sucesión hasta el 5, pues tendría que tener el 5.
Así que la n, en este caso, sería cuántas veces tiene que hacer esta sucesión.
Vamos a poner por ahora n y luego lo llamaremos así.
Fibonacci y Fibonacci, lo he puesto bien.
Y aquí le vamos a poner 5.
Esto debería devolver, si no me equivoco, 0, 1, 2, 3, 4, 5.
Vale.
Entonces, lo primero que tenemos que hacer es la cláusula de escape.
Hay un montón de formas de hacerlo, ¿eh?
Tampoco quiero ser aquí el...
Porque la puedo liar muy parda.
Pero yo lo que diría, para asegurarte, es que si n es igual a 0, o sea, si...
O a 1.
¿Cuál sería la sucesión?
Si es menor que 1, bueno, si es...
Vamos a poner 0, que es menor que 1.
Si m, n es igual a 0, entonces deberíamos devolver 0.
¿Vale?
Esto sería ya la cláusula de escape.
De forma que, aunque recursivamente vayamos preguntando hacia atrás,
lo que vamos a decirle...
Bueno, voy a ponerle menor a 0 para asegurarme.
No debería haber ningún problema, pero lo voy a poner así.
Si n es menor que 1, que sería 0, menos 1 y tal, aunque no debería llegar,
entonces devolvemos 0.
Como veis, esta es nuestra cláusula de escape.
Cualquier función recursiva que queráis hacer, tiene que tener una cláusula de escape.
Podríais tener...
Hay veces que puedes tener incluso más, ¿vale?
Que puedes decir, si n es menor o igual a 2, por ejemplo.
Esto me lo estoy inventando.
Puedes hacer un return 1.
Esa es una forma muy interesante de enfrentaros muchas veces a algoritmos.
Por ejemplo, yo lo que estoy haciendo.
Luego lo podéis refactorizar.
Pero cuando os piden un algoritmo, y esto es súper típico,
que os piden un algoritmo y no domináis, ¿vale?
Imaginad que os dicen Fibonacci, ¿vale?
Y no lo domináis.
Esto a mí me ha pasado 10.000 millones de veces.
Os dicen el enunciado.
Dice, bueno, tenéis una sucesión de números de tal que así.
¿Vale?
Tal que así.
8, 13, 21.
Tenéis una sucesión de números tal que así.
Y esto se le llama sucesión de Fibonacci.
Crea un algoritmo que puedas hacer no sé qué, no sé cuánto.
Una forma para empezar a justamente dominar más o menos un algoritmo
es empezar con los casos más sencillos.
Por ejemplo, aquí, ¿no?
Este que decimos, vale, pues la sucesión.
Si esta es una, pues debería ser cero.
A ver, lo podemos cambiar para que, claro, ¿no?
Pues esto debería devolver cero.
Esto debería devolver, si esto es dos, debería devolver uno.
Por ejemplo, ¿vale?
Si esto es tres.
Y entonces, aunque parece esto una tontería,
aquí ya podríais empezar a ver cuál es el truquillo que tiene el algoritmo.
Aunque tengáis esto, esto en realidad ya pasaría a algunos test.
Parece una tontería, ¿vale?
Pero si normalmente las pruebas técnicas os dan una batería de test
que tienen que pasar.
Si vosotros empezáis por aquí, ya es una buena práctica.
Es mejor ir entregando valor en la prueba,
en el hecho de que tú empieces ya con algo verde, ¿sabes?
Ya escribir una línea, esta, y que ya tenga verde,
ya es una buena señal.
Porque estás haciendo de una forma iterativa.
Aunque esto pueda parecer que dice,
ostras, pero es que lo que estás haciendo aquí no está bien,
entre comillas, porque lo estás haciendo a mano.
¿Vale? Es verdad.
Pero al menos ya te estás dando cuenta que el n igual a 2 devuelve 1
y el 3 también devuelve 1, lo cual es un poco raro.
Pero esto ya te asegura que tienes unos cuantos verdes en los test
y ya te está empezando a levantar un poquito el ánimo y el ver el patrón.
Ya estás escribiendo, vas teniendo verde, vas viendo el patrón.
Y ahora, ¿qué es lo que deberíamos ver?
A ver, ya os digo que el Fibonacci se puede hacer de un montón de formas.
Pero la gracia del Fibonacci, por ejemplo, si nos dicen que el 5,
lo que debería hacer es el que nos diga más, o sea, hay que sumar el elemento actual más el anterior.
Pues así, ¿no?
¿Qué pasa?
Que cuando te dicen 0, 1, 2, 3, 4 y 5, cuando tienes este, tienes que saber cuánto es el anterior.
Pero para saber cuánto es el anterior, tienes que saber también cuánto es el anterior.
Y para saber cuánto es el anterior, tienes que saber cuánto es el anterior.
Entonces, ya que esto nos serviría como cláusula de escapes, de forma que cuando llega a este,
ya no tiene que saber el anterior, sino que tú ya sabes que es 0.
Ya sabes que en este punto es 0 el valor.
Cuando n es 1, es 0.
O sea, que cuando pongamos, por ejemplo, esto, ya sabemos que debería ser 0.
Y si le ponemos aquí el 2, debería ser 1.
Vale, hasta aquí, perfecto.
Este, el 3, este como tal, no hace falta porque lo podemos calcular.
Lo que podemos hacer aquí, justamente, es ahora utilizar la recursividad.
Porque como hemos visto, necesitamos ir hacia atrás para saber realmente cuál es el valor.
Entonces, lo que tenemos que hacer es llamar otra vez a Fibonacci, pero vamos a ejecutar menos 1, ¿no?
Porque si lo que tenemos que hacer es ir hacia atrás, tenemos que ir contando hacia atrás y ver cuál era el valor que teníamos.
Entonces, tenemos que ver el anterior menos el anterior anterior.
Y con esto, ya tendríamos justamente la regla de Fibonacci, si todo ha ido bien.
Podemos hacer una prueba, si queréis, de que vayamos paso a paso a ejecutarlo.
Pero el caso es que si yo aquí pongo un 3 ahora, ¿veis?
Me da 1, sin haberle puesto aquí el if del 1.
Si pongo aquí 4, que es la sucesión, deberíamos ver el 2, que es este.
Si pongo la del 5, deberíamos ver el 3, ¿vale?
Y lo importante, importantísimo, y es que esto es una cosa que la gente cuando hace recursividad falla.
Lo primero que hay que escribir en una función recursiva es la cláusula de escape.
Lo primero, lo primero, ¿vale?
No empecéis, aunque sepáis que es recursiva, no empecéis haciendo recursividad a saco.
Primero, estas cláusulas de escape.
Ya veis que en este caso he puesto 2.
¿Por qué?
Porque estas no se pueden calcular.
Estas dos primeras no se pueden calcular directamente, sino que directamente lo mejor sería hacerlo así.
Como os digo, hay diferentes formas y de hecho pueden ser bastante interesantes.
Podéis tener una constante que sean initial, Fibonacci, y entonces tener aquí justamente que si es 1, entonces es el 2.
Por ejemplo, en la 1 podéis poner un objeto mejor.
Un objeto que tenga, dice, vale, cuando n es 1, entonces 0.
Cuando es 2, entonces 1.
Y entonces en lugar de hacer un if, esto ya lo que queráis de llevaros, de ir a otro nivel, ¿no?
Hacéis un return y podéis decirle, vale, pues inicia, initial Fibonacci.
Y aquí le podéis pasar la n, y si lo detecta es eso, y si no, pues es nuestro cálculo.
Esto ya, ya es como palamerlo, ¿vale?
Esto es de que os estáis sacando un poco, estáis yendo un poco sobraos, ¿vale?
No sé qué he petado, pero bueno, puede ir un poco por aquí.
Vale, porque, ah, claro, porque justamente me estoy cargando la cláusula de escape.
Bueno, podríais buscar, si existe este, está aquí, y entonces lo devolvéis,
en lugar de llamar otra vez al Fibonacci y todo esto, ¿vale?
Encontráis, aquí tenéis el resultado, y si tenéis el resultado lo devolvéis.
Y entonces le podéis decir al entrevistador, bueno, esto es por si el día de mañana, pues quieres hacer un Fibonacci
que empiece a partir de, en lugar del cero, pues que empiece de otro sitio, no sé qué.
Esto sería un poco la cosa, ¿no?
Esto sería 6, sería el 5 que hemos visto aquí, luego debería ser el 8, y esto sería un poco...
Uy, me salté el 8.
Esto sería Fibonacci.
Con recursividad.
Bueno, hemos visto recursividad, ¿eh?
En un momento, esto es un ejemplo súper típico, ¿eh?
Esto, yo os recomiendo el Fibonacci a que saber hacerlo en JavaScript.
A mí, bueno, no me ha costado, aunque ya veis que he tenido que pensarlo.
Pero es mejor el hecho que lo tengáis que pensar.
Pero aunque lo penséis, una vez que tenéis estos pasos claros,
de no ponerse nervioso con un algoritmo, entenderlo, y luego cláusula de escape.
Eso, a fuego, cláusula de escape, y luego pam, pam, pam,
ya, genial.
Haremos directos, ¿vale?
Haciendo catas y cosas así, que hoy lo estaba comentando.
Pero lo interesante, siempre que se hacen catas, algoritmos y tal, es esto, ¿vale?
Dominar los casos básicos.
Por eso os lo explican, ¿vale?
Los casos básicos, porque justamente son los que os van a dar un poquito las más temas.
Ahora, sí, aquí os pueden decir, es que peta con...
Mira, alguien me pone en chat.
Peta con números negativos.
A ver, no creo que se pongan tan exquisitos,
pero bueno, lo que podéis hacer es lo que he hecho antes, ¿vale?
Si n es menor que 1, pues ya devuelve 0 y ya está.
O sea, que ya no tendría los casos negativos y ya está.
También es verdad que ahí depende un poco de realmente cuál es el contrato que tiene esta función.
Y de hecho, lo podríais discutir.
Porque esto de decir, es que peta con números negativos, lo que se puede decir es que igual tiene sentido que pete porque una sucesión de Fibonacci no acepta números negativos.
O le puedes decir, bueno, puede ser un caso de uso, que quieras utilizar números negativos, entonces darle la vuelta y hacerlo y tal.
Pero no me lo habías especificado, me habías dicho una serie de Fibonacci.
Eso sería un poco el tema, ¿vale?
A ver, que os leo un momentito y seguimos.
Se puede poner un yield en una función flecha.
No se puede poner un yield.
Tiene que ser una función generadora.
No puedes ponerlo y ya está.
¿Qué es lo que hace yield?
Un break.
Bueno, eso lo he ido explicando un poco.
¿Por qué tiene asterisco la función?
Y ahora porque era una función generadora.
No bloquea el hilo de JavaScript, ¿vale?
Esta función, de hecho, se nos ha quedado pendiente el tema de hacer el Fibonacci, ¿no?
Con esto.
A ver, voy a intentar hacer el Fibonacci con la función generadora.
Esto sería el Fibonacci con la recursividad.
De nuevo, súper importante.
Lo tenéis que dominar o tener muy claro cómo debería hacerse, ¿vale?
Entonces, lo vamos a quitar por aquí.
Bueno, voy a dejarme esto porque esto lo voy a comentar.
Porque igual me ayuda un poco para el tema de la generadora.
Las funciones generadoras son estas.
El asterisco justamente lo que le indica es que es una función generadora.
No sé muy bien.
Entiendo que esta función generadora lo que se quiere conseguir es que cada vez que se llame a esta función
te devuelva la siguiente sucesión de Fibonacci, ¿vale?
O sea, que cuando llamemos a Fibonacci.next, esto lo que tiene que devolvernos es justamente la primera vez.
Debería ser 0, la próxima vez que le llamemos sea 1, ¿no?
Y esto es lo que tendría que hacer.
Yo creo que la primera vez debería ser yield 0, luego yield 1.
Y ahora, claro, lo que podemos hacer esto...
No sé cómo hacer esto.
No sé cómo pensar cómo lo podemos hacer.
O sea, podríamos, por ejemplo, guardar una constante.
Podríamos poner esto a 0.
Y luego, claro, lo que necesitamos...
Esto funcionaría para las dos primeras, por ejemplo.
Fibonacci...
A ver, esto lo he liado.
Esta funcionaría para las dos primeras.
Y el 0...
Ah, bueno, claro.
Es que si empiezo a llamar así, vais a ver que siempre me devuelve 0, claro.
Hay que guardar la generación.
Lo que quería enseñaros antes es que se podía llamar una vez.
Se podía llamar tantas veces como queráis y se queda ahí.
Y no bloquea el hilo.
Cuando está justamente...
Vamos a poner esto aquí.
Generator next, generator next.
¿Vale?
Aquí lo tendríamos.
Claro, el tema aquí es que las dos primeras funcionan bien.
Ahora, si lo vuelvo a ejecutar, pues ya me va a decir que esto es undefined y que don't true.
Que ya ha terminado.
Claro, para hacer esto, lo que tendríamos que ir guardando serían como las más recientes.
O sea, las dos más recientes, los dos valores que hemos tenido.
O sea, a ver, ¿cómo lo podemos hacer esto?
Tendríamos que guardar...
He pensado que con el i0 podríamos tener, o los dos valores que hemos guardado, los dos más recientes,
podríamos tener el recent y el most first recent, second recent.
¿Vale?
Como los dos más recientes.
Esto podría ser.
Y luego aquí ya tendría que ser...
Claro, podríamos hacer un while y podría ser infinito.
O sea, tendríamos que hacer un while, while true,
y aquí hacer un yield justamente de la suma de estos dos números.
Por ahora, a ver, una vez que tenemos esto, el primero más reciente, el siguiente,
esto debería ser...
Esto lo podríamos poner en realidad aquí.
Que los más recientes serían cero y uno, ¿no?
Estos serían los más recientes.
O el prim...
Bueno, no sé cómo llamarles.
Pero podemos hacer así.
Y esto ya tendría que hacer un yield de first recent más second recent.
Por aquí pueden ir los tiros.
No sé si le va a gustar esto.
Bueno, es que este while true no sé si le va a gustar mucho, ¿eh?
Que lo hagamos así.
Pero...
De hecho se ha quedado así como picueto.
Vamos a quitar un momento esto.
A ver si es que...
A ver, vamos a volver a hacerlo.
Pero el yield en principio debería parar la ejecución.
O sea, ya sea que tiene...
Que está haciendo lo que sea.
A ver.
Vamos a probar ahora.
Ahora parece que sí.
Vale.
Este ahora ya sí que funciona.
Este ya sí que funciona.
Si le doy otra vez a next, me va a volver a devolver un 1.
Madre mía, esto se ha convertido un momento en funciones generadoras.
Pero, bueno, me parece súper bien, ¿eh?
Porque esto realmente...
Si vosotros decís que sabéis JavaScript avanzado
o que sabéis bastante JavaScript,
igual esto es una cosa que os pueden preguntar, ¿eh?
Y ya os digo que esto no bloquea el hilo.
Bueno, vamos a ver.
Ahora que tenemos esto, ¿qué es lo que debería devolver?
0, 1, 1 y este debería ser el 2.
Claro, para hacer eso, lo que tenemos que hacer es como actualizar...
Antes de devolver en este while, deberíamos actualizar los valores, ¿no?
Vamos a ver.
¿Cómo devolvemos...
¿Cómo hacemos esto de los valores?
Esto debería ser...
Después de devolverlo, deberíamos ser capaces de...
Primero, calcularlo, ¿no?
Deberíamos a poner...
Yo qué sé cómo lo llamo.
New value.
O sea, value.
Vamos a ponerle value, ¿no?
First recent más second recent.
Esto es lo que vamos a devolver el value.
Ahora, este valor, el último que hemos calculado,
debería ser el second recent.
Este sería el value.
Y el first recent debería devolver...
Sería el second recent.
Entonces, ¿veis?
Ahora sí que es un 2.
Y ahora esto debería ser un...
Bah, fatal.
No es un 4.
Debería ser un 3.
¿Por qué?
Porque la hemos liado aquí.
A ver.
Vamos a ver.
Aquí me habéis puesto totalmente en un aprieto.
O sea, habéis dicho...
Vamos a liarla y tal.
Vale.
Tiene el value y el second recent.
O sea que aquí sí que lo está calculando bien.
Tienes el value y el value es el first recent.
A ver, que igual lo he liado aquí, ¿no?
El value first recent.
Vamos a ver en la consola.
Ta, ta, ta.
Sí, igual los debería leer en los comentarios
que seguro que me decís dónde está el problema, ¿eh?
O lo podemos dejar así.
Yo os lo dejo como ejercicio.
Ya está.
A ver.
Este es el value 2, first recent 1, second recent.
¿Vale?
Second recent.
Guardamos el value, que es el 2.
El value, que es el 2.
Y el first recent, ahí.
Porque esto lo he puesto al revés, ¿vale?
Lo he puesto mal.
Cuando lo estaba pensando, lo he puesto al revés.
Ahora sí, ¿vale?
Ahora sí.
Bueno, pero no pasa nada.
O sea que tiene boca, se equivoca.
Ahora sí.
Ya tenemos nuestro Fibonacci con funciones generadoras.
Oye, pues me parece un ejercicio interesante.
Dominar a hacer Fibonacci tanto con recursividad
como funciones generadoras, ¿vale?
Y esto lo hemos hecho aquí en un momentito.
No está mal.
No sé si conocíais las funciones generadoras,
pero si no las conocíais, las tenéis que dominar, ¿vale?
Bueno, y aprovecho que muchas gracias, Hernarzo.
Muchas gracias, Evoret.
Muchas gracias, Josef.
Feliz Pascua.
Muchas gracias, Lazul de Sondes, por suscribirse con Prime.
Voy a leeros.
Porque es una función generadora.
Porque hemos puesto asterisco.
Y no bloquea el hilo, ¿vale?
El yield no bloquea el hilo.
Y para validar si ha terminado,
lo que se suele hacer es mirar el done.
Si es true o es false.
Es muy raro, ¿no?
Hay gente que dice que no lo ha usado nunca.
Para Fibonacci no es mejor la recursividad.
Pero ya hemos visto que a lo mejor
la recursividad es interesante
si sabemos el número de veces que queremos, ¿no?
O sea, si decimos lo queremos hacer cinco veces.
Pero imagínate que te dicen, bueno,
tiene que tener la serie de Fibonacci
cada vez que lo ejecutas, ¿no?
Cada vez que lo ejecutas
tienes que devolver el siguiente.
Y tú no sabes cuántas veces se va a ejecutar
porque por mil millones de razones, ¿vale?
Pues mira, así lo puedes hacer.
Es totalmente diferente.
Sería como otro caso de uso.
Pero bueno, no sé si lo sabíais.
Se puede crear un diccionario para eso.
Por lo menos se ejecuta más rápido, ¿vale?
A ver, un diccionario en el tema de Fibonacci
no tiene sentido
porque la gracia está en el cálculo del algoritmo.
Pero, bueno, se puede crear un diccionario
pero sería un poco raro, ¿vale?
Sí que en los casos más normales...
Bueno, normales no.
En los más básicos tiene sentido hacerlo, ¿no?
En el 0 y en el 1, por supuesto que tiene sentido.
Pero a partir de ahí ya hay que calcularlo
porque no puedes tener en el diccionario
infinitos números.
A no ser que os digan que solo la serie de Fibonacci
solo van a ser los cinco primeros
pero por lo demás no tiene sentido.
La azul de Sondes, gracias por el...
Ay, por el Prime.
Que es que pensaba que había hecho alguien una write
y pensaba que había sido tú.
Una link list haría lo mismo.
Se refiere a tener una memoization.
También se podría cachear, se puede mejorar.
Hola, Cami, ¿cómo está?
La recursividad cuesta, es verdad, ¿eh?
Pero al final la recursividad,
al menos con ejemplos como lo de Fibonacci,
hay que tenerlo en cuenta.
Lo más importante es la cláusula de escape.
Una vez que sabes que una recursividad
tiene que tener una cláusula de escape,
tampoco debería ser muy chungo.
Lo que ejecuto, lo que estoy utilizando
es run.js, ¿vale?
Veo que lo ha dicho ahí la gente.
Que mucha gente lo está preguntando, ¿vale?
Madre mía.
Gracias por los bits, wichos, 80.
No sé si se va con el hilo del stream,
pero no he podido resolver una cata de code wars
que involucre recursividad.
¿Lo podríamos hacer aquí?
Pues pásala y la miraremos.
A lo mejor hoy no,
y que ya hemos tocado recursividad
y tampoco quiero hacer una clase
que sea todo de recursividad.
Alguien me decía por aquí
que petaba con los números negativos,
pero bueno, lo hemos comentado.
¿Qué suelen colocar en entrevistas?
Vale, en entrevistas suelen hacer
un montón de preguntas.
A ver, a nivel técnico,
son, digamos, dos tipos de preguntas
que os pueden hacer.
Una, como hemos visto aquí,
las técnicas, ¿no?
Que sería, oye, hazme,
incluso te lo pueden pedir en la pizarra.
Esto es muy típico,
la de Fibonacci y recursividad en una pizarra.
Os lo pueden pedir,
y no tanto para ver si lo hacéis bien exactamente,
sino para ver si tenéis en cuenta
la cláusula de escape y cosas así,
que es como lo más básico.
Luego, pueden haber preguntas más de teoría, ¿vale?
Como por ejemplo,
¿qué es una cláusula?
¿Qué es this?
¿Qué es no sé qué?
¿Qué no sé cuánto?
¿Puedes explicar por qué hacen la suma
de n-1 y n-2?
Claro.
Esto aquí lo tengo comentado, ¿no?
Claro, o sea,
si yo lo que quiero aquí,
básicamente,
es la sucesión de números,
lo que hacemos,
voy a descuentarlo para que lo veamos.
Imaginemos el caso de Fibonacci 3, ¿vale?
Vamos a poner aquí el 3.
Fibonacci 3, que es el más sencillo.
Esto también es una cosa que os recomiendo mucho
para algoritmos y tal.
Empezar siempre con los casos más sencillos.
No solo para las cláusulas de escape,
sino que una vez que hacéis recursividad,
ir paso a paso con el caso más sencillo,
que es el 3, ¿no?
Entonces, imaginemos el 3.
Vamos a hacer el caso del 3.
Llegamos con Fibonacci 3.
Entonces, Fibonacci 3 lo que va a hacer es entrar por aquí,
no va a entrar ningún if,
y lo que va a hacer es devolver Fibonacci n-1,
que va a ser Fibonacci 2 más Fibonacci 1, ¿no?
Porque es n-2.
Entonces, es 3 menos 2, 1.
Entonces, Fibonacci 2 y Fibonacci 1,
si miramos en nuestra lista,
sería este y este, 0 y 1,
que son justos los que se tienen que sumar
para que te dé el resultado que queremos.
Y ya estaría.
Eso sería el caso.
Entonces, cuando tú aquí haces el Fibonacci 2,
lo que entras es otra vez a la nueva función,
pero aquí entrarías en n igual a 2
y devolverías 1.
Y el más del Fibonacci n-2 sería 0,
entraría en nuestra función y devolvería 0.
Y ya está. Eso es lo que hace.
Lo que estamos calculando es con el anterior
y con el previo del anterior.
Y ya con eso lo tendríamos.
Cuando sumas este, es este más este.
Y así siempre.
Claro, cuando es el 4,
ya se hace un poquito más complejo.
Con la recursividad es lo que tiene,
que se va haciendo un poco más compleja.
Pero si lo vas siguiendo,
verás que no tiene mucho.
En las entrevistas te ponen a recrear la matriz.
La matrix.
Así es la subsección de Fibonacci.
Vale.
Exacto.
Muy bien.
No se dijeron ya,
pero el HackerRank es una buena herramienta
para ir practicando.
Totalmente.
Súper interesante.
Meadu nunca había visto este tipo de funciones.
¿Has visto?
¿Has visto?
Que siempre se aprende algo.
Siempre se entiende algo.
Ahí está.
Aquí está.
Estabéis todos súper atentos en el chat.
Oye, ¿no?
Que has machacado.
Totalmente.
Sergiedo.
Muy bien.
Bueno, es que es lo que tiene el live coding.
Que uno se pone ahí.
¿El código lo sigue ejecutando luego el yield?
Sí.
O sea, cuando tú pones...
Esto encuentra un yield.
Vamos a quitar esto.
Vamos a poner esto.
Vale.
Cuando tú encuentras este yield,
aquí se para la ejecución de la función.
Se para.
Pero, ¿qué pasa?
Que una vez que retomas la ejecución,
cuando tú le das al punto next,
lo que hace es partir desde aquí.
¿Vale?
Lo que hace es partir desde aquí.
Entonces, sigue ejecutando, ejecutando.
Y por eso, fíjate que nunca aseguro,
muy pocas veces habréis visto un while true
que no bloquea nuestro programa.
No lo bloquea.
O sea, le estás diciendo, vale, while true.
Fíjate, es que me parece uno de los mejores ejemplos
para hacer una de Fibonacci.
Seguro que se puede hacer de otras formas.
Yo lo he hecho de esta forma por no sé qué.
Pero para que lo tengáis en cuenta.
Esto, por ejemplo, lo podríamos poner aquí.
Y aquí, pues, primero devolver este.
Luego devolver este.
Para que sea un poco menos de código.
Pero es un ejemplo muy, muy, muy, muy bueno.
Creo que es un ejemplo que deberíais controlar
para saber que es una función generadora.
Y a partir de aquí, pues, nada, hacerle cambios y lo que sea.
¿Cómo se hace una función generadora con Arrow Functions?
Que yo sepa, una Arrow Function no puede ser una función generadora.
Creo que no.
No sé si se puede.
Pero creo que no.
Yo no la conozco, desde luego.
Creo que las funciones generadoras tienen que ser así.
No se puede hacer de otra forma, ¿vale?
No puedes utilizar una Arrow Function para hacerlo.
No puedes hacer Arrow Function asterisk.
Esto no se puede hacer.
Hasta donde yo sé, ¿eh?
Igual la han sacado algo nuevo.
O, ¿sabes?
Estas cosas siempre van cambiando.
Pero no, no se puede.
Las generadoras se usan mucho en Redact Saga.
Sí, os lo he comentado antes.
Que una de las pocas...
Estas no son pruebas para juniors.
Para semiseniors yo tampoco diría, ¿vale?
Yo diría que esto es más para seniors.
Pero me pareció interesante, sobre todo,
porque si soy juniors o semiseniors,
pues, hemos explicado desde cero
que es una función generadora.
Y, hombre, si no lo sabíais, lo sabéis ahora.
Y de esta forma, incluso podéis llegar a saber más que algunos senios.
Que habrá muchos, muchos, muchos, muchos senios
que seguramente no saben utilizar
o no saben qué es una función generadora.
Así que no, tampoco digáis,
ah, bueno, como soy junior, esto no me interesa.
Yo no lo recomiendo,
porque ya que lo hemos aprendido desde cero
y os he explicado qué es cada cosa y cómo hacerlo,
pues, creo que esto,
aunque no lo veáis en vuestro día a día,
es una parte del lenguaje.
Lo que sí que es interesante,
y muy poca gente sabe,
que mucha gente dice que la SinkAwait
por detrás utiliza promesas.
Pero eso no es así, ¿vale?
Lo que utiliza son generadores.
Y esto que estáis aprendiendo,
en realidad,
lo se usa con la SinkAwait.
Cuando veis una SinkAwait,
de hecho, mirad,
lo vamos a ver en un momento.
Esto ya es, o sea,
esto está muy bien,
porque esto no se ve en cualquier sitio, ¿vale?
Esto no se ve en cualquier sitio.
Vamos a ver.
Si hacemos una función asíncrona aquí,
esto es el REPL de Babel.
Si ponemos aquí una función GET whatever,
whatever,
ay, me está dejando la Sink.
Vamos a ver.
Stage2, preset.
Esto.
Vale.
Fíjate.
Mira, ya ves tú las tres líneas de código
que he puesto en Babel
y todo lo que me ha generado aquí.
Pero si lo miráis,
si os ponéis a mirar un poco por encima,
no hace falta dominarlo, ¿eh?
Pero para que veáis un poco por encima,
vais a ir viendo que veis que pone
AsyncToGenerator
y lo que está utilizando es el punto NEXT
y cosas así que ahora hemos puesto.
¿Veis?
Aquí tenemos el NEXT,
el DON,
¿veis?
el DON,
el cómo se está haciendo esto en realidad
es utilizando funciones generadoras,
¿vale?
Así que nada,
tenerlo súper, súper, súper en cuenta
que son con funciones generadoras.
Uy, me he cargado mi ventana.
Vamos ahí otra vez.
Ok.
Yo aún no tengo mi primer empleo.
No soy junior,
pero lo estudio en cursos.
Muy bien.
Midu, ¿tú has hecho entrevistas?
Buah.
Fercho, yo he hecho,
pero cientos,
cientos y cientos de entrevistas.
Cientos y cientos y cientos de entrevistas.
Vamos, pero...