<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joaquin "Florius" Azcarate</title>
    <description>The latest articles on DEV Community by Joaquin "Florius" Azcarate (@florius).</description>
    <link>https://dev.to/florius</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F489423%2Fdf197b20-0375-4f43-bd0b-51e88a704cdd.jpeg</url>
      <title>DEV Community: Joaquin "Florius" Azcarate</title>
      <link>https://dev.to/florius</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/florius"/>
    <language>en</language>
    <item>
      <title>Inspiraciones</title>
      <dc:creator>Joaquin "Florius" Azcarate</dc:creator>
      <pubDate>Sun, 31 Jan 2021 14:20:44 +0000</pubDate>
      <link>https://dev.to/florius/inspiraciones-824</link>
      <guid>https://dev.to/florius/inspiraciones-824</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Te pasa de querer programar algo y no saber que? tengo un bloqueo de ideas hace tiempo, quiero hacer algo con xxx y no se me ocurre qué /cazzo/ hahcer&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Así empezó la conversación con un amigo. Después de hablar un poco, creo haber destilado un par de ideas que me gustaría compartir&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Por qué yo?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Q&lt;/strong&gt;: Habiendo miles de otros posts de miles de otras personas -muchas mejor calificadas que yo-, por qué leer este?&lt;br&gt;
&lt;strong&gt;A&lt;/strong&gt;: Creo que mi enfoque es mucho más especifico del que eh encontrado: Proyectos personales de programación, cuyo principal &lt;em&gt;driver (1)&lt;/em&gt; es aprender algo nuevo.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Prove it
&lt;/h3&gt;

&lt;p&gt;En mi porfolio (&lt;a href="https://florius.com.ar/"&gt;florius.com.ar&lt;/a&gt;) podrás ver alguno de los proyectos más recientes y más interesantes. No son muchísimos, pero son algunos. Siempre estoy &lt;em&gt;tinkering (2)&lt;/em&gt; con algo nuevo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fuentes de inspiración
&lt;/h2&gt;

&lt;p&gt;Voy a separar la inspiración en 3 categorías, no porque una sea más "fácil" o menos costosa; si no porque he conocido personas que están muy entonadas con una u otra categoría, y tal vez alguna de esta resuene más contigo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 1 - Directo
&lt;/h3&gt;

&lt;p&gt;En el trabajo, me pasa a veces que estoy haciendo algo, y pienso&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Uh, esto sería super guay si fuese así”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pero caigo en la realidad de que no habría forma que pueda completar el feature en el tiempo si hiciera todo ese cambio, ni que me aprueben un PR si agrego siete millones de bibliotecas 😅.&lt;br&gt;
Entonces me lo anoto:&lt;br&gt;
“Estaría bueno una aplicación que haga X o una biblioteca que haga Y”.&lt;/p&gt;

&lt;p&gt;Tiene una aplicación real, concreta y directa (por eso el nombre); que si existiese la usaría aquí y ahora. Pero no existe.&lt;/p&gt;

&lt;p&gt;Algunos ejemplos de esto mismo&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jazcarate/koncierge"&gt;GitHub :: koncierge 🔔&lt;/a&gt;: Necesitabamos segmentar clientes según un u otro atributo; entonces se me ocurrió que un DSL parecido al query-dsl de Mongo podría verse bien. Finalmente terminamos utilizando algo similar en produción!&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jazcarate/aao"&gt;GitHub:: Apples and Oranges&lt;/a&gt;:  Tambien en el trabajo quería una forma de testear un código que tenía todos &lt;code&gt;BigInt&lt;/code&gt;s, algunos números tenían impuestos otros no; entonces no podía sumar libremente unos con otros; por lo que me ocurrió una librería para “tagear” objetos.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jazcarate/marble-os"&gt;GitHub :: marble-OS&lt;/a&gt;: En la facultad, para probar y evaluar trabajos prácticos, muchas veces necesitabamos lanzar programas de manera sincronizada. La mejor herramienta hasta el momento era ser una persona alta que pueda presionar en dos computadoras diferentes la tecla &lt;code&gt;↵ Enter&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para este tipo de proyectos, recomiendo siempre estar atento a hacerse este tipo de preguntas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Este feature/bug/issue en el que estoy trabajando: ¿Tiene alguna parte súper interesante que podría extraer en su propia cosa?&lt;/li&gt;
&lt;li&gt;¿Puedo desacoplar completamente esta sección de lógica en su propia cosa?&lt;/li&gt;
&lt;li&gt;Veo que alguien tomó esta decisión de arquitectura; ¿por qué no lo habrán hecho diferente? ¿puedo hacerlo de otra forma?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Level 2 - Concretization
&lt;/h3&gt;

&lt;p&gt;Otra “forma” que suelo descubrir nuevas ideas es encontrar un blog post o algo que sea una idea abstracta, y convertirla en algo más concreto.&lt;br&gt;
No es casual que me guste mirar videos sobre matemática!&lt;/p&gt;

&lt;p&gt;En esta categoría no empiezo de un proyecto como en la categoría anterior, si no que llego a un proyecto desde algo más abstracto.&lt;/p&gt;

&lt;p&gt;Algunos ejemplos de mis proyectos que surgieron a partir de esta forma de encarar problemas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jazcarate/aao#tag-laws"&gt;GitHub:: Apples and Oranges # leyes de tags&lt;/a&gt;: Hace algunos 3 años vi una charla de “propagators” por &lt;a href="https://www.youtube.com/watch?v=acZkF6Q2XKs"&gt;YouTube :: Edward Kmett&lt;/a&gt;. Sumamente interesante! Adicionalmente semirretículos es un tema que eh dado en clase de Matemática Discreta; y nunca le encontré una aplicación tan directa y &lt;em&gt;linda&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jazcarate/tryhard/blob/main/src/Tryhard/TUI.hs#L360-L362"&gt;GitHub :: Tryhard # applicativos en todos lados&lt;/a&gt; _(warning: el código es un desastre, estaba trabajando en eso, pero otro proyecto se llevó toda mi atención por ahora 🙈): También viendo un video de &lt;a href="https://www.youtube.com/watch?v=RtYWKG_zZrM"&gt;YouTube :: Tsoding&lt;/a&gt; y la relación de &lt;a href="https://hackage.haskell.org/package/base-4.14.1.0/docs/Control-Applicative.html#t:Applicative"&gt;Applicative&lt;/a&gt; y &lt;a href="https://hackage.haskell.org/package/base-4.14.1.0/docs/Data-Monoid.html#t:Monoid"&gt;Monoid&lt;/a&gt; y como podríá usar esto para "sumar" resultados de &lt;a href="https://www.opendota.com/"&gt;OpenDota&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WIP&lt;/strong&gt; &lt;code&gt;rapt&lt;/code&gt;: También en un video de &lt;a href="https://www.youtube.com/user/Computerphile"&gt;YouTube :: Computerphile&lt;/a&gt; &lt;em&gt;(¿tendré un problema con la consumición de videos?)&lt;/em&gt; sobre onion routing, y encriptación en capas; junto con contraseñas y &lt;em&gt;OTP (3)&lt;/em&gt;. Se que tengo una idea ahí, pero creo que es muy parecida a &lt;a href="https://www.vaultproject.io/"&gt;Vault, de HashiCorp&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para este tipo de proyectos recomiendo pensar cada vez que escuches o leas algo (no importa de que; no digo oque hay que solo hacer uso de matemática! Estoy seguro que otras ramas de la ciencia son tan aptas a esto.) pensar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;¿Cómo podría usar eso?&lt;/li&gt;
&lt;li&gt;¿En qué universo esta idea sería útil?&lt;/li&gt;
&lt;li&gt;¿Veo que dice que se puede usar en &lt;code&gt;X&lt;/code&gt; e &lt;code&gt;Y&lt;/code&gt;; se podrá usar en &lt;code&gt;Z&lt;/code&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(&lt;strong&gt;bonus&lt;/strong&gt;: Creo que este mentalidad ayuda mucho a adquirir nuevos conocimientos. Más que una atención pasiva sobre un tema nuevo)&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 3 - Snapshot
&lt;/h3&gt;

&lt;p&gt;A mi gusto, la mejor forma de inspiración: Cuando pienso solo en una interacción, en una pantalla, en un link.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://jazcarate.github.io/es-dia-de-helado-de-fruta/"&gt;GitHub :: es-dia-de-helado-de-fruta&lt;/a&gt;: Mi novia me dijo que hoy no era día de helado de fruta, porque hacía mucho frio. Sería ideal tener una página que le pueda pasar para &lt;strong&gt;demostrarle&lt;/strong&gt; la temperatura&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://frasal.florius.com.ar/?q=velocidad%20de%20dios"&gt;FrasaL&lt;/a&gt;: Tienes un amigo que habla español traduciendo &lt;strong&gt;literalmente&lt;/strong&gt;  verbos preposicionales del ingles? Dice cosas como “velocidad de dios” en vez de “buena suerte”, y quieres pasar una página como &lt;a href="https://www.deepl.com/en/translator"&gt;DeepL&lt;/a&gt; para ayudar a otras personas a comprenderle?&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/JuanFdS/delCanioBot"&gt;GitHub :: delCanioBot&lt;/a&gt;: Necesitas un bot que genere imágenes de Nicolás del Caño, a razón de el &lt;em&gt;&lt;a href="https://www.youtube.com/watch?v=tdOP4V4mtoY"&gt;meme del año, Nico del Caño&lt;/a&gt;&lt;/em&gt;?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A veces estos &lt;em&gt;chistes&lt;/em&gt; incluso terminan siendo aplicaciones de verdad, como una aplicación para coordinar car pooling (&lt;a href="https://github.com/jazcarate/catapult"&gt;GitHub :: catapult&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;No tengo una buena recomendación para estos proyectos "chistes", más que intentar hacerte pensar que no necesariamente un proyecto tiene que ser completamente serio; y son muchas veces estos proyectos que se combinan y que sirven de lugar para aprender nuevas tecnologías o metodologías. Y te podrían brindar un &lt;em&gt;armazón&lt;/em&gt; para proyectos al futuro.&lt;/p&gt;

&lt;h3&gt;
  
  
  Level 9000 - Todas las anteriores
&lt;/h3&gt;

&lt;p&gt;Lamentablemente, la “creatividad” no es un proceso súper directo. A veces algo sale por un lado, a veces por otro. A veces 2 ideas inconexas se conectan en una idea mejor.&lt;br&gt;
Personalmente, me gusta escribir estas esbozos de ideas en un receptáculo físico. hay quienes prefieren un archivo en la computadora. Hay quienes tienen varios pre-ideas en la mente a la vez y nueva información decanta esas pre-ideas en un proyecto.&lt;/p&gt;

&lt;p&gt;Gracias por tu tiempo, y espero que algo de todo esto te ayude a encontrar inspiración!&lt;/p&gt;

&lt;p&gt;La imagen de la portada es de &lt;a href="https://unsplash.com/@joszczepanska?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Jo Szczepanska&lt;/a&gt; en &lt;a href="https://unsplash.com/s/photos/project?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Glosario&lt;/strong&gt;:&lt;br&gt;
1: &lt;em&gt;driver&lt;/em&gt;: Un factor que hace que suceda o se desarrolle un fenómeno particular.&lt;br&gt;
2: &lt;em&gt;tinkering&lt;/em&gt;: Intentar reparar o mejorar algo de manera casual o poco metódica.&lt;br&gt;
3: &lt;em&gt;otp&lt;/em&gt;: One-time password&lt;/p&gt;

</description>
      <category>help</category>
      <category>productivity</category>
      <category>personal</category>
      <category>project</category>
    </item>
    <item>
      <title>Haskell para mentes imperativas</title>
      <dc:creator>Joaquin "Florius" Azcarate</dc:creator>
      <pubDate>Thu, 03 Dec 2020 20:38:38 +0000</pubDate>
      <link>https://dev.to/florius/haskell-para-mentes-imperativas-4n7k</link>
      <guid>https://dev.to/florius/haskell-para-mentes-imperativas-4n7k</guid>
      <description>&lt;p&gt;&lt;em&gt;Foto de portada por &lt;a href="https://unsplash.com/@edurnepaula?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Edurne Chopeitia&lt;/a&gt; en &lt;a href="https://unsplash.com/s/photos/mind?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Browseando YouTube encontré una playlist con un nombre muy interesante: “&lt;a href="https://www.youtube.com/watch?v=Vgu82wiiZ90&amp;amp;list=PLe7Ei6viL6jGp1Rfu0dil1JH1SHk9bgDV"&gt;Haskell for Imperative Programmers&lt;/a&gt;” en donde el autor Philipp Hagenlocher explica conceptos de Haskell en videos cortos, concisos, con varios ejemplos y hasta algunos ejercicios. Lo que me inspiró a pensar cómo podría aprender alguien que tiene raíces en un paradigma imperativo. Por suerte no tuve que usar mucho la imaginación, ya que yo comencé con lenguajes imperativos, y en mi trabajo utilizo mayoritariamente el paradigma de objetos.&lt;/p&gt;

&lt;p&gt;En este post quiero explorar algunas cosas que creo que me hubiesen servido para aprender Haskell. Teniendo una base en algún lenguaje imperativo, usar esta para programar en Haskell.&lt;/p&gt;

&lt;p&gt;Si crees que entras en esta categoría, continúa leyendo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prefacio
&lt;/h3&gt;

&lt;p&gt;En este post haré uso de analogías y de patrones fuertemente asociados a la programación imperativa, de tal forma que la carga para aclimatarse al nuevo paradigma sea la menor posible, pero no considero esta la mejora forma de programar de forma funcional. Mi razonamiento es que: usando nuestro conocimiento previo ayude a comenzar a escalar la pendiente que es aprender un paradigma nuevo, y que esto a su vez dispare nuevas e interesantes investigaciones.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variables
&lt;/h2&gt;

&lt;p&gt;Veo muy comúnmente la cara de espanto cuando uno habla de un lenguaje, como Haskell, donde la inmutabilidad está por defecto. Prontamente surge la pregunta de “cómo puedo asignar una variable” o “como puedo cambiar el valor de un contador”.&lt;br&gt;
Recordemos que Haskell es un lenguaje de programación &lt;a href="https://es.wikipedia.org/wiki/Turing_completo"&gt;Turing completo&lt;/a&gt;, así que no es que &lt;em&gt;no se pueda&lt;/em&gt; hacer, solo que hay que reconocer  que hay diferentes formas de afrontar un problema.&lt;/p&gt;

&lt;p&gt;En Haskell, el símbolo &lt;code&gt;=&lt;/code&gt; no representa una asignación, si no es más próximo a la idea matemática del &lt;code&gt;=&lt;/code&gt; donde lo leemos (e interpretamos) como que algo &lt;strong&gt;es&lt;/strong&gt; otra cosa.&lt;/p&gt;

&lt;p&gt;En un lenguaje imperativo &lt;code&gt;x = 3&lt;/code&gt; lo leemos como “asignamos el valor &lt;code&gt;3&lt;/code&gt; a la variable &lt;code&gt;x&lt;/code&gt;”, donde en un paradigma funcional, lo deberíamos interpretar como “&lt;code&gt;x&lt;/code&gt; &lt;em&gt;es&lt;/em&gt; 3”. &lt;code&gt;x&lt;/code&gt; no puede cambiar. &lt;code&gt;x&lt;/code&gt; simplemente &lt;em&gt;es&lt;/em&gt;. &lt;/p&gt;

&lt;p&gt;Se que esta justificación suele no quitar el pavor. Tras indagar más a fondo, suelo descubrir que hay dos temas distintos (pero muy  sobrelapados en los lenguajes imperativos):&lt;/p&gt;

&lt;p&gt;Ponerle nombre a algo “intermedio”. Por ejemplo, si uno está escribiendo un método, y ve que hay una operación que se repite dos veces, suele ser considerado una buena práctica extraer lo común a una “variable” y ponerle nombre. Por ejemplo, podríamos empezar con un método:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;y luego refactorizar a algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;Int&lt;/span&gt; &lt;span class="n"&gt;tamaño&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tamaño&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tamaño&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En este acaso &lt;code&gt;tamaño&lt;/code&gt; si bien es una “variable”, su intención no es variar en el contexto de la función. Es tan común y útil poder aseverar sobre qué cosas no cambian, que en otros lenguajes existe la idea que las “variables” puedan ser constantes (vaya oxímoron). Como &lt;code&gt;const&lt;/code&gt; en JavaScript y PHP, &lt;code&gt;val&lt;/code&gt;/&lt;code&gt;var&lt;/code&gt;en Kotlin, variables en mayúsculas en Python o &lt;code&gt;final&lt;/code&gt; en Java.&lt;/p&gt;

&lt;p&gt;Lectores atentos pueden reconocer un potencial problema en esta refactorización, en donde no podemos asegurar 100% que el método &lt;code&gt;List::size()&lt;/code&gt; no cambia la lista, y que invocarlo 2 veces como en el código de “antes” podría no ser igual al código de “despues” en donde solo se invoca una vez. Dado que conocemos la semántica de &lt;code&gt;List::size()&lt;/code&gt;, podemos descansar que no va a alterar la lista; pero a veces, por la naturaleza de la mutabilidad, esto lleva a problemas. Toda una categoría de problemas que simplemente no pueden ocurrir en un mundo inmutable 😉.&lt;/p&gt;

&lt;p&gt;Esto mismo podríamos lograr en Haskell con palabras reservadas como &lt;code&gt;let … in&lt;/code&gt; o &lt;code&gt;where&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
         &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
       &lt;span class="kr"&gt;else&lt;/span&gt;
         &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y luego del refactor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
   &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;tama&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;
   &lt;span class="kr"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tama&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
         &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
       &lt;span class="kr"&gt;else&lt;/span&gt;
         &lt;span class="n"&gt;tama&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;foo&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;tama&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
         &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
       &lt;span class="kr"&gt;else&lt;/span&gt;
         &lt;span class="n"&gt;tama&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;
   &lt;span class="kr"&gt;where&lt;/span&gt; &lt;span class="n"&gt;tama&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;length&lt;/span&gt; &lt;span class="n"&gt;xs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si bien hacen lo mismo, tienen sutiles diferencias a las entraré en detalle (pero si está aquí: &lt;a href="https://wiki.haskell.org/Let_vs._Where"&gt;Let vs. Where - HaskellWiki&lt;/a&gt;).&lt;/p&gt;

&lt;h2&gt;
  
  
  Cosas que cambian
&lt;/h2&gt;

&lt;p&gt;El otro &lt;em&gt;sabor&lt;/em&gt; de variables, es el de algo que cambia; y aquí, no tenemos suerte. No vamos a poder hacerlo. Pero eso no quita que podamos generar abstracciones para poder escribir algo que &lt;em&gt;se parezca&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Pero antes de hablar de cosas que cambian, primero necesitamos estar de acuerdo en algunas convenciones. Cosas como&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En donde una función altera el valor que se le pasa son &lt;em&gt;el mal&lt;/em&gt;, y no poder hacerlo es un &lt;em&gt;feature&lt;/em&gt; (Aunque me encanta la idea de &lt;a href="https://www.tweag.io/blog/2020-11-11-linear-dps/"&gt;Pure destination-passing style in Linear Haskell&lt;/a&gt; cuando se apalanca del maravilloso sistema de tipos).&lt;/p&gt;

&lt;p&gt;Algo mucho más sensible sería una función que tome el argumento y devuelva un nuevo número, resultado de la suma del argumento y 4. &lt;/p&gt;

&lt;p&gt;Pero no siempre es tan sencillo. A veces tenemos varias mutaciones encadenadas, o unas que dependen de otras; por lo que podemos aplicar este algoritmo mental:&lt;br&gt;
Cada vez que fuésemos a cambiar una variable, en realidad utilizaremos una nueva variable que sea el resultado del cambio, y de ahora en adelante, utilizar el nuevo nombre.&lt;/p&gt;

&lt;p&gt;Por ejemplo, con la nueva herramienta de &lt;code&gt;let … in&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;buzz&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; 
       &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
       &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
       &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
       &lt;span class="n"&gt;x3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
  &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;x3&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si esta forma de escribir parece tediosa (lo es!), al final de la próxima sección volveremos sobre esto, pero todavía tenemos algo que podemos hacer. Revisemos qué es lo que es tan inconveniente: nombrar los pasos intermedios (&lt;code&gt;x0 - x3&lt;/code&gt;) ¿Podemos no hacerlo?.&lt;/p&gt;

&lt;p&gt;De esta forma nos acercamos a un patrón muy común en funcional, en donde uno tiene funciones intermedias que toman un valor, y devuelven “el nuevo” valor. Podemos concatenar estas operaciones (que hablan de cambios, no de variables).&lt;/p&gt;

&lt;p&gt;Imaginemos el mismo ejemplo, pero vamos a re escribirlo en pequeñas funciones intermedias que cambien el valor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;buzz&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kr"&gt;let&lt;/span&gt; &lt;span class="n"&gt;f0&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
       &lt;span class="n"&gt;f1&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
       &lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
       &lt;span class="n"&gt;f3&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

       &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
       &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f0&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;
       &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f1&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;
       &lt;span class="n"&gt;x3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f2&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
  &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;f3&lt;/span&gt; &lt;span class="n"&gt;x3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lamentablemente como es un ejemplo tan sintético, los nombres de las funciones intermedias serán malos; pero espero que puedan imaginarse que estas funciones sean cosas como &lt;code&gt;incrementarEdad&lt;/code&gt;, &lt;code&gt;extraerDinero&lt;/code&gt; u otro nombre más cercano al dominio de lo que esten programando.&lt;/p&gt;

&lt;p&gt;Por ello voy a cambiar levemente el ejemplo para tener algo que sea más humanamente legible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;esValido&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
       &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
       &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;
       &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;
  &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;esValido&lt;/span&gt; &lt;span class="n"&gt;x2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora podemos intentar pensar sobre nuestra &lt;code&gt;tarjetaValida&lt;/code&gt;, donde lo que tiene que pasar es, en orden: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dado un número pasado como parámetro (&lt;code&gt;n&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Tomamos el número validador (&lt;code&gt;x mod 3&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Lo normalizamos (&lt;code&gt;x + 2&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Migramos el coeficiente (&lt;code&gt;x + 5&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Y chequeamos que sea válido (&lt;code&gt;x &amp;gt; 3&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Probablemente todavía no sea evidente, pero ahora podemos hacer un refactor de “inline” en cada variable intermedia (&lt;code&gt;x0 - x3&lt;/code&gt;). Empecemos con &lt;code&gt;x3&lt;/code&gt; e iremos ineline-ando de a una&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
       &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
       &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;
       &lt;span class="n"&gt;x2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;
  &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;esValido&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt;  &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
       &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
       &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;
  &lt;span class="kt"&gt;In&lt;/span&gt; &lt;span class="n"&gt;esValido&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizarValidador&lt;/span&gt;  &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
       &lt;span class="n"&gt;x0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
  &lt;span class="n"&gt;esValido&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;esValido&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto se parece mucho más a la descripción funcional de &lt;code&gt;tarjetaValida&lt;/code&gt;, pero está escrito “al revés”. Por razones como esta existen &lt;a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Function.html#v:-38-"&gt;combinadores como &lt;code&gt;&amp;amp;&lt;/code&gt;&lt;/a&gt;, donde hablando mal y pronto, éste es el operador de &lt;em&gt;aplicación reversa&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;esValido&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Es interesante notar como todas nuestras funciones de “cambio” tienen la misma firma: &lt;code&gt;:: Int -&amp;gt; Int&lt;/code&gt;. De forma más genérica, son funciones que toman un valor de un tipo, y &lt;em&gt;devuelven&lt;/em&gt; algo del mismo tipo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Aplicación parcial
&lt;/h3&gt;

&lt;p&gt;Con el código que tenemos hasta aquí; podríamos cambiarlo para que &lt;code&gt;migrarCoeficiente&lt;/code&gt; no siempre sume 5, si no que pueda ser parametrizable por una letra.&lt;br&gt;
Sabiendo que hay una función que transforma una letra a un número &lt;a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Char.html#v:ord"&gt;&lt;code&gt;ord :: Char -&amp;gt; Int&lt;/code&gt;&lt;/a&gt; &lt;br&gt;
Podríamos cambiar &lt;code&gt;migrarCoeficiente&lt;/code&gt; a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Char&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="n"&gt;letra&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ord&lt;/span&gt; &lt;span class="n"&gt;caracter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ahora nuestra &lt;code&gt;tarjetaValida&lt;/code&gt; no sufre muchos cambios:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;tarjetaValida&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;numeroValidador&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;normalizarValidador&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;migrarCoeficiente&lt;/span&gt; &lt;span class="sc"&gt;'f'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;
  &lt;span class="n"&gt;esValido&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y eso fué gracias a &lt;a href="http://aprendehaskell.es/content/OrdenSuperior.html"&gt;la currificación&lt;/a&gt; de todas las funciones en Haskell!&lt;/p&gt;

&lt;h3&gt;
  
  
  A veces
&lt;/h3&gt;

&lt;p&gt;Otro gran “hack” que nos permite la mutabilidad, es la de cambiar el valor, pero solo según un flujo de control. Algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;qux&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ret&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En donde asignamos una variable que según uno u otro flujo de control puede cambiar. Siempre podremos reescribir esto de forma inmutable. Por ejemplo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;qux&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="kr"&gt;else&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interesante notar que necesitamos un &lt;code&gt;else&lt;/code&gt; que “deje todo como estaba”, pues no podemos “no hacer nada” en esta forma de escribirlo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monadas
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;(No podía ser un post de Haskell, y no mencionar a las monadas)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Una idea en la programación imperativa muy arraigada es que uno escribe una línea debajo de la otra, y esto hace que se ejecuten en ese orden.&lt;br&gt;
Tan arraigada que casi no se considera una decisión del lenguaje, pero lo es! Es una decisión de diseño, y una que en un paradigma funcional es fácil escaparse.&lt;/p&gt;

&lt;p&gt;Pero a veces, queremos ordenar una secuencia de cosas. Recordemos el ejemplo anterior de &lt;code&gt;buz&lt;/code&gt;. Hay una monada (y probablemente &lt;a href="http://aprendehaskell.es/content/MasMonadas.html"&gt;miles de&lt;/a&gt; &lt;a href="https://gist.github.com/sdiehl/8d991a718f7a9c80f54b"&gt;tutoriales de&lt;/a&gt; &lt;a href="https://wiki.haskell.org/State_Monad"&gt;como&lt;/a&gt; &lt;a href="https://mmhaskell.com/monads/state"&gt;implementarla&lt;/a&gt;) llamada “state” que representa una forma de secuenciar operaciones, e ir mutando un valor. Por lo que uno podría escribir algo mucho más parecido a la forma imperativa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="cd"&gt;--            |----- Va a ir mutando un Int&lt;/span&gt;
&lt;span class="c1"&gt;--            v   v- va a retornar un booleano&lt;/span&gt;
&lt;span class="n"&gt;buz&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;State&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="kt"&gt;Bool&lt;/span&gt;
&lt;span class="n"&gt;buz&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="p"&gt;`&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="p"&gt;`&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;put&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;set&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
  &lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;\&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ret&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada &lt;code&gt;ret&lt;/code&gt; en este caso solo existe dentro del lambda &lt;em&gt;(todo lo que esté entre &lt;code&gt;(\&lt;/code&gt; y &lt;code&gt;)&lt;/code&gt;)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Muchas veces se ven las monadas con el &lt;a href="https://es.wikipedia.org/wiki/Az%C3%BAcar_sint%C3%A1ctico"&gt;&lt;em&gt;azúcar sintáctico&lt;/em&gt;&lt;/a&gt; de la notación &lt;code&gt;do&lt;/code&gt;, que lo hace muy conveniente porque nos deja, como en un paradigma imperativo, escribir una línea debajo de la otra.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monadas Cont.
&lt;/h3&gt;

&lt;p&gt;Otra gran razón para implementar una secuencia de operaciones, es que estas puedan fallar. El fallo en cualquier renglón invalide toda la computación. Pensemos en métodos que podrían lanzar excepciones.&lt;br&gt;
Para esto también existe una monada! Y podríamos escribir algo como:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;precio&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;itemConNombre&lt;/span&gt; &lt;span class="nv"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;item&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inventario&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="kt"&gt;Errores&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;noExiste&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cantidad&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="kt"&gt;Errores&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fueraDeStock&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;De esta forma&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Errores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;FueraDeStock&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kt"&gt;NoExiste&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;

&lt;span class="n"&gt;buscar&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Inventario&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Item&lt;/span&gt;
&lt;span class="n"&gt;buscar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Either&lt;/span&gt; &lt;span class="kt"&gt;Errores&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;
&lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;maybe&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;NoExiste&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="kt"&gt;Right&lt;/span&gt; &lt;span class="n"&gt;itemEncontrado&lt;/span&gt; &lt;span class="c1"&gt;-- (1)&lt;/span&gt;
    &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cantidad&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Left&lt;/span&gt; &lt;span class="kt"&gt;FueraDeStock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;return&lt;/span&gt; &lt;span class="n"&gt;precio&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;
  &lt;span class="kr"&gt;where&lt;/span&gt;
    &lt;span class="n"&gt;itemEncontrado&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Maybe&lt;/span&gt; &lt;span class="kt"&gt;Item&lt;/span&gt;
    &lt;span class="n"&gt;itemEncontrado&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buscar&lt;/span&gt; &lt;span class="n"&gt;inventario&lt;/span&gt; &lt;span class="n"&gt;nombre&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La idea de la función &lt;a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/Prelude.html#v:maybe"&gt;&lt;code&gt;maybe&lt;/code&gt;&lt;/a&gt; es poder extraer el valor de un &lt;code&gt;Maybe&lt;/code&gt; (algo que puede o no estar). En el caso de que pueda fallar, &lt;em&gt;devolveremos&lt;/em&gt; un &lt;code&gt;Left&lt;/code&gt; (recordemos, representaría como lanzar una excepción), y en el caso que hubiese un &lt;code&gt;Item&lt;/code&gt;, devolveremos un &lt;code&gt;Right&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;De esta forma, no &lt;em&gt;ejecutaremos&lt;/em&gt; el &lt;code&gt;return&lt;/code&gt; hasta que no pasen las dos condiciones anteriores.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getter y Setter
&lt;/h2&gt;

&lt;p&gt;Por último, quiero tocar algo de modelado, y la parte de lo que menos quiero escribir, porque es la que más se separa del paradigma; pero no obstante puedo ver cómo alguien puede estar tentado a utilizar herramientas de modelado de paradigmas que ya conoce, y pensar en un &lt;a href="http://aprendehaskell.es/content/ClasesDeTipos.html"&gt;&lt;em&gt;record&lt;/em&gt;&lt;/a&gt; es parecido a un objeto. Pero si así fuera… donde ponemos los métodos de este objeto?! (Sin entrar en el mundo de &lt;a href="https://hackage.haskell.org/package/lens"&gt;&lt;code&gt;lens&lt;/code&gt;&lt;/a&gt;).&lt;br&gt;
No voy a objetar (🤭) porque se que yo lo hice durante mucho tiempo, así que mientras que sepamos que hay &lt;em&gt;tela para cortar&lt;/em&gt;, por ahora puedo vivir con que pensemos que son objetos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Point&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;podríamos escribirlo así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Y tendremos &lt;em&gt;gratis&lt;/em&gt; la función &lt;code&gt;edad :: Persona -&amp;gt; Int&lt;/code&gt; que “saca” la edad de una persona. Cual un getter, y la construcción:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;cambiarEdad&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt;
&lt;span class="n"&gt;cambiarEdad&lt;/span&gt; &lt;span class="n"&gt;nuevaEdad&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nuevaEdad&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como un setter. Pero, como en OOP no estamos limitados a simplemente asignar el nuevo valor; podríamos hacer lo que queramos!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="n"&gt;cambiarEdad&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt;
&lt;span class="n"&gt;cambiarEdad&lt;/span&gt; &lt;span class="n"&gt;nuevaEdad&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nuevaEdad&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos encontrar un patrón recurrente, donde tengamos funciones que &lt;em&gt;terminen&lt;/em&gt; con el tipo: &lt;code&gt;foo :: … -&amp;gt; Algo -&amp;gt; Algo&lt;/code&gt;. Si recordamos el ejemplo de &lt;code&gt;tarjetaValida&lt;/code&gt;, todas las funciones intermedias que teníamos eran del tipo: &lt;code&gt;:: Int -&amp;gt; Int&lt;/code&gt;, y el ejercicio al lector hubiera generado una función con el tipo: &lt;code&gt;:: Char -&amp;gt; Int -&amp;gt; Int&lt;/code&gt;. Podemos pensar en toda esta familia de funciones como funciones que “alteran”. Además ahora ya sabemos cómo combinarlas!&lt;br&gt;
Por ejemplo, concatenar listas  &lt;a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/GHC-List.html#v:-43--43-"&gt;&lt;code&gt;(++) :: [a] -&amp;gt; [a] -&amp;gt; [a]&lt;/code&gt;&lt;/a&gt; en donde toma una primera lista y una segunda, y las “altera” (recordando que en realidad lo que hace es &lt;em&gt;devolver&lt;/em&gt; una nueva lista) o tomar los primeros &lt;code&gt;n&lt;/code&gt; elementos (&lt;a href="https://hackage.haskell.org/package/base-4.14.0.0/docs/GHC-List.html#v:take"&gt;&lt;code&gt;take :: Int -&amp;gt; [a] -&amp;gt; [a]&lt;/code&gt;&lt;/a&gt;). Hay muchísimas funciones como estas, y probablemente escribamos tantas de estas como “métodos” podrían tener nuestros objetos, si lo modelamos en OOP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Persona&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;edad&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;altura&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;crecer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;años&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                 &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;años&lt;/span&gt;
                 &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;altura&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;años&lt;/span&gt;&lt;span class="p"&gt;*&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight haskell"&gt;&lt;code&gt;&lt;span class="kr"&gt;data&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;crecer&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt; &lt;span class="kt"&gt;Int&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt;
&lt;span class="n"&gt;crecer&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Persona&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;edad&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="n"&gt;altura&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;altura&lt;/span&gt; &lt;span class="n"&gt;persona&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="err"&gt;ñ&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Fin
&lt;/h2&gt;

&lt;p&gt;Espero que con estas herramientas, el prospecto de programar en Haskell sea menos aterrorizador.&lt;/p&gt;

</description>
      <category>functional</category>
      <category>haskell</category>
    </item>
    <item>
      <title>koncierge 🛎 :: Una librería para segmentar usuarios</title>
      <dc:creator>Joaquin "Florius" Azcarate</dc:creator>
      <pubDate>Wed, 14 Oct 2020 13:50:58 +0000</pubDate>
      <link>https://dev.to/florius/koncierge-una-libreria-para-segmentar-usuarios-fjp</link>
      <guid>https://dev.to/florius/koncierge-una-libreria-para-segmentar-usuarios-fjp</guid>
      <description>&lt;h1&gt;
  
  
  Trasfondo
&lt;/h1&gt;

&lt;p&gt;En donde estoy trabajando, cada nuevo feature o idea, pasa por un proceso de &lt;em&gt;A/B Testing&lt;/em&gt;.&lt;br&gt;
Normalmente lo que hacemos es:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generamos una hipótesis del estilo: "Si los usuarios tuviesen una notificación cuando pasa &lt;code&gt;X&lt;/code&gt;, entonces van a hacer &lt;code&gt;Y&lt;/code&gt; más seguido".&lt;/li&gt;
&lt;li&gt;Desatollamos esta notificación, o lo que sea.&lt;/li&gt;
&lt;li&gt;Apuntamos a algún mercado para participar de esta prueba&lt;/li&gt;
&lt;li&gt;Dividimos a la mitad de los usuarios de ese mercado, tal que vean e interactúen con en nuevo feature, mientras que la otra mitad (grupo &lt;em&gt;control&lt;/em&gt;) no.&lt;/li&gt;
&lt;li&gt;Esperamos dos semanas&lt;/li&gt;
&lt;li&gt;Comparamos las métricas entre los dos grupos.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Este último paso puede llevar a miles de ramificaciones: Activamos el feature para toda la población. Cambiamos algo y volvemos a hacer una prueba. Lo deshabilitamos por completo porque nuestra hipótesis era incorrecta. Etc, etc.&lt;/p&gt;

&lt;p&gt;Para la segmentación de la población, estamos usando un servicio de un tercero. A este servicio, ocasionalmente le brindamos la información de segmentación de nuestros usuarios.&lt;br&gt;
Información como&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;El usuario &lt;code&gt;123&lt;/code&gt; es de Madrid&lt;br&gt;
para que luego, cuando queramos segmentar, podríamos segmentar solo usuarios de Madrid.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Este servicio externo, adicionalmente, solo nos provee acceso a las variantes (si un usuario pertenece al segmento, es parte del grupo de control, o es parte del grupo que participa) mediante un SDK para usar en móviles (iOS y Android).&lt;/p&gt;

&lt;p&gt;Esto nos presentaba dos dificultades:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Si quisiéramos hacer un A/B Test en alguno de los micro-servicios de backend, no podríamos consultar a este servicio.&lt;/li&gt;
&lt;li&gt;Si quisiéramos segmentar por algo de lo que no le habíamos informado al servicio, deberíamos compartirle toda esta nueva información para que este pueda segmentar.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Por esta situación, decidimos crear un micro-servicio que se encargue de segmentar y separar en variantes a nuestros usuarios.&lt;/p&gt;
&lt;h1&gt;
  
  
  Problemas
&lt;/h1&gt;

&lt;p&gt;Rápidamente nos vimos enfrentados a resolver como hacer para obtener la información para segmentar.&lt;/p&gt;

&lt;p&gt;Normalmente segmentamos por país, lo que sería sencillo hacer que el nuevo micro-servicio consultara con otro micro-servicio de información; y obtuviese el país del usuario.&lt;br&gt;
Con esta nueva información, podríamos segmentar.&lt;/p&gt;

&lt;p&gt;Lo que presenta un desafío interesante:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como evitar que este micro-servicio crezca cada vez introduzcamos un nuevo micro-servicio que almacene alguna información del usuario?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Por eso, pensamos que podríamos delegar la responsabilidad de obtener el &lt;em&gt;contexto&lt;/em&gt; del usuario, a quien consuma este micro-servicio; por lo que una llamada podría ser:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dado el usuario &lt;code&gt;123&lt;/code&gt;, de Madrid; a qué variante pertenece?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;De esta manera, es quien consume quien necesita saber todas las dependencias del experimento, y cada experimento puede tener dependencias distintas, de distintas formas de computarse, y el micro-servicio podría no crecer.&lt;/p&gt;
&lt;h1&gt;
  
  
  DSL (Domain-specific language - Lenguaje específico de dominio)
&lt;/h1&gt;

&lt;p&gt;Ya sabíamos como querríamos que se comporte el micro-servicio, ahora necesitábamos una forma de expresar como querríamos segmentar nuestra población. Hacía poco estaba trabajando mucho con &lt;a href="https://www.mongodb.com/"&gt;&lt;code&gt;Mongo&lt;/code&gt;&lt;/a&gt; y se me ocurrió que un lenguaje de consultas como el de mongo podría ser interesante de explorar.&lt;br&gt;
De tal forma que una segmentación como:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Quiero que solo participen del experimento &lt;code&gt;EXP001&lt;/code&gt;, usuarios quienes sean de Madrid. De estos, la mitad estarán en el grupo de &lt;code&gt;participando&lt;/code&gt; y el esto en &lt;code&gt;control&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se transformaría en:&lt;/p&gt;

&lt;blockquote&gt;

&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"EXP001"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ubicación"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Madrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"$children"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"participando"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"$rand"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"$gt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"control"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://koncierge-playground.herokuapp.com/?context=%7B%0A%20%20%20%20%22ubicaci%C3%B3n%22:%20%22Madrid%22,%0A%20%20%20%20%22userId%22:%205%0A%7D&amp;amp;experiment=%7B%0A%20%20%20%20%22EXP001%22:%20%7B%0A%20%20%20%20%20%20%20%20%22ubicaci%C3%B3n%22:%20%22Madrid%22,%0A%20%20%20%20%20%20%20%20%22%24children%22:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22participando%22:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%24rand%22:%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22%24gt%22:%200.5%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D,%0A%20%20%20%20%20%20%20%20%20%20%20%20%22control%22:%20%7B%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D"&gt;&lt;em&gt;Playground&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;De esta manera, quien consuma al micro-servicio debería proveer, al menos, la información de la &lt;code&gt;"ubicación"&lt;/code&gt; del usuario.&lt;br&gt;
Una posible consulta podría ser con el &lt;em&gt;contexto&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ubicación"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Madrid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;El micro-servicio debería responder que pertenece al &lt;code&gt;EXP001&lt;/code&gt; (dado que la ubicación empareja con la definición), y podría pertenecer a la variante &lt;code&gt;participando&lt;/code&gt; o &lt;code&gt;control&lt;/code&gt;.&lt;br&gt;
Los usuarios deberían estar distribuidos 50%-50%; dado que hay un 50% de probabilidad que un numero al azar, uniformemente distribuido entre 0 y 1 (como es &lt;code&gt;$rand&lt;/code&gt;) sea mayor a 0.5.&lt;/p&gt;

&lt;p&gt;Con esta idea, sabiendo que la intención era que el micro-servicio no dependiente de ninguna otra parte de arquitectura de nuestro ecosistema; se me ocurrió que podría desarrollarlo como una librería pública; por si alguien más tiene la necesidad que tuvimos nosotros.&lt;/p&gt;

&lt;h1&gt;
  
  
  koncierge 🛎
&lt;/h1&gt;

&lt;p&gt;La librería está en &lt;a href="https://github.com/jazcarate/koncierge#readme"&gt;GitHub/jazcarate/koncierge&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cover image by &lt;a href="https://unsplash.com/@shotz?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Nicolas Cool&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/hotel-building?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>showdev</category>
      <category>development</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
