<?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: Willian Frantz</title>
    <description>The latest articles on DEV Community by Willian Frantz (@wlsf).</description>
    <link>https://dev.to/wlsf</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%2F482270%2F0705f655-033f-449f-800d-84ddef9f153d.png</url>
      <title>DEV Community: Willian Frantz</title>
      <link>https://dev.to/wlsf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/wlsf"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Mon, 05 Jan 2026 22:05:44 +0000</pubDate>
      <link>https://dev.to/wlsf/-a1f</link>
      <guid>https://dev.to/wlsf/-a1f</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/mensonones/react-native-em-alta-performance-expo-modules-c-e-simd-arm-neon-4bhg" class="crayons-story__hidden-navigation-link"&gt;React Native em Alta Performance: Expo Modules, C++ e SIMD (ARM NEON)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/mensonones" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F192520%2F5eec35d1-b513-4b48-945b-f71bd3422d3e.jpg" alt="mensonones profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/mensonones" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Emerson Vieira
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Emerson Vieira
                
              
              &lt;div id="story-author-preview-content-3149922" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/mensonones" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F192520%2F5eec35d1-b513-4b48-945b-f71bd3422d3e.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Emerson Vieira&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/mensonones/react-native-em-alta-performance-expo-modules-c-e-simd-arm-neon-4bhg" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jan 5&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/mensonones/react-native-em-alta-performance-expo-modules-c-e-simd-arm-neon-4bhg" id="article-link-3149922"&gt;
          React Native em Alta Performance: Expo Modules, C++ e SIMD (ARM NEON)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/expo"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;expo&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/reactnative"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;reactnative&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/android"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;android&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cpp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cpp&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/mensonones/react-native-em-alta-performance-expo-modules-c-e-simd-arm-neon-4bhg" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/mensonones/react-native-em-alta-performance-expo-modules-c-e-simd-arm-neon-4bhg#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              2&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            5 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>expo</category>
      <category>reactnative</category>
      <category>android</category>
      <category>cpp</category>
    </item>
    <item>
      <title>Casamento de Padrões em Elixir</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Wed, 07 May 2025 18:50:11 +0000</pubDate>
      <link>https://dev.to/wlsf/casamento-de-padroes-em-elixir-1a98</link>
      <guid>https://dev.to/wlsf/casamento-de-padroes-em-elixir-1a98</guid>
      <description>&lt;p&gt;Você sabia que tanto Erlang como Elixir não possuem um operador de atribuição?&lt;br&gt;
Ou seja, o que significa a seguinte expressão abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mais conhecido como &lt;strong&gt;Pattern Matching&lt;/strong&gt;, esse mecanismo te permite fazer associações de valores através&lt;br&gt;
da comparação de símbolos entre o lado esquerdo do operador e o lado direito.&lt;/p&gt;

&lt;p&gt;Na prática:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello_world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello_world&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Hello "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os 2 exemplos acima ilustram o funcionamento do casamento de padrões.&lt;br&gt;
Onde a primeira execução aparenta ser uma simples atribuição, mas a partir da segunda, é possível perceber uma grande diferença conceitual.&lt;/p&gt;

&lt;p&gt;No segundo exemplo a runtime irá tentar encontrar o valor &lt;code&gt;"Hello "&lt;/code&gt; no valor do lado direito do operador, se esse valor for encontrado(deu match)&lt;br&gt;
o resto do valor será armazenado na variável &lt;code&gt;world&lt;/code&gt;.d&lt;/p&gt;

&lt;p&gt;Quando essa assertiva não acontece, e o padrão não é encontrado, uma exception é gerada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Hellu "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MatchError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;no&lt;/span&gt; &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt; &lt;span class="n"&gt;hand&lt;/span&gt; &lt;span class="n"&gt;side&lt;/span&gt; &lt;span class="ss"&gt;value:&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Essa é uma das minhas funcionalidades favoritas no ecossistema Erlang/Elixir, e neste texto vou tentar sintetizar um pouco do porquê.&lt;/p&gt;

&lt;p&gt;Ex-1. Em Elixir, o casamento de padrões pode ser utilizado em Strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Apenas uma comparação e nada acontece, pois o padrão é encontrado (caso contrário, geraria uma exception)&lt;/span&gt;
&lt;span class="s2"&gt;"Hello World"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila o valor "World" à variável world&lt;/span&gt;
&lt;span class="s2"&gt;"Hello "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;

&lt;span class="c1"&gt;# Mesmo resultado do exemplo acima, porém escrito de uma forma diferente. (usando operadores de bitstring)&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"Hello "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila os primeiros 5 caracteres na variável hello, valida um espaço " ", e joga o resto da string na variável world&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;

&lt;span class="c1"&gt;# Como não existe nenhum padrão a ser encontrado, meio que simula uma atribuição.&lt;/span&gt;
&lt;span class="n"&gt;hello_world&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Hello World"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;É possível usar casamento de padrões com praticamente todos tipos, strings, listas, tuplas, maps, structs...&lt;/p&gt;

&lt;p&gt;Ex-2. Testando outros tipos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Apenas procura o padrão do lado esquerdo no lado direito do operador, o mesmo com as strings.&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&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="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila o valor 2 na variável second.&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;second&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;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila o valor 1 na variável first, e descarta os demais valores. (operadores importantes que usamos para listas `++` e `|`)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&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="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Ignora apenas o primeiro valor da lista, e assimila os demais na variável rest. (2, 3)&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;rest&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="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Simplesmente joga todos os valores da direita do operador na variável list.&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="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;E o quão relevante é este tipo de operação no dia-a-dia?&lt;br&gt;
Casamento de padrões pode ser utilizado em praticamente tudo, validação, polimorfia de funções, estruturas de controle, funções de ordem maior.&lt;/p&gt;

&lt;p&gt;Ex-3. Em Elixir costumamos trabalhar bastante com o conceito de Tuplas de erro ou sucesso, e isso vale para requests,&lt;br&gt;
comunicação externa, funções impuras, e por ai adiante...&lt;/p&gt;

&lt;p&gt;Digamos que a execução de uma função qualquer do nosso código irá retornar uma tupla de sucesso, contendo &lt;code&gt;{status, person}&lt;/code&gt;&lt;br&gt;
Podemos tirar vantagem do casamento de padrões nesse cenário para criar uma tomada de decisão no nosso código.&lt;/p&gt;

&lt;p&gt;Ilustração:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&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="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila o valor "Willian" na variável name.&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&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="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila todo o map da pessoa na variável person&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;person&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="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="c1"&gt;# Assimila :ok no status e o map pessoa na variável person&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;person&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="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="c1"&gt;# Joga todo o valor da direita do operador na variável tuple_result&lt;/span&gt;
&lt;span class="n"&gt;tuple_result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Criando uma tomada de decisão a partir desse valor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;print_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&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="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Houve um erro ao processar o resultado"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# se executarmos este código passando nosso resultado do exemplo anterior teríamos algo como:&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;print_name&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}})&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora com polimorfismo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;print_name&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&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;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&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;def&lt;/span&gt; &lt;span class="n"&gt;print_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Houve um erro ao processar o resultado"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em funções de ordem maior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;list_results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Algo deu ruim"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Algo deu ruim"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list_results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No caso acima, iremos filtrar da lista de resultados somente as tuplas de sucesso, e ignorar as que tiveram erro.&lt;/p&gt;

&lt;p&gt;Concluindo, essa funcionalidade me permiti flexibilidade na hora de manipular dados e basicamente escrever toda estrutura do meu código,&lt;br&gt;
tratamento de erros, estruturas condicionais, polimorfismo, e muito mais que não consigo nem lembrar direito.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
    </item>
    <item>
      <title>Consumindo GraphQL com Elixir?</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Thu, 02 Jun 2022 16:41:55 +0000</pubDate>
      <link>https://dev.to/wlsf/consumindo-graphql-com-elixir-2pp</link>
      <guid>https://dev.to/wlsf/consumindo-graphql-com-elixir-2pp</guid>
      <description>&lt;p&gt;Hoje em dia é muito comum ver um serviço backend em &lt;a href="https://elixir-lang.org"&gt;Elixir&lt;/a&gt; servindo uma API com endpoint &lt;a href="https://graphql.org"&gt;GraphQL&lt;/a&gt; usando uma biblioteca chamada &lt;a href="https://github.com/absinthe-graphql/absinthe"&gt;Absinthe&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Mas você já se perguntou como funcionaria isso se a nossa necessidade fosse consumir um &lt;em&gt;Endpoint GraphQL&lt;/em&gt; já existente em outro serviço externo?&lt;/p&gt;

&lt;p&gt;Digamos que você precise ingerir e processar dados para renderizar isso no seu frontend com Elixir (usando LiveView, etc).&lt;/p&gt;

&lt;p&gt;A ideia deste texto é mostrar o quão simples é consumir dados de um endpoint GraphQL usando apenas requests &lt;a href="https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol"&gt;HTTP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vamos la!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/cdNSp4L5vCU7aQrYnV/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/cdNSp4L5vCU7aQrYnV/giphy.gif" alt="lets go gif" width="396" height="516"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é GraphQL?
&lt;/h2&gt;

&lt;p&gt;Grosseiramente falando, é uma linguagem de busca/manipulação de dados e também uma ferramenta para criação de APIs.&lt;/p&gt;

&lt;p&gt;Uma implementação de GraphQL te permite ter os dois lados da moeda:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Criar um serviço backend de &lt;a href="https://en.wikipedia.org/wiki/Create,_read,_update_and_delete"&gt;CRUD&lt;/a&gt; &lt;em&gt;(Create, Read, Update e Delete)&lt;/em&gt; para recursos.&lt;/li&gt;
&lt;li&gt;Consumir dados deste serviço a partir de um frontend com requisições &lt;em&gt;HTTP&lt;/em&gt; ou utilizando uma biblioteca de cliente apropriado para o mesmo.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;E diferente de uma implementação &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer"&gt;REST&lt;/a&gt; padrão, onde você teria um endpoint para cada ação do seu CRUD/serviço. Aqui você irá utilizar um único endpoint, e através do &lt;em&gt;payload&lt;/em&gt; &lt;em&gt;(corpo da requisição)&lt;/em&gt; você indicará o que você precisa, seja busca ou manipulação de dados, e irá elencar quais dados de um determinado modelo.&lt;/p&gt;

&lt;p&gt;Como isso funciona na prática? Usando como exemplo o endpoint disponibilizado pelo &lt;strong&gt;GitHub&lt;/strong&gt;, irei requisitar dados do repositório oficial do &lt;a href="https://github.com/elixir-lang/elixir"&gt;Elixir&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Para ter uma noção mais apurada sobre como funciona o endpoint do github, recomendo este &lt;a href="https://docs.github.com/en/graphql/overview/about-the-graphql-api"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Irei usar a seguinte Query para buscar informações básicas sobre o Repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;query {
  repository(owner: "elixir-lang", name: "elixir") {
    name,
    pushedAt,
    createdAt,
    owner { login },
    latestRelease { id },
    defaultBranchRef { name }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note que eu determino o primeiro termo &lt;em&gt;query&lt;/em&gt; para indicar que estou buscando dados, e logo após, &lt;em&gt;repository&lt;/em&gt; para indicar que os dados que estou buscando são sobre repositórios cujo owner se chama &lt;code&gt;elixir-lang&lt;/code&gt; e o nome seja &lt;code&gt;elixir&lt;/code&gt;. &lt;br&gt;
Como resposta a isso, receberei os mesmos dados &lt;code&gt;name, pushedAt, createdAt, owner.login, latestRelease.id, defaultBranchRef.name&lt;/code&gt; preenchidos.&lt;/p&gt;

&lt;p&gt;Vale ressaltar que no graphql eu determino exatamente o que eu estou buscando, e a resposta será praticamente espelhada nessa requisição.&lt;/p&gt;

&lt;p&gt;Para simular essa query estarei usando o cURL, mas caso você queira testar de outra maneira, existe um cliente próprio para isso chamado &lt;a href="https://github.com/graphql/graphiql"&gt;GraphiQL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;cURL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST "https://api.github.com/graphql" \
-H "Authorization: Bearer SEU_TOKEN_AQUI" \
-d '{"query": "query { repository(owner: \"elixir-lang\", name: \"elixir\") { name, pushedAt, createdAt, owner{login}, latestRelease{id}, defaultBranchRef{name} } }"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Substitua a parte "SEU_TOKEN_AQUI", pelo seu &lt;a href="https://github.com/settings/tokens"&gt;token pessoal&lt;/a&gt; para testes)&lt;/p&gt;

&lt;p&gt;Obtemos a seguinte resposta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "data": {
    "repository": {
      "name": "elixir",
      "pushedAt": "2022-06-01T15:57:31Z",
      "createdAt": "2011-01-09T08:43:57Z",
      "owner": {
        "login":  "elixir-lang"
      },
      "latestRelease": {
        "id":"RE_kwDOABLXGs4DzeaA"
      },
      "defaultBranchRef": {
        "name":"main"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A resposta irá conter exatamente o que pedimos na requisição.&lt;/p&gt;

&lt;p&gt;Resumo: Com apenas um endpoint e um payload flexível, eu consigo dizer para o serviço backend oque eu preciso, e ele me responde somente o necessário.&lt;/p&gt;

&lt;p&gt;Para mais informações sobre GraphQL, eu recomendo este &lt;a href="https://graphql.org/learn/"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como consumir um Endpoint com Elixir?
&lt;/h2&gt;

&lt;p&gt;Como vimos anteriormente, é possível consumir um endpoint apenas fazendo chamadas HTTP para o mesmo. &lt;/p&gt;

&lt;p&gt;Seguindo esta ideia, vou simular a requisição acima com Elixir, utilizando as seguintes bibliotecas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/edgurgel/httpoison"&gt;httpoison:1.8&lt;/a&gt; (Cliente HTTP, para requisições)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/michalmuskala/jason"&gt;jason:1.3&lt;/a&gt; (Conversor de JSON)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Github&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;GraphQL&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Módulo responsável por se comunicar com o endpoint GraphQL do Github.
  """&lt;/span&gt;

  &lt;span class="nv"&gt;@endpoint&lt;/span&gt; &lt;span class="sx"&gt;~s(https://api.github.com/graphql)&lt;/span&gt;
  &lt;span class="nv"&gt;@token&lt;/span&gt; &lt;span class="sx"&gt;~s(SEU_TOKEN_AQUI)&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Busca informações básicas de um determinado repositório.

  ## Exemplos

      iex&amp;gt; repo_info("elixir-lang", "elixir")
      %{
        "data" =&amp;gt; %{
          "repository" =&amp;gt; %{
            "createdAt" =&amp;gt; "2011-01-09T08:43:57Z",
            "defaultBranchRef" =&amp;gt; %{"name" =&amp;gt; "main"},
            "latestRelease" =&amp;gt; %{"id" =&amp;gt; "RE_kwDOABLXGs4DzeaA"},
            "name" =&amp;gt; "elixir",
            "owner" =&amp;gt; %{"login" =&amp;gt; "elixir-lang"},
            "pushedAt" =&amp;gt; "2022-06-01T15:57:31Z"
          }
        }
      }
  """&lt;/span&gt;
  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;repo_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;repo_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
      &lt;span class="ss"&gt;variables:&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;owner:&lt;/span&gt; &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="ss"&gt;query:&lt;/span&gt; &lt;span class="sx"&gt;~S""&lt;/span&gt;&lt;span class="s2"&gt;"
      query GetRepoInfo($owner: String!, $name: String!) {
        repository(owner: $owner, name: $name){
          name,
          pushedAt,
          createdAt,
          owner {
            login
          },
          latestRelease {
            id
          },
          defaultBranchRef {
            name
          }
        }
      }
      """&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Jason&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;encode!&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;status_code:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;@endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="no"&gt;Jason&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;decode!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Bearer &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;@token&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Perceba como no payload eu criei um map com dois valores (&lt;code&gt;variables&lt;/code&gt; e &lt;code&gt;query&lt;/code&gt;). Neste caso, por motivos de organização, optei por isolar as variáveis &lt;code&gt;name&lt;/code&gt; e &lt;code&gt;owner&lt;/code&gt; do resto da query, para não precisar fazer interpolação na String. (Isto é algo próprio do GraphQL, onde o campo &lt;code&gt;variables&lt;/code&gt; é opcional).&lt;/p&gt;

&lt;p&gt;A execução seria:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;repo_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"elixir-lang"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"elixir"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;%{&lt;/span&gt;
  &lt;span class="s2"&gt;"data"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
    &lt;span class="s2"&gt;"repository"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;
      &lt;span class="s2"&gt;"createdAt"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"2011-01-09T08:43:57Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"defaultBranchRef"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="s2"&gt;"latestRelease"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;"id"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"RE_kwDOABLXGs4DzeaA"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"elixir"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"owner"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="s2"&gt;"login"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"elixir-lang"&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="s2"&gt;"pushedAt"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"2022-06-01T15:57:31Z"&lt;/span&gt;
    &lt;span class="p"&gt;}&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;Por padrão um endpoint GraphQL recebe as seguintes informações via payload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "query": "query a ser executada"
  "variables": {"variavel": "valor"}
  "operationName": "NomeDaOperação"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E a resposta é sempre a mesma, contendo uma chave &lt;code&gt;data&lt;/code&gt; com os dados requisitados, ou uma chave &lt;code&gt;errors&lt;/code&gt; contendo os possíveis problemas na construção da sua &lt;em&gt;query&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Consumir um endpoint GraphQL pode ser tão simples quanto consumir qualquer outro serviço utilizando o seu cliente HTTP de preferência.&lt;/p&gt;

&lt;p&gt;E ainda é possível criar todo um padrão para consumo GraphQL com Elixir, usando behaviours e contextos para envelopar o código, pattern matching para tratamento de erros nas respostas, organização das variáveis de ambiente/aplicação, e por ai vai...&lt;/p&gt;

&lt;p&gt;Isso te interessou? foi útil? Deixa nos comentários para eu ficar por dentro!&lt;/p&gt;

&lt;p&gt;Abraços!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💚💜 Elixir é amor, Erlang é vida! 💜💚&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
      <category>graphql</category>
      <category>programming</category>
    </item>
    <item>
      <title>5 curious facts about Elixir</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Thu, 14 Oct 2021 12:27:58 +0000</pubDate>
      <link>https://dev.to/x-team/5-curious-facts-about-elixir-4bpm</link>
      <guid>https://dev.to/x-team/5-curious-facts-about-elixir-4bpm</guid>
      <description>&lt;p&gt;Elixir is a functional programming language that runs on the BEAM virtual machine, itself used to implement Erlang. Elixir extends Erlang and provides interoperability between both languages. Its syntax is easy to understand and its tools help to standardize code so it's easier to move from one project to the next.&lt;/p&gt;

&lt;p&gt;My name is Willian Frantz and I've been an Elixir Alchemist since 2017. I actively contribute to the Brazilian programming community by writing blog posts, speaking at events, and &lt;a href="https://x-team.com/blog/contribute-to-open-source-projects/"&gt;contributing to open-source libraries&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Despite being used by companies such as Pinterest, Slack, and Discord, Elixir remains a niche programming language. That's why I want to give you 5 curious facts about Elixir. Hopefully, they will encourage you to give the Elixir programming language a look.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Functional, but Dynamic too
&lt;/h2&gt;

&lt;p&gt;Elixir is a functional language, but it also allows you to rebind a variable. This is only possible because of the pattern matching operator &lt;code&gt;=&lt;/code&gt;. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Something"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Else"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s2"&gt;"Else"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. There's No Assign Operator
&lt;/h2&gt;

&lt;p&gt;That's right. Elixir has no assign operator. Instead, it uses &lt;code&gt;=&lt;/code&gt; as its main pattern matching function. Every time you use &lt;code&gt;=&lt;/code&gt;, you're pattern matching. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Something"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Else"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s2"&gt;"SomethingElse"&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Something"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&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="s2"&gt;"Something"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"Else"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="s2"&gt;"Else"&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="n"&gt;name&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="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"Willian"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&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="s2"&gt;"Willian"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pattern matching is an amazing functionality in Elixir. You can use it to write complex business logic and decision-making capabilities into your code. For example, let's use it to create function polymorphism:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Empty string provided"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello&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;do&lt;/span&gt;
  &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello World, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, if we call the &lt;code&gt;hello/1&lt;/code&gt; function (with &lt;code&gt;/1&lt;/code&gt; indicating the number of arguments it expects) and give it an empty string as its main argument, it will raise an exception with the message "Empty string provided". Otherwise, it will print "Hello World, {name}".&lt;/p&gt;

&lt;p&gt;Another way to create function polymorphism is by using bodyguards. Elixir has some default functions called guards that you can use to control structures (like &lt;code&gt;case/do&lt;/code&gt;) or apply to a function scope. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello&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="ow"&gt;when&lt;/span&gt; &lt;span class="n"&gt;is_binary&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;do&lt;/span&gt;
  &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Hello World, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;!"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="s2"&gt;"Expected a String, received: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We added a guard called &lt;code&gt;is_binary/1&lt;/code&gt; to our function, which checks if the name is actually a string. If it fails to validate the string, it will raise an exception that says "Expected a String, received: {var}".&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Elixir Goes Meta
&lt;/h2&gt;

&lt;p&gt;Here's a mind-blowing fact: 92% of Elixir's source code is written in Elixir. That's why dealing with constructs is so flexible in Elixir. The programming language is meta: it allows you to write code that writes code, so you can, for example, extend your Elixir program with &lt;a href="https://elixir-lang.org/getting-started/meta/macros.html"&gt;macros&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's use an Elixir pipe operator to solve chainable calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# without pipe operator&lt;/span&gt;
&lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;frequencies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Repeated Chars on String"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;trim:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# result:&lt;/span&gt;
&lt;span class="p"&gt;%{&lt;/span&gt;
  &lt;span class="s2"&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="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"C"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"R"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"S"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"a"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"d"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"e"&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;span class="s2"&gt;"g"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"h"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"i"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"n"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"o"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"p"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"r"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"s"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"t"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Same code with pipe operator&lt;/span&gt;
&lt;span class="s2"&gt;"Repeated Chars on String"&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;trim:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;frequencies&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The pipe operator breaks chainable calls into a sequential, readable list of code. You could read this as:&lt;/p&gt;

&lt;p&gt;I have a string "Repeated Chars on String"&lt;br&gt;
I want to split that string by character and trim it&lt;br&gt;
I want the frequencies of the generated list&lt;br&gt;
We can actually pipe into control structures:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# without pipe operator&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"1..10 sum = 55"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# with pipe operator&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Kernel&lt;/span&gt;&lt;span class="o"&gt;.==&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"1..10 sum = 55"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While I wouldn't recommend to use a pipe operator in this case, it's a good demonstration of &lt;a href="https://liftm.io/posts/cursed-elixir.html"&gt;how flexible Elixir can be&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. How Elixir Deals with Strings
&lt;/h2&gt;

&lt;p&gt;Imagine we have both a string &lt;code&gt;"Hey I am a String"&lt;/code&gt; and a charlist &lt;code&gt;'Hey I am a Charlist'&lt;/code&gt;. We can cast either whenever we need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"to Charlist"&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;to_charlist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="s1"&gt;'to Charlist'&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'to String'&lt;/span&gt; &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;to_string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="s2"&gt;"to String"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also interpolate or concatenate &lt;a href="https://elixirschool.com/en/lessons/basics/strings/"&gt;strings&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Interpolation&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"some"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"thing"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"String: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="si"&gt;}#{&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="s2"&gt;"String: something"&lt;/span&gt;

&lt;span class="c1"&gt;# Concatenation&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"String: "&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"something"&lt;/span&gt;
&lt;span class="s2"&gt;"String: something"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since Elixir deals with strings as sequences of bytes, we can also use binary operations to create strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"String: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"some"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"thing"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt;
&lt;span class="s2"&gt;"String: something"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or combine binaries with pattern matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="s2"&gt;"String: "&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;binary&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"String: something"&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;rest&lt;/span&gt;
&lt;span class="s2"&gt;"something"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. There Are No Loops
&lt;/h2&gt;

&lt;p&gt;Elixir doesn't have loops. Instead, it uses list comprehensions, recursion, and higher-order functions to iterate over a collection of items. Let's go over each in order.&lt;/p&gt;

&lt;p&gt;Here's an example of how you can use &lt;strong&gt;list comprehensions&lt;/strong&gt; to generate a list of squared numbers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Elixir handles &lt;strong&gt;recursion&lt;/strong&gt; pretty well too. Because recursive calls are optimized, they use almost the same amount of space as an imperative loop. Take this programmed factorial, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Fact&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Fact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can recursively calculate the factorial of a number without having any call-stack issues. This works even with a much bigger number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Fact&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="mi"&gt;30414093201713378043612608166064768844377641568960512000000000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Last but not least, we have &lt;strong&gt;higher-order functions&lt;/strong&gt;, a set of functions that take another function as input (e.g. map, reduce, filter, etc). Let's say we want to find all the even numbers in a list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_even&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Enum.filter/2&lt;/code&gt; to filter our collection.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1..20&lt;/code&gt; to generate a list of numbers from 1 to 20.&lt;/li&gt;
&lt;li&gt;A capture operator &lt;code&gt;&amp;amp;&lt;/code&gt; into &lt;code&gt;Integer.is_even/1&lt;/code&gt; as the function that the filter uses.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope I've captured your interest with these 5 curious facts about Elixir. In my opinion, Elixir has a few unique features that make it stand out from other languages. If you'd like to know more, check out the following Elixir resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learnxinyminutes.com/docs/elixir/"&gt;Learn X in Y minutes where X = Elixir&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elixir-lang.org/getting-started/introduction.html"&gt;Elixir introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://elixirschool.com/en/"&gt;Elixir School&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>elixir</category>
      <category>programming</category>
      <category>erlang</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Mas e os loops em Elixir?</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Mon, 23 Aug 2021 21:54:27 +0000</pubDate>
      <link>https://dev.to/wlsf/mas-e-os-loops-em-elixir-3d0k</link>
      <guid>https://dev.to/wlsf/mas-e-os-loops-em-elixir-3d0k</guid>
      <description>&lt;p&gt;Se você está vindo de uma linguagem de paradigma imperativo, orientada a objetos, muito provavelmente você vai esbarrar nessa pergunta do título.&lt;/p&gt;

&lt;p&gt;Pois bem, &lt;strong&gt;Elixir&lt;/strong&gt; não possui esse termo em seu vocabulário. Apesar de ser possível iterar sobre uma lista de elementos utilizando o &lt;code&gt;for&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso não significa que o &lt;strong&gt;Elixir&lt;/strong&gt; possui &lt;em&gt;loops&lt;/em&gt;, esse &lt;code&gt;for&lt;/code&gt; nada mais é do que uma chamada nativa ao &lt;em&gt;List Comprehensions&lt;/em&gt; do &lt;strong&gt;&lt;a href="https://erlang.org/doc/programming_examples/list_comprehensions.html" rel="noopener noreferrer"&gt;Erlang&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Curioso né? Como fazer para lidar com uma coleção de itens então? &lt;/p&gt;

&lt;p&gt;Há 2 maneiras de trabalhar com este tipo de problema, sendo elas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;High Order Functions (map, reduce, filter, find, etc...)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Recursividade&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  High Order Functions
&lt;/h2&gt;

&lt;p&gt;É muito comum se deparar com uma situação onde você tem uma lista de elementos e precisa manipular os dados dela.&lt;/p&gt;

&lt;p&gt;E para isso podemos utilizar funções como &lt;em&gt;map&lt;/em&gt;, &lt;em&gt;reduce&lt;/em&gt;, &lt;em&gt;filter&lt;/em&gt;, etc.&lt;/p&gt;

&lt;p&gt;Digamos que você precise multiplicar todos os elementos da sua lista por 2, isso deveria ser um problema trivial, certo?&lt;/p&gt;

&lt;p&gt;A implementação desse problema em &lt;em&gt;js&lt;/em&gt; utilizando uma estrutura de repetição &lt;em&gt;(loop)&lt;/em&gt; seria mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&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;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em Elixir é possível resolver isso com &lt;code&gt;map/2&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;fn&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="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="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Enum&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;)&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Comparando os exemplos acima, diferente da estrutura de repetição, com o &lt;code&gt;map/2&lt;/code&gt; não é necessário definir nada além da fórmula para mapear os dados da minha lista, onde a fórmula é &lt;code&gt;x -&amp;gt; x * 2&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;O próprio &lt;code&gt;map/2&lt;/code&gt; faz o resto do trabalho aplicando a fórmula pra cada elemento da nossa lista, e gerando uma nova lista ao final da execução.&lt;/p&gt;

&lt;p&gt;Segue o mesmo conceito para as demais funções, como:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;map/2&lt;/code&gt; manipula os elementos e gera uma nova lista&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;filter/2&lt;/code&gt; filtra os elementos e gera uma nova lista&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;reduce/2&lt;/code&gt; manipula os elementos acumulando seus resultados anteriores&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existem diversos tipos de &lt;em&gt;&lt;a href="https://elixirschool.com/en/lessons/basics/enum/" rel="noopener noreferrer"&gt;High Order Functions&lt;/a&gt;&lt;/em&gt; disponíveis no Elixir, feitas para facilitar a sua vida na hora de resolver problemas sejam eles triviais ou não.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursividade
&lt;/h2&gt;

&lt;p&gt;Mesmo que você seja uma pessoa de linguagens imperativas, o termo recursividade ainda é algo familiar!&lt;/p&gt;

&lt;p&gt;E o que é recursividade? É uma forma de iterar sob listas (ou não), onde a função chama ela própria até atingir uma condição de parada.&lt;/p&gt;

&lt;p&gt;Um exemplo muito conhecido sobre recursividade, é o cálculo fatorial de um número, onde &lt;code&gt;4! = 4 x 3 x 2 x 1 = 24&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Destrinchando esse cálculo, teríamos algo semelhante a:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4! = 3! * 4
   = 2! * 3
   = 1! * 2
   = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Considerando o exemplo acima, a condição de parada para essa execução é o valor 1. Quando a função fatorial receber como argumento o valor 1, ela deverá retornar 1 e as outras execuções devem se basear neste valor, exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;4! = (6) * 4 = 24
   = (2) * 3
   = (1) * 2
   = 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Em parênteses&lt;/strong&gt;: resultado da chamada fatorial anterior.&lt;/p&gt;

&lt;p&gt;A implementação em &lt;strong&gt;JS&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;val&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;Essa mesma função em &lt;strong&gt;Elixir&lt;/strong&gt; fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nota-se que na chamada recursiva, a função &lt;code&gt;fact/1&lt;/code&gt; chama a si mesma passando o &lt;code&gt;argumento - 1&lt;/code&gt;, e quando essa função é chamada com o valor 1, ela retorna somente o valor 1 e encerra sua execução em cadeia.&lt;/p&gt;

&lt;p&gt;Vamos analisar mais de perto essa chamada do &lt;code&gt;fact/1&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Considere que estamos chamando fatorial com o argumento 4 (4!)&lt;/span&gt;

&lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="c1"&gt;# Esse será o retorno&lt;/span&gt;
&lt;span class="c1"&gt;# Ele estará chamando fact(3) e multiplicando por 4.&lt;/span&gt;
&lt;span class="c1"&gt;# E assim sucessivamente...&lt;/span&gt;

&lt;span class="n"&gt;fact&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;&lt;/span&gt; &lt;span class="n"&gt;fact&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;1&lt;/span&gt;&lt;span class="p"&gt;)&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;fact&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&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;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# Essa abordagem gera uma cadeia de chamadas que precisam ser resolvidas.&lt;/span&gt;
&lt;span class="c1"&gt;# Quando a chamada em cadeia chega na nossa condição de parada (1)&lt;/span&gt;
&lt;span class="c1"&gt;# O processador começa a desencadear essas chamadas que empilhamos.&lt;/span&gt;
&lt;span class="c1"&gt;# Seguindo assim:&lt;/span&gt;

&lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;fact&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="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;fact&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;&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;
&lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Implementar uma função &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Factorial" rel="noopener noreferrer"&gt;fatorial&lt;/a&gt;&lt;/em&gt; utilizando recursividade é bem simples, né? Mas se formos considerar a explicação que acabamos de ver, isso pode se tornar um problema?&lt;/p&gt;

&lt;p&gt;Imagine que temos uma função que precisará iterar milhares de vezes para resolver um determinado problema, precisaremos empilhar várias chamadas não-resolvidas na nossa pilha de chamadas, e isso poderá estourar o limite da pilha.&lt;/p&gt;

&lt;p&gt;Para esse problema em específico, há uma solução chamada &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Tail_call" rel="noopener noreferrer"&gt;Tail Call Optimization&lt;/a&gt;&lt;/strong&gt; (ou TCO). Com  &lt;strong&gt;TCO&lt;/strong&gt; é possível eliminar essas chamadas não-resolvidas que uma função recursiva costuma criar.&lt;/p&gt;

&lt;p&gt;O pulo do gato quando aplicamos &lt;em&gt;Tail Call Optimization&lt;/em&gt; em uma função recursiva é que essa função saiba o valor processado em todas as suas chamadas, sendo assim, ela não depende do desencadeamento para encontrar o valor final de sua execução.&lt;/p&gt;

&lt;p&gt;E como podemos fazer isso? Segue o exemplo de uma chamada sem TCO:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# nossa condição de parada&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="c1"&gt;# função fatorial recursiva&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;com TCO:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# nossa condição de parada&lt;/span&gt;
&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;

&lt;span class="c1"&gt;# função fatorial recursiva&lt;/span&gt;
&lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A grande diferença, é que na função fatorial com TCO, ela sabe exatamente o valor da sua execução.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fact(4) -&amp;gt; fact(4 - 1, 4)
fact(3, 4) -&amp;gt; fact(3 - 1, (4 * 3)) -&amp;gt; fact(2, 12)
fact(2, 12) -&amp;gt; fact(2 - 1, (12 * 2)) -&amp;gt; fact(1, 24)
fact(1, 24) -&amp;gt; 24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Portanto, quando a nossa função chega na sua condição de parada, não é necessário desencadear todas as chamadas anteriores e seus respectivos cálculos. Ela só precisa retornar seu valor final (24) para a função que originou a sua chamada &lt;code&gt;fact(4)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fato curioso:&lt;/strong&gt; Por padrão, &lt;strong&gt;Elixir/Erlang&lt;/strong&gt; implementam &lt;em&gt;Tail Call Optimization&lt;/em&gt;, por isso a utilização de recursividade é algo muito comum e encorajada! Inclusive as &lt;em&gt;High Order Functions&lt;/em&gt; são implementadas através de recursividade, no final das contas.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Elixir é amor, Erlang é vida.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FxUPOqo6E1XvWXwlCyQ%2Fgiphy.gif%3Fcid%3Decf05e47ku92k1x33lofok9qn7hwhy8jtxr7f8b8a3e7evnz%26rid%3Dgiphy.gif%26ct%3Dg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fmedia.giphy.com%2Fmedia%2FxUPOqo6E1XvWXwlCyQ%2Fgiphy.gif%3Fcid%3Decf05e47ku92k1x33lofok9qn7hwhy8jtxr7f8b8a3e7evnz%26rid%3Dgiphy.gif%26ct%3Dg" alt="thats all"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
    </item>
    <item>
      <title>Behaviours em Elixir</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Tue, 01 Jun 2021 01:42:39 +0000</pubDate>
      <link>https://dev.to/wlsf/behaviours-em-elixir-25i3</link>
      <guid>https://dev.to/wlsf/behaviours-em-elixir-25i3</guid>
      <description>&lt;p&gt;Assim como &lt;code&gt;Protocols&lt;/code&gt;, &lt;code&gt;Behaviours&lt;/code&gt; também são uma forma de manter um padrão de &lt;em&gt;interface/herança&lt;/em&gt; e até mesmo &lt;em&gt;polimorfismo&lt;/em&gt; no &lt;strong&gt;Elixir&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Vale lembrar que Elixir é uma linguagem de programação funcional, portanto, não é o nosso forte o conceito de objeto, classe e métodos. No final, sempre estaremos falando sobre &lt;strong&gt;módulos&lt;/strong&gt; e &lt;strong&gt;funções&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;Então de que me serve possuir uma &lt;em&gt;abstração&lt;/em&gt; para criar interfaces em uma tecnologia como esta?&lt;/p&gt;

&lt;h1&gt;
  
  
  Cenário
&lt;/h1&gt;

&lt;p&gt;Imaginem que vamos desenvolver uma aplicação onde a pessoa insere seus dados para consultar todos seus cartões de crédito, verificar se as faturas estão em dia, e inclusive gerar possíveis estratégias financeiras, etc...&lt;/p&gt;

&lt;p&gt;Para isso precisamos criar uma &lt;em&gt;API REST&lt;/em&gt; que irá consultar de diversas fontes de cartões para validar os dados e processar as respostas finais.&lt;/p&gt;

&lt;p&gt;Você consegue identificar um padrão nisso? Se precisamos consultar mais de uma API externa para reunir os dados para a resposta final, isso significa que nosso código terá muitos módulos que serão correspondentes a provedores diferentes (ex: Itaú, Nubank, etc...)&lt;/p&gt;

&lt;h1&gt;
  
  
  Problema
&lt;/h1&gt;

&lt;p&gt;Como iremos mapear todos esses módulos de provedores que vamos criar dentro do nosso sistema então? Como garantir que eles precisam ter uma execução semelhante, retornando os dados processados da mesma forma? &lt;/p&gt;

&lt;p&gt;Tendo em vista que as APIs externas podem ser distintas, possuir dados diferentes e respostas diferentes, isso pode se tornar um problema e pode nos levar a criar códigos aleatórios para solucionar cada tipo de API de uma forma desnecessária.&lt;/p&gt;

&lt;h1&gt;
  
  
  Behaviours
&lt;/h1&gt;

&lt;p&gt;Com &lt;strong&gt;behaviours&lt;/strong&gt; conseguimos criar um padrão comportamental, definindo uma assinatura pré-exigida pelo módulo, garantindo que todos os módulos subsequentes que irão se especializar naquela API precisarão implementar aqueles requisitos.&lt;/p&gt;

&lt;p&gt;Em outras palavras, considere sendo essa a nossa interface de acesso à APIs externas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Bank&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;API&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Este módulo é responsável por definir uma interface 
  padrão para os demais módulos de acesso ao 
  Banco implementarem.
  """&lt;/span&gt;

  &lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nv"&gt;@type&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map&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="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;

  &lt;span class="nv"&gt;@doc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Este método irá acessar a base externa e
  retornar os dados bancários da pessoa usuária
  """&lt;/span&gt;
  &lt;span class="nv"&gt;@callback&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ignorando os &lt;em&gt;moduledocs&lt;/em&gt; e &lt;em&gt;typespecs&lt;/em&gt; do nosso módulo, nos resta essa &lt;code&gt;@callback&lt;/code&gt;, que é exatamente o comando utilizado para definir as funções que deverão ser implementadas pelo módulo que pretende se especializar nessa API.&lt;/p&gt;

&lt;p&gt;Perceba o quão genérico nossa interface ficou, ela só da a entender que é uma API de Banco, com uma função de chamada. Em momento algum foi especificado qual o tipo de banco, ou como essa chamada será feita (via: API, gRPC, SOAP, etc...), isso será total responsabilidade de quem for implementar essa interface.&lt;/p&gt;

&lt;p&gt;Agora com nosso &lt;strong&gt;behaviour&lt;/strong&gt; bem definido, podemos seguir para a implementação do primeiro Client que iremos utilizar em nossa aplicação para consultar os dados:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Bank&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Nubank&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Módulo que implementa a requisição para a API do Nubank.
  """&lt;/span&gt;

  &lt;span class="nv"&gt;@behaviour&lt;/span&gt; &lt;span class="no"&gt;Bank&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;API&lt;/span&gt;

  &lt;span class="nv"&gt;@impl&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(%{&lt;/span&gt;&lt;span class="ss"&gt;user_id:&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nubank_url&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;HTTPoison&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;status_code:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;body:&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;nubank_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
      &lt;span class="no"&gt;Application&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:my_app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:nubank&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="ss"&gt;:url&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"/user/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;(a requisição acima é meramente ilustrativa 😅)&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;O comando &lt;code&gt;@behaviour Bank.API&lt;/code&gt; descreve que nosso módulo &lt;code&gt;Nubank&lt;/code&gt; irá se especializar no &lt;code&gt;Bank.API&lt;/code&gt;, logo, ele deverá implementar a seguinte função: &lt;code&gt;call/1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Com isto, temos nosso primeiro provedor implementado, yaay 🚀!&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Gosto de dizer que estamos definindo padrões comportamentais, com isso, quando vemos que um módulo específico implementa um &lt;strong&gt;Behaviour&lt;/strong&gt;, já dá para ter uma ideia de quais funções ele roda, qual o seu propósito, como ele deve ser implementado em termos de &lt;em&gt;input&lt;/em&gt; e &lt;em&gt;output&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Esse tipo de padronização ajuda a escalar nosso código, diminuir a curva de aprendizagem para novas pessoas desenvolvedoras e inclusive é uma ótima ferramenta para auto-documentar nosso código, deixa tudo mais descritivo e explícito!&lt;/p&gt;

&lt;p&gt;E você, o que acha de &lt;strong&gt;behaviours&lt;/strong&gt;? Gostaria de complementar, adicionar ou remover alguma informações deste tópico? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l4pTjOu0NsrLApt0Q/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l4pTjOu0NsrLApt0Q/giphy.gif" alt="that's all"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A salada de frutas dos modelos de dados</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Tue, 11 May 2021 21:46:46 +0000</pubDate>
      <link>https://dev.to/wlsf/salada-de-frutas-dos-modelos-de-dados-2in7</link>
      <guid>https://dev.to/wlsf/salada-de-frutas-dos-modelos-de-dados-2in7</guid>
      <description>&lt;p&gt;Você sabia que existem diversos modelos de dados além do padrão relacional (ex PostgreSQL) e o baseado em documentos (ex MongoDB)?&lt;/p&gt;

&lt;p&gt;Acredito que esse detalhe passe despercebido por muitas pessoas desenvolvedoras, não que isso seja um problema. Na maioria dos casos é possível atender a sua necessidade com Postgres, e as vezes utilizaremos modelos diferentes de forma implícita, como em uma ferramenta de Cache.&lt;/p&gt;

&lt;p&gt;Portanto, gostaria de enfatizar que estou escrevendo este texto apenas para saciar a curiosidade de vocês, e meu próprio interesse por modelos de dados. 😅 &lt;/p&gt;

&lt;p&gt;Vamos começar dissecando alguns dos diferentes modelos existentes? Na nossa lista temos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;armazenamento por chave-valor&lt;/li&gt;
&lt;li&gt;armazenamento em triplas&lt;/li&gt;
&lt;li&gt;armazenamento em documentos&lt;/li&gt;
&lt;li&gt;armazenamento relacional&lt;/li&gt;
&lt;li&gt;armazenamento em grafos&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Modelo Chave-Valor
&lt;/h2&gt;

&lt;p&gt;Um dos modelos mais simples de armazenamento de dados, ele utiliza apenas &lt;code&gt;chave=valor&lt;/code&gt;, é um dado altamente desacoplado e sem conexões, não possui relacionamentos. &lt;/p&gt;

&lt;p&gt;Se fôssemos representar esse modelo com um Map em Elixir seria algo mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;%{&lt;/span&gt;
  &lt;span class="ss"&gt;key:&lt;/span&gt; &lt;span class="s2"&gt;"value"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;%{&lt;/span&gt;
  &lt;span class="ss"&gt;name:&lt;/span&gt; &lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;age:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O que representaria uma estrutura map in-memory, semelhante a um JSON.&lt;/p&gt;

&lt;p&gt;Este modelo é amplamente utilizado em ferramentas de &lt;em&gt;Cache&lt;/em&gt; hoje em dia, como por exemplo: &lt;strong&gt;Redis&lt;/strong&gt; e &lt;strong&gt;Memcached&lt;/strong&gt;. Digamos que você possui um dado que é usado com frequência pela sua aplicação, e esse dado não costuma sofrer alteração. Nesses cenários específicos nós aplicamos um &lt;em&gt;cache&lt;/em&gt; para garantir que esse dado fique armazenado de forma simples e rápida de buscar, assim evitamos chamadas desnecessárias ao banco de dados &lt;em&gt;(round trips)&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Modelo de triplas
&lt;/h1&gt;

&lt;p&gt;Também é um modelo extremamente simples. Possui uma forma homogênea de armazenar o dado, onde todas entradas são estruturas da seguinte forma: &lt;code&gt;(sujeito, predicado, objeto)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Podemos ter uma entrada que represente a nossa idade, nosso nome, etc. &lt;br&gt;
Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(john_doe, idade, 30)
(john_doe, nome, "John Doe")
(john_doe, gosta, "macarronada")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No final das contas, a ideia por trás desse esquema é que possamos representar uma sentença, como por exemplo &lt;em&gt;"John Doe tem 30"&lt;/em&gt; ou &lt;em&gt;"John Doe gosta de maçãs"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;O próprio triple store ou também conhecido como RDF, utiliza queries semânticas através do &lt;strong&gt;SPARQL&lt;/strong&gt; &lt;em&gt;(Protocol and RDF Query Language)&lt;/em&gt; para conseguir manipular ou buscar suas triplas.&lt;/p&gt;

&lt;p&gt;Normalmente uma Query de busca se baseia no predicado, ex com &lt;strong&gt;SPARQL&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT ?person :nome "John Doe"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aqui buscamos a pessoa cujo nome é John Doe. É possível ter relacionamentos neste modelo, porém, sempre seguindo o padrão proposto de sujeito-predicado-objeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Curiosidade:&lt;/strong&gt; Este esquema é muito utilizado em uma linguagem de programação declarativa, que também serve como linguagem de &lt;em&gt;Query&lt;/em&gt; chamada &lt;strong&gt;Datalog&lt;/strong&gt;, ele cria entradas com um padrão bem semelhante, seguindo o formato: &lt;code&gt;predicado(sujeito, objeto)&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;idade(john_doe, 30)
nome(john_doe, "John Doe")
gosta(john_doe, "maçãs")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E inclusive, o &lt;strong&gt;Datomic&lt;/strong&gt; é uma implementação do Datalog. O Datomic, para quem não conhece, é um banco de dados distribuído, ACID, que é muito utilizado com o Clojure na JVM. (Inclusive é o banco que o Nubank usa!)&lt;/p&gt;

&lt;p&gt;O modelo de triplas ou RDF, também é mencionado em artigos sobre Semantic Web, que prega a transformação da Internet num lugar onde a camada semântica seja mais acessível.&lt;/p&gt;

&lt;h2&gt;
  
  
  Modelo de Documentos
&lt;/h2&gt;

&lt;p&gt;Aqui já percebemos uma forma mais rebuscada de armazenar o nosso dado; normalmente os bancos baseados em documentos trabalham com collections e documents (que são objetos JSON-like).&lt;/p&gt;

&lt;p&gt;Esse padrão de armazenamento é muito conhecido por se assemelhar a um objeto JSON.&lt;br&gt;
Exemplo de um objeto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "notebook",
  "qty": 50,
  "rating": [ { "score": 8 }, { "score": 9 } ],
  "size": { "height": 11, "width": 8.5, "unit": "in" },
  "status": "A",
  "tags": [ "college-ruled", "perforated"]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(ex retirado da documentação do próprio MongoDB)&lt;/p&gt;

&lt;p&gt;A partir daqui já começamos a enxergar dados que se conectam, que se relacionam diretamente. Como podemos ver no exemplo acima: temos um notebook com 50 unidades em estoque, onde as avaliações impostas a ele foram nota 8 e nota 9, fora demais detalhes sobre tamanho, status, tags, etc.&lt;/p&gt;

&lt;p&gt;É interessante frisar aqui, que apesar desses dados se relacionarem, estamos falando de um documento (muito semelhante a uma estrutura JSON), portanto, este documento é salvo exatamente desta forma, com todas as relações e conexões no mesmo objeto, é como se estivéssemos compactando um JSON numa String. Pelo dado ser salvo todo junto, é muito mais simples buscar esse dado do banco, tendo em vista que ele só precisa carregar o que foi salvo no documento. Porém por outro lado, por mais que você só deseje acessar uma pequena parte do documento (ex dados como &lt;code&gt;name&lt;/code&gt; e &lt;code&gt;qty&lt;/code&gt;), todo o documento precisa ser carregado da mesma forma.&lt;/p&gt;

&lt;p&gt;Um banco muito utilizado atualmente que implementa este formato de modelo baseado em documentos é o MongoDB!&lt;/p&gt;

&lt;h2&gt;
  
  
  Modelo Relacional
&lt;/h2&gt;

&lt;p&gt;Se no modelo anterior falamos um pouco sobre relacionamentos entre dados, agora vamos entrar com força nesse assunto. O modelo relacional é conhecido por nos permitir mapear o mundo usando esquemas e relações.&lt;/p&gt;

&lt;p&gt;Nele não falamos mais apenas sobre chave=valor, muito menos sobre documentos. Nele utilizamos os termos banco, esquema, tabela, relacionamentos, e por aí vai...&lt;/p&gt;

&lt;p&gt;Digamos que estamos mapeando estruturas para o site do nosso restaurante, teríamos algo semelhante a:&lt;/p&gt;

&lt;p&gt;Tabela &lt;strong&gt;Menu&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;hour&lt;/th&gt;
&lt;th&gt;status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Almoço&lt;/td&gt;
&lt;td&gt;11h~13h&lt;/td&gt;
&lt;td&gt;on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Janta&lt;/td&gt;
&lt;td&gt;18h~22h&lt;/td&gt;
&lt;td&gt;on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Sobremesa&lt;/td&gt;
&lt;td&gt;all-day&lt;/td&gt;
&lt;td&gt;on&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Tabela &lt;strong&gt;Prato&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;id&lt;/th&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;price&lt;/th&gt;
&lt;th&gt;menu_id&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Strognoff&lt;/td&gt;
&lt;td&gt;R$49&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Sopa&lt;/td&gt;
&lt;td&gt;R$35&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Sorvete&lt;/td&gt;
&lt;td&gt;R$12&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Mousse&lt;/td&gt;
&lt;td&gt;R$20&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Olha que interessante, acabamos de ilustrar 2 tabelas que serão utilizadas para representar os dados do nosso restaurante, nele teremos menus que serão divididos entre [Almoço: 1, Janta: 2, Sobremesa: 3], e definimos também 3 pratos diferentes para cada um dos menus, sendo eles [Strognoff: Almoço, Sopa: Janta, Sorvete: Sobremesa]&lt;/p&gt;

&lt;p&gt;Apesar desses dados estarem separados por tabelas, eles estão relacionados pelo menu_id, o que chamamos de foreign key em bancos relacionais. Com isso, conseguimos afirmar que um prato pertence a um Menu, e um Menu pode possuir diversos pratos diferentes! Isso simboliza um relacionamento 1..n de menus para pratos.&lt;/p&gt;

&lt;p&gt;E conseguimos validar/testar esses relacionamentos através de um join feito por uma linguagem de Query chamada SQL (Structured Query Language).&lt;/p&gt;

&lt;p&gt;Ex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM menus m
INNER JOIN pratos p ON p.menu_id=m.id
WHERE m.name = 'Almoço'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traduzindo o resultado disso para um objeto JSON, teremos algo mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  'name': 'Almoço',
  'hour': '11h~13h',
  'status': 'on',
  'pratos': [
    {
      'name': 'Strognoff',
      'price': 'R$49'
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A coisa tá ficando mais abstrata e complexa comparada ao primeiro modelo discutido aqui, não é mesmo? Mas imaginem a infinidade de coisas que podemos modelar utilizando um banco relacional...&lt;/p&gt;

&lt;p&gt;Ele nos dá um universo de opções, como por exemplo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mapear os nossos dados utilizando diferentes tipos (entre valores inteiros, string, até estruturas JSON)&lt;/li&gt;
&lt;li&gt;buscar esses dados de forma fragmentada (somente alguns dados de uma tabela)&lt;/li&gt;
&lt;li&gt;buscar dados de 2 ou mais tabelas que se relacionam, através de joins&lt;/li&gt;
&lt;li&gt;criar indexes para os dados que mais se relacionam, isso faz com que o banco consiga encontrar aqueles dados de forma mais fácil, isso pode melhorar a performance de nossas buscas (dependendo do tamanho do seu banco)&lt;/li&gt;
&lt;li&gt;criar views ou views materializadas, que são bem semelhantes a uma tabela, porém com dados modelados de uma forma mais madura para que a aplicação final possa utilizar isso em funcionalidades específicas.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Além disso, bancos de dados relacionais são muito conhecidos por serem ACID.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atômico - Garante que cada transação é tratada como uma unidade separada, e que ou roda tudo com sucesso, ou não roda nada e nenhuma alteração é aplicada ao estado do banco.&lt;/li&gt;
&lt;li&gt;Consistente - Garante que o banco de dados não será corrompido de forma alguma. Sem falhas, seguindo as regras, constraints, cascades e triggers definidos. Mantendo sempre um estado consistente.&lt;/li&gt;
&lt;li&gt;Isolado - A ideia de grandes bancos relacionais é garantir que as execuções possam rodar de forma concorrente ao máximo possível, ter um ambiente isolado ajuda no controle de concorrência, pois estamos sempre garantindo que o estado do banco estará da mesma forma que ele estaria se as execuções estivessem sendo feitas de forma sequencial.&lt;/li&gt;
&lt;li&gt;Durabilidade - Garante que seus dados estarão salvos independente de uma falha na aplicação, queda de energia ou qualquer outra coisa que possa afetar o processo do banco.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Um bom exemplo de um banco de dados relacional que é muito utilizado atualmente é o Postgres!&lt;/p&gt;

&lt;h2&gt;
  
  
  Modelo de Grafos
&lt;/h2&gt;

&lt;p&gt;Ué, grafos? Sim, aqueles grafos que você provavelmente viu na faculdade! Bolinha e tracinho pra todo lado, onde as bolinhas representam os nós e os tracinhos as arestas que conectam os nós.&lt;/p&gt;

&lt;p&gt;Mas o que isso tem a ver com modelo de dados? Bom, isso significa um modelo de dados altamente conectado, que se relacionam múltiplas vezes.&lt;/p&gt;

&lt;p&gt;Neste modelo podemos ter nós com propriedades específicas, como por exemplo, digamos que o nó representa uma pessoa, o mesmo nó pode ter as seguintes propriedades:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nome
idade
altura
peso
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E esse nó pode se relacionar com outro nó, através de uma aresta, que indica um relacionamento.&lt;/p&gt;

&lt;p&gt;Por sua vez, relacionamentos podem ser indicados de duas maneiras, sendo elas: [saída: outgoing, entrada: incoming]. E esse mesmo relacionamento pode possuir uma propriedade que esclarece qual o propósito do relacionamento.&lt;/p&gt;

&lt;p&gt;Ex:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8Nl2016u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4eho9zy8sdkrlqj5zs86.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8Nl2016u--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4eho9zy8sdkrlqj5zs86.png" alt="Screen Shot 2021-05-11 at 17.15.47"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nesse cenário, temos um nó que representa um usuário chamado John Doe, ele se relaciona com outro nó que representa um país chamado Canadá, e o propósito do relacionamento é indicar que John Doe mora/reside no Canadá.&lt;/p&gt;

&lt;p&gt;Representando isso usando Cypher (Query Language do Neo4j):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(u:User {name: 'John Doe'}),
(c:Country {name: 'Canadá'}),
(u)-[:LIVES_IN]-&amp;gt;(c)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Você não precisa necessariamente possuir um esquema pré-definido para poder criar nós e relacionamentos, eles podem ser criados com as propriedades e propósitos que melhor satisfazer a sua necessidade.&lt;/p&gt;

&lt;p&gt;Um bom exemplo de banco de dados atual que utiliza esse modelo é o Neo4j.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;O que podemos deduzir após olhar esses modelos? Claramente eles possuem uma certa afinidade, já que todos modelam dados para serem armazenados. Porém, eles são extremamente diferentes na modelagem, abordagens de relacionamentos, armazenamento, etc. E isso impacta diretamente no propósito deles.&lt;/p&gt;

&lt;p&gt;Pode ser que um dia você esbarre na necessidade de utilizar um banco key-value como Cache para a sua aplicação, um banco de documentos como uma estratégia de armazenar dados fragmentados que se relacionam mas que não possuem conexões externas. Ou até mesmo um banco de grafos para conseguir modelar a sua solução, tendo em vista que seus dados possuem muitos relacionamentos many-to-many.&lt;/p&gt;

&lt;p&gt;Se você se interessou por esse texto e ainda não leu o livro &lt;em&gt;Design Data-Intensive Applications&lt;/em&gt; do &lt;strong&gt;Martin Kleppmann&lt;/strong&gt;, eu super recomendo que você vá atrás dessa leitura! Inclusive, no livro, ele plota uma linha muito interessante entre dados que não se relacionam até dados que possuem muitas conexões.&lt;/p&gt;

&lt;p&gt;Ref:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sdwfmyQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwx47cq1trbgpddceiwz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sdwfmyQ8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nwx47cq1trbgpddceiwz.png" alt="Screen Shot 2021-05-11 at 17.28.17"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Você tem alguma sugestão, complemento ou crítica? Gostaria de saber mais sobre, deixa nos comentários pra eu poder ler 💜&lt;/p&gt;

</description>
      <category>database</category>
      <category>elixir</category>
    </item>
    <item>
      <title>Processos em Elixir</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Sat, 28 Nov 2020 18:20:19 +0000</pubDate>
      <link>https://dev.to/wlsf/processos-em-elixir-5e37</link>
      <guid>https://dev.to/wlsf/processos-em-elixir-5e37</guid>
      <description>&lt;h1&gt;
  
  
  Para quem é este texto?
&lt;/h1&gt;

&lt;p&gt;Este texto vai ser um pouco mais teórico, então se você está buscando entender melhor sobre como os &lt;em&gt;processos&lt;/em&gt; em Elixir funcionam, continue lendo...&lt;/p&gt;

&lt;h1&gt;
  
  
  Por que estudar processos?
&lt;/h1&gt;

&lt;p&gt;Como diria &lt;em&gt;Joe Armstrong&lt;/em&gt;, um dos criadores do Erlang:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"O Erlang foi projetado desde o começo para ser uma linguagem de programação funcional, que permitisse a criação de programas concorrentes e distribuídos." - citado em Programming Erlang, Software for a concurrent world.&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;E assim como Erlang, o Elixir também possui essas mesmas características, e lidar com &lt;strong&gt;programas concorrentes&lt;/strong&gt; tem se tornado cada vez mais uma necessidade real no mundo do Desenvolvimento de Software.&lt;/p&gt;

&lt;p&gt;Por isso, lidar com processos e suas abstrações no Elixir é um tópico extremamente importante, não só para conseguirmos aprimorar os nossos projetos, mas também para entender como a linguagem, frameworks e bibliotecas disponíveis nesse ecossistema funcionam.&lt;/p&gt;

&lt;h1&gt;
  
  
  Por onde começar?
&lt;/h1&gt;

&lt;p&gt;Elixir atualmente possui diversos tipos de abstrações de processos, como por exemplo: &lt;strong&gt;Tasks, Agents, GenServers e Supervisors&lt;/strong&gt;... Onde cada abstração possui a sua própria responsabilidade definida.&lt;/p&gt;

&lt;p&gt;É importante estar por dentro deste mundo de abstrações de processos desde a parte mais básica - utilizando spawn/receive - até a criação de processos com GenServers e Supervisors, já que estamos falando sobre uma linguagem de programação concorrente.&lt;/p&gt;

&lt;p&gt;Supondo que precisamos criar um módulo que será responsável por tratar detalhes específicos da funcionalidade do nosso produto, que não necessariamente precisam ser executados de forma síncrona, como um disparador de emails, ou até mesmo um disparador de tokens para um sistema 2FA (&lt;a href="https://en.wikipedia.org/wiki/Multi-factor_authentication"&gt;2 Factor Authentication&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;Ambos são exemplos de aplicações boas para ter um processo secundário rodando.&lt;/p&gt;

&lt;p&gt;Mas como eu posso começar a trabalhar com processos?&lt;/p&gt;

&lt;h2&gt;
  
  
  Iniciando com &lt;code&gt;spawn/1&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Uma das formas que tem funcionado muito bem para mim tem sido tentar entender como funcionavam os processos em Elixir desde o mais básico, utilizando somente &lt;code&gt;spawn/1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dito isso, vamos começar com um exemplo:&lt;/p&gt;

&lt;p&gt;Digamos que eu precise criar um processo que irá esperar uma mensagem e disparar um &lt;code&gt;IO.inspect/1&lt;/code&gt; (Função de inspecionar o elemento) com os argumentos recebidos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="c1"&gt;# módulo que irá disparar as mensagens&lt;/span&gt;
&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;DispatchMessage&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Process that will await for a message, dispatch when
  received and terminate. 
  """&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;wait_message&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="n"&gt;wait_message&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:inspect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ele irá executar uma simples atividade de forma assíncrona e encerrar.&lt;/p&gt;

&lt;p&gt;Podemos checar isso da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DispatchMessage&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.119.0&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alive?&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;span class="no"&gt;true&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:inspect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;hello:&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
&lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;hello:&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Process&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alive?&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;
&lt;span class="no"&gt;false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos ver com o &lt;code&gt;Process.alive?/1&lt;/code&gt; que o processo foi encerrado após executar a sua task de &lt;code&gt;IO.inspect(data)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Mas o que exatamente aconteceu quando executamos este trecho de código no &lt;em&gt;iex&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;DispatchMessage.start_link/0&lt;/code&gt; retornou um PID (Process ID), que é o que usaremos para nos comunicar com o processo que acabamos de criar.&lt;/p&gt;

&lt;p&gt;Já o &lt;code&gt;send/2&lt;/code&gt; é a função que usamos para enviar uma mensagem para o processo (PID) que criamos. Este mesmo processo já estava esperando receber uma mensagem a partir do trecho: &lt;code&gt;wait_message/0&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Ciclo de vida
&lt;/h1&gt;

&lt;p&gt;Existem alguns detalhes importantes para mencionar sobre o ciclo de vida desses tipos de processos.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Os processos criados a partir do &lt;code&gt;spawn/1&lt;/code&gt; por padrão irão executar uma task simples e encerrar.&lt;/li&gt;
&lt;li&gt;Apesar de estarmos paralelizando o projeto utilizando processos, nosso processo só será capaz de executar um comando por vez.&lt;/li&gt;
&lt;li&gt;Chamadas em excesso podem fazer com que o processo precise enfileirar as demais chamadas e isso pode causar &lt;em&gt;timeout&lt;/em&gt; em chamadas síncronas (pode acontecer se você estiver usando GenServer &lt;code&gt;handle_call/3&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Podemos determinar se esse processo está esperando por um input utilizando a estrutura de &lt;code&gt;receive&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
&lt;span class="o"&gt;...&amp;gt;&lt;/span&gt;   &lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; 
&lt;span class="o"&gt;...&amp;gt;&lt;/span&gt;     &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;puts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Recebi uma mensagem &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;...&amp;gt;&lt;/span&gt;   &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="o"&gt;...&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"oi"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="s2"&gt;"Recebi uma mensagem oi"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos definir também loops e até mesmo simular um estado interno para processos desse tipo, por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;StatefulProcess&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nv"&gt;@moduledoc&lt;/span&gt; &lt;span class="sd"&gt;"""
  Stateful process abstraction using spawn/1
  """&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;start_link&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;add_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;tuple&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;add_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nv"&gt;@spec&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;::&lt;/span&gt; &lt;span class="n"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:list&lt;/span&gt;

  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;([])&lt;/span&gt;
  &lt;span class="k"&gt;defp&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;receive&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;map_msg&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;map_msg&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="ss"&gt;:list&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;state&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acabamos de criar um módulo de processo com estado interno que irá iniciar vazio e incrementará a lista de estado a partir das chamadas &lt;code&gt;add_data/2&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;StatefulProcess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start_link&lt;/span&gt;
&lt;span class="c1"&gt;#PID&amp;lt;0.231.0&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;StatefulProcess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_data&lt;/span&gt; &lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;hello:&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;hello:&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;

&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;StatefulProcess&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;[%{&lt;/span&gt;&lt;span class="ss"&gt;hello:&lt;/span&gt; &lt;span class="ss"&gt;:world&lt;/span&gt;&lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="ss"&gt;:list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A grande sacada deste novo módulo é que quando iniciarmos o processo pelo &lt;code&gt;c:start_link/0&lt;/code&gt;, o mesmo não irá terminar após alguma execução (seja ela: &lt;code&gt;c:add_data/2&lt;/code&gt; ou &lt;code&gt;c:list/1&lt;/code&gt;), além de que ele também irá armazenar o estado atualizado a partir do &lt;code&gt;c:add_data/2&lt;/code&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Perceba a quantidade de possibilidades que temos somente com a implementação mais básica de processos em Elixir: imagine o que podemos fazer usando as demais abstrações acima!?&lt;/p&gt;

&lt;p&gt;A ideia deste texto era desmistificar processos com Elixir, mostrar algumas abordagens usando &lt;code&gt;spawn/1&lt;/code&gt; e &lt;code&gt;receive-do&lt;/code&gt; e destacar alguns pontos importantes sobre ciclo de vida dentro da linguagem.&lt;/p&gt;

&lt;p&gt;Os tópicos abordados neste texto podem servir para os demais tipos de processos. Pretendo escrever mais sobre as outras abstrações!&lt;/p&gt;

&lt;p&gt;Até mais...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/tuvMgAPzxaQBq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/tuvMgAPzxaQBq/giphy.gif" alt="cat bye giphy"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
      <category>tutorial</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Protocolos com Elixir</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Thu, 29 Oct 2020 13:30:57 +0000</pubDate>
      <link>https://dev.to/wlsf/protocolos-com-elixir-e0k</link>
      <guid>https://dev.to/wlsf/protocolos-com-elixir-e0k</guid>
      <description>&lt;p&gt;Os protocolos são uma forma de alcançar polimorfismo utilizando Elixir. Podemos determinar ações para uma função genérica baseado no tipo de dado inserido.&lt;/p&gt;

&lt;p&gt;Digamos que você precisa implementar uma função que será responsável por recuperar o primeiro elemento de uma lista.&lt;/p&gt;

&lt;p&gt;Teríamos algo mais ou menos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule MyList do
  def first_item([item | _list]), do: item
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usando este exemplo no IEx, conseguimos visualizar o seu funcionamento:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; my_list = [1, 2, 3, 4, 5, 6, 7]
[1, 2, 3, 4, 5, 6, 7]
iex&amp;gt; MyList.first_item(my_list)
1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uma vez que criamos este módulo &lt;code&gt;MyList&lt;/code&gt; e definimos a função para receber uma lista como parâmetro através de &lt;em&gt;pattern matching&lt;/em&gt;, a sua implementação fica limitada a somente listas não-vazias.&lt;/p&gt;

&lt;p&gt;O uso de outro tipo de dado como argumento geraria o seguinte erro:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; MyList.first_item(%{t: 2, b: 3})
** (FunctionClauseError) no function clause matching in MyList.first_item/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos resolver esse problema de duas maneiras, onde uma delas seria implementar uma nova função com um &lt;em&gt;guard&lt;/em&gt; que cumpra os requisitos para Maps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule MyList do
  def first_item([item | _list]), do: item
  def first_item(map) when is_map(map) do
    map
    |&amp;gt; Enum.to_list()
    |&amp;gt; List.first()
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E dessa forma seria possível utilizar maps e listas como argumentos, ex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;iex&amp;gt; list = [1,2,3,4,5,6,7,8,9]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
iex&amp;gt; map = %{a: 1, b: 2}
%{a: 1, b: 2}
iex&amp;gt; MyList.first_item(list)
1
iex&amp;gt; MyList.first_item(map)
{:a, 1}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enquanto isso, a segunda opção para resolver este problema seria implementar um protocolo para essa função e garantir que esse protocolo funcione para as seguintes implementações: [Lista, Map]&lt;/p&gt;

&lt;p&gt;Mas como fazemos isso?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Mr5yS9nR4kAda/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Mr5yS9nR4kAda/giphy.gif" alt="dancing cat gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Protocolos e Implementações
&lt;/h1&gt;

&lt;p&gt;Fazendo uma breve analogia a linguagens OO (Orientada a Objetos), podemos ver o &lt;strong&gt;Protocolo&lt;/strong&gt; em si como uma Interface, onde iremos definir a assinatura de um método, e as implementações como o famoso @override que usamos para dizer que queremos sobrescrever a implementação de determinada funcionalidade da interface que estamos implementando.&lt;/p&gt;

&lt;p&gt;A definição de protocolos é feita através da estrutura &lt;code&gt;defprotocol&lt;/code&gt;, da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defprotocol MyList do
  def first_item(value)
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não precisamos dizer como a função &lt;code&gt;first_item/1&lt;/code&gt; irá funcionar, basta indicar que estamos criando esse protocolo e que ele precisa possuir as devidas implementações para funcionar de acordo com o esperado.&lt;/p&gt;

&lt;p&gt;Agora vamos fazer as implementações usando &lt;code&gt;defimpl&lt;/code&gt; para o nosso caso de aceitar Listas e Maps como argumentos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defimpl MyList, for: List do
  def first_item([item | _list]), do: item
end

defimpl MyList, for: Map do
  def first_item(map) do
    map
    |&amp;gt; Enum.to_list()
    |&amp;gt; List.first()
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Conclusão
&lt;/h1&gt;

&lt;p&gt;Com &lt;strong&gt;Protocolos&lt;/strong&gt; nós podemos definir diferentes tipos de comportamentos para uma determinada função, sempre se baseando no tipo de dado que queremos processar.&lt;/p&gt;

&lt;p&gt;Um bom exemplo de cenário real para isso é o próprio Jason que usamos para transformar as respostas da nossa aplicação web.&lt;/p&gt;

&lt;p&gt;O mesmo possui um protocolo chamado &lt;a href="https://github.com/michalmuskala/jason/blob/master/lib/encoder.ex"&gt;Jason.Encoder&lt;/a&gt;, contendo a assinatura do método encode. A partir desta interface podemos implementar diferentes tipos de encoding para json dependendo do tipo de dados que queremos retornar na nossa API.&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>erlang</category>
      <category>protocols</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Elixir GenServer?</title>
      <dc:creator>Willian Frantz</dc:creator>
      <pubDate>Wed, 07 Oct 2020 02:55:52 +0000</pubDate>
      <link>https://dev.to/wlsf/elixir-genserver-2n6p</link>
      <guid>https://dev.to/wlsf/elixir-genserver-2n6p</guid>
      <description>&lt;p&gt;Primeiramente, oi 👋 me chamo Willian, sou desenvolvedor e pretendo usar esse espaço para compartilhar o pouco que aprendi durante esses últimos anos trabalhando com TI.   Se você é pessoa desenvolvedora back-end e/ou está sempre procurando atualizações, novas tecnologias ou novos conhecimentos, esse texto é para você!&lt;/p&gt;

&lt;p&gt;Bom, vem comigo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/LoCDk7fecj2dwCtSB3/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/LoCDk7fecj2dwCtSB3/giphy.gif" alt="Come on!!!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Elixir
&lt;/h1&gt;

&lt;p&gt;Se você ainda não conhece a linguagem de programação Elixir, vou deixar alguns links abaixo que considero como sendo os de maior influência para te dar uma leve noção de sintaxe e semântica, porém nada muito profundo, para não te sobrecarregar. 😄  &lt;/p&gt;

&lt;p&gt;Links:&lt;br&gt;
&lt;a href="https://elixir-lang.org/" rel="noopener noreferrer"&gt;https://elixir-lang.org/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://elixirschool.com/pt" rel="noopener noreferrer"&gt;https://elixirschool.com/pt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Além disso, pretendo postar mais conteúdos sobre e garantir que seja possível acompanhar essa tecnologia, e entender como ela pode funcionar (ou não) para você!&lt;/p&gt;
&lt;h1&gt;
  
  
  GenServer
&lt;/h1&gt;
&lt;h2&gt;
  
  
  O que seria isso?
&lt;/h2&gt;

&lt;p&gt;Ele é um dos módulos que compõem o pacote &lt;a href="https://en.wikipedia.org/wiki/Open_Telecom_Platform" rel="noopener noreferrer"&gt;OTP (Erlang/BEAM)&lt;/a&gt;. É possível acessar ele a partir do Elixir graças a &lt;a href="https://elixir-lang.org/getting-started/erlang-libraries.html" rel="noopener noreferrer"&gt;interoperabilidade&lt;/a&gt; que a linguagem oferece.   &lt;/p&gt;

&lt;p&gt;Diz-se que o GenServer é um tipo de processo, assim como os demais processos que podem ser gerados no Elixir (ex: &lt;em&gt;&lt;a href="https://hexdocs.pm/elixir/Agent.html" rel="noopener noreferrer"&gt;Agent&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href="https://hexdocs.pm/elixir/Task.html" rel="noopener noreferrer"&gt;Task&lt;/a&gt;&lt;/em&gt;). O seu diferencial é que os processos que são criados a partir de sua implementação possuem um estado interno; em outras palavras, você pode criar um processo que roda como um servidor à parte, de forma assíncrona, sem interferir na sua aplicação principal, e esse processo terá um estado interno que poderá ser alterado da forma que for mais adequado para suas necessidades.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ciclo de vida
&lt;/h2&gt;

&lt;p&gt;O ciclo de vida do seu GenServer tende a funcionar da seguinte maneira: inicia -&amp;gt; loop(chama uma função -&amp;gt; gera um novo estado).&lt;/p&gt;

&lt;p&gt;Ex:&lt;br&gt;
Suponhamos que você tenha utilizado o GenServer para implementar uma pilha, seria mais ou menos assim:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fne0h89af65dtuydkyits.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fne0h89af65dtuydkyits.png" alt="diagrama sobre o uso do GenServer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A sua aplicação inicia essa pilha chamando &lt;strong&gt;Stack.start()&lt;/strong&gt; (você está iniciando o seu processo).&lt;/p&gt;

&lt;p&gt;Você pode adicionar elementos ou remover elementos utilizando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stack.push(value) # value = valor que você deseja adicionar.
stack.pop() # retorna o valor que está no topo da pilha.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Os métodos &lt;code&gt;push/1&lt;/code&gt; e &lt;code&gt;pop/0&lt;/code&gt; se encaixam no &lt;code&gt;loop&lt;/code&gt; citado acima, onde você está chamando uma função e atualizando o estado interno do seu &lt;strong&gt;GenServer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;⚠️ Lembrando que essa pilha irá executar o &lt;code&gt;push/1&lt;/code&gt; de forma assíncrona por ser implementada usando o método &lt;code&gt;handle_cast&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Exemplo implementação de pilha
&lt;/h2&gt;

&lt;p&gt;Seguindo no exemplo do tópico anterior, se estivesse implementando uma pilha, você iria neste caminho:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;defmodule Stack do
  use GenServer

  # {...} Outras implementações como init, start_link, etc...

  def handle_call(:pop, _from, [value | state]), do: {:reply, value, state}
  def handle_call(:pop, _from, []), do: {:reply, nil []}

  def handle_cast({:push, value}, state), do: {:no_reply, [value | state]}

  def push(value), do: GenServer.cast(__MODULE__, {:push, value})
  def pop(), do: GenServer.call(__MODULE__, :pop)
end

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;E isso rodaria mais ou menos assim: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdtukbkb1npp4yyt637z0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdtukbkb1npp4yyt637z0.gif" alt="exemplo executando pilha, formato GIF"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Curiosidades
&lt;/h2&gt;

&lt;p&gt;O &lt;a href="https://discord.com/" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; atualmente utiliza Elixir e resolve alguns de seus problemas técnicos utilizando GenServer. Um bom exemplo disso é a implementação de semaphores que foi feito para tratar o gerenciamento dos processos, link: &lt;a href="https://github.com/discord/semaphore" rel="noopener noreferrer"&gt;https://github.com/discord/semaphore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Além disso, existem libs do próprio ecossistema do Elixir que utilizam GenServer, um bom exemplo disso seria a própria lib do &lt;a href="https://github.com/kafkaex" rel="noopener noreferrer"&gt;kafka_ex&lt;/a&gt;, que conecta a sua aplicação ao seu serviço &lt;a href="http://kafka.apache.org/" rel="noopener noreferrer"&gt;Apache Kafka&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O GenServer é muito utilizado no dia-a-dia de um desenvolvedor Elixir, as vezes até mesmo de forma inconsciente (em libs, frameworks, etc). Por isto, é sempre bom conhecer e saber que ele existe e como ele funciona por baixo dos panos.&lt;/p&gt;

&lt;p&gt;Deixarei aqui um repositório com algumas implementações básicas de estruturas de dados:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/WLSF" rel="noopener noreferrer"&gt;
        WLSF
      &lt;/a&gt; / &lt;a href="https://github.com/WLSF/data_structures_ex" rel="noopener noreferrer"&gt;
        data_structures_ex
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Repo to implement data structures using Elixir GenServer
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Estruturas de dados usando GenServer (Elixir)&lt;/h1&gt;

&lt;/div&gt;

&lt;p&gt;Ex de como executar:&lt;/p&gt;

&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;iex
$ Stack.start_link
$ Stack.push 10
$ Stack.pop
-&amp;gt; 10
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Repositório do texto: &lt;a href="https://dev.to/wlsf/elixir-genserver-2n6p" rel="nofollow"&gt;Elixir GenServer?&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/WLSF/data_structures_ex" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;Por hoje é só, até a próxima... 👋&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>phoenix</category>
      <category>erlang</category>
      <category>genserver</category>
    </item>
  </channel>
</rss>
