<?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: Leoni Mella</title>
    <description>The latest articles on DEV Community by Leoni Mella (@leonimella).</description>
    <link>https://dev.to/leonimella</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%2F325680%2F5c71dfe3-9963-43a8-937e-caf9c2c2d71b.jpeg</url>
      <title>DEV Community: Leoni Mella</title>
      <link>https://dev.to/leonimella</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/leonimella"/>
    <language>en</language>
    <item>
      <title>O que é um produto?</title>
      <dc:creator>Leoni Mella</dc:creator>
      <pubDate>Sun, 08 May 2022 23:32:21 +0000</pubDate>
      <link>https://dev.to/leonimella/o-que-e-um-produto-49jj</link>
      <guid>https://dev.to/leonimella/o-que-e-um-produto-49jj</guid>
      <description>&lt;p&gt;Faz tempo que penso em criar algum produto / empresa com as habilidades que adquiri ao longo dos anos como desenvolvedor, mas nunca tive um feeling &lt;strong&gt;do que&lt;/strong&gt; fazer.&lt;/p&gt;

&lt;p&gt;E ai um tempo atrás no trabalho aconteceu uma coisa que achei muito interessante.&lt;/p&gt;

&lt;p&gt;Durante uma chamada de vídeo, com um possível fornecedor, eles apresentaram o produto deles e eu fiquei de boca aberta &lt;strong&gt;porque eu tinha desenvolvido a mesma coisa em 2018!!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  O ano era 2018
&lt;/h2&gt;

&lt;p&gt;Uma empresa da Estônia entrou em contato comigo pelo LinkedIn interessada no meu perfil e depois de uma conversa rápida marcamos a primeira entrevista.&lt;/p&gt;

&lt;p&gt;Logo em seguida me passaram o teste técnico que era fazer uma API capaz de ler arquivos &lt;code&gt;.csv&lt;/code&gt; e salvar o conteúdo em um banco de dados.&lt;/p&gt;

&lt;p&gt;Se você quiser dar uma olhada no resultado desse teste ele está público no meu GitHub.&lt;/p&gt;

&lt;p&gt;Mas vou deixar um disclaimer aqui devido ao fato dele ser bem antigo então não sei se ele funciona ainda hahaha.&lt;/p&gt;

&lt;p&gt;Em todo o caso: &lt;a href="https://github.com/leonimella/fractory"&gt;Fractory&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cumpri os requisitos do teste e ainda fiz uma parada que se houvesse um erro em uma linha, ele retornava a mesma para o usuário pedindo para ele corrigir.&lt;/p&gt;

&lt;p&gt;Ficou um projeto bem legal! Feito em PHP (com Laravel) e JS (front em React).&lt;/p&gt;

&lt;p&gt;Apesar de gostarem do resultado e me chamarem para a última entrevista acabei não passando para a vaga, mas sem problemas, faz parte.&lt;/p&gt;

&lt;h2&gt;
  
  
  Voltando para 2022...
&lt;/h2&gt;

&lt;p&gt;Eu conheci a &lt;a href="https://flatfile.com/"&gt;FlatFile&lt;/a&gt;, uma empresa fundada em 2019 que levantou ~7.9M de dólares e o que eles fazem é exatamente a mesma coisa que o meu repozinho em PHP faz!!!&lt;/p&gt;

&lt;p&gt;Claro que eles fazem de um jeito &lt;strong&gt;MUITO&lt;/strong&gt; melhor e mais elegante, mas cara, o que eu fiz foi no mínimo o MVP da &lt;strong&gt;FlatFile&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  E isso me faz pensar...
&lt;/h2&gt;

&lt;p&gt;Deve existir mais um monte de coisas simples que nós fazemos e resolvemos durante nosso dia que teria espaço para crescer em algo maior.&lt;/p&gt;

&lt;p&gt;Igual a FlatFile fez com uma ideia tão simples, mas que é uma dorzinha chata em várias aplicações e sistemas.&lt;/p&gt;

&lt;p&gt;E também após esse episódio fico me perguntando:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"o que mais eu já fiz ou que eu faço que poderia virar um produto oferecido por uma empresa?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ainda não tenho uma resposta para essa pergunta.&lt;/p&gt;

&lt;p&gt;Será que você também já não fez alguma coisa que poderia ter um valor grande e que pessoas estejam dispostas a pagar por isso?&lt;/p&gt;

&lt;p&gt;Faz a gente pensar nas possibilidades, né?&lt;/p&gt;

&lt;p&gt;Obrigado pelo tempo&lt;/p&gt;

&lt;p&gt;🖖&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Nasce um programador</title>
      <dc:creator>Leoni Mella</dc:creator>
      <pubDate>Mon, 11 Jan 2021 15:15:27 +0000</pubDate>
      <link>https://dev.to/leonimella/nasce-um-programador-16cc</link>
      <guid>https://dev.to/leonimella/nasce-um-programador-16cc</guid>
      <description>&lt;p&gt;E ai pessoal, Leoni aqui, voltando a publicar depois de quase um ano sem publicar nada 😮.&lt;/p&gt;

&lt;p&gt;Para ganhar um pouco de inércia na criação de conteúdo eu queria contar para vocês como que eu comecei a programar e como construí a minha carreira no desenvolvimento.&lt;/p&gt;

&lt;p&gt;Apesar de ser um tema bastante documentado, acredito que &lt;strong&gt;cada pessoa tem uma experiência única&lt;/strong&gt; e por isso vim aqui contar um pouco do que passei, então bora lá!&lt;/p&gt;

&lt;h2&gt;
  
  
  Antes da programação só existia o caos!
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/5qoRdabXeT4GY/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/5qoRdabXeT4GY/giphy.gif" width="439" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Acho importante dizer logo de cara que eu nem sabia o que era programação, na realidade eu não tinha ideia do que queria fazer da vida.&lt;/p&gt;

&lt;p&gt;E os primeiros anos da minha "carreira" refletiu bastante esse problema, pois &lt;strong&gt;sem saber muito bem o que fazer, fui aproveitando as oportunidades que apareciam.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fui de montador veicular à assistente de compras, passando por corretor de imóveis, motorista Uber e algumas tentativas de "empreender" fracassadas.&lt;/p&gt;

&lt;p&gt;Pois é, eu fazia o que aparecia na esperança de encontrar algo que eu realmente gostava.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Escrevi meu primeiro código no final de 2014, enquanto era corretor de imóveis, pois queria criar um site para anunciar os imóveis que eu poderia vender.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resultado?&lt;/strong&gt; Não fiz site nenhum e não aprendi a programar também. Beleza, vida que segue, mas gostei muito de ter aprendido um pouco sobre criação de sites e ter uma introdução a HTML e CSS&lt;/p&gt;

&lt;p&gt;Até que no final de 2015 eu fui &lt;strong&gt;demitido do meu emprego de assistente de compras&lt;/strong&gt;, que aliás eu achava um saco (talvez por isso mesmo eu tenha sido demitido...) e resolvi dar mais uma chance para "aprender a criar um site"&lt;/p&gt;

&lt;p&gt;E daí em diante, não parei mais! 🚀&lt;/p&gt;

&lt;h2&gt;
  
  
  Nasce um programador
&lt;/h2&gt;

&lt;p&gt;Ainda em 2015 eu comprei o curso &lt;a href="https://www.udemy.com/course/design-and-develop-a-killer-website-with-html5-and-css3/"&gt;Design and develop a killer website with html5 and css3&lt;/a&gt; na Udemy.&lt;/p&gt;

&lt;p&gt;É um curso bem simples sobre criação de websites usando HTML e CSS. Concluí o curso bem rápido e comecei a praticar criando sites pequenos para alguns amigos, tudo na faixa.&lt;/p&gt;

&lt;p&gt;Depois de achar que tinha dominado bem HTML e CSS comecei a estudar JavaScript e PHP também em cursos onlines.&lt;/p&gt;

&lt;p&gt;Depois de uns 5 meses eu senti que dava pra arriscar algumas entrevistas e comecei a montar um portfólio básico.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;E foi em maio de 2016, 7 meses depois de começar a programar que consegui meu primeiro trabalho como Desenvolvedor Front-End!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Pausa para uma reflexão
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Eu entendo o quanto eu fui privilegiado aqui.&lt;/strong&gt; Minha vida estava estável o suficiente para que eu dedicasse 6 a 7 meses a uma prática sem precisar me preocupar com a minha sobrevivência uma vez que sai com uma grana da minha demissão e ainda morava com os meus pais.&lt;/p&gt;

&lt;p&gt;Muita gente que está lendo isso não tem condição alguma de fazer, de pausar a vida para se dedicar a algo que elas gostem, por isso sou muito grato pela oportunidade que tive.&lt;/p&gt;

&lt;p&gt;No entanto, mesmo sem dispor desse tempo ainda é possível aprender a programar. Se você tem esse objetivo, não desista e saiba que você tem uma comunidade de desenvolvedores e desenvolvedoras incríveis que vão te ajudar a chegar onde você quer.&lt;/p&gt;

&lt;p&gt;Se dedique o quanto você conseguir, mesmo que for só alguns minutos por semana e tenha consistência que o resultado vai chegar, foque no longo prazo e tente fazer pequenas coisas, mas faça!&lt;/p&gt;

&lt;h2&gt;
  
  
  O primeiro emprego
&lt;/h2&gt;

&lt;p&gt;Comecei a trabalhar em uma agência digital fazendo temas institucionais no WordPress para os clientes que eles possuíam. Eu era o único desenvolvedor lá e o trabalho era bem tranquilo.&lt;/p&gt;

&lt;p&gt;Mas devo confessar que eu não fazia ideia de como era programar um tema de WordPress antes de fazer a entrevista nesta agência 😅.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eu tinha um curso comprado que ensinava exatamente isso&lt;/strong&gt;, mas nunca tinha feito ele e durante a entrevista quando me perguntaram se eu sabia mexer com o WordPress eu dei uma &lt;em&gt;leeeeve&lt;/em&gt; enrolada, joguei um "veja bem..." e "conheço o básico" e assim que eu saí da entrevista fui correndo para casa começar o bendito curso Hahahaha.&lt;/p&gt;

&lt;p&gt;Eu sei, não foi o mais correto a se fazer, mas eu tinha certeza que eu conseguiria aprender a tempo &lt;strong&gt;e apesar de eu não entender especificamente o WordPress eu já tinha uma boa base de PHP, por isso senti essa confiança.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No final, tudo deu certo. Trabalhei nesta agência por quase um ano e depois saí dela procurando um lugar de volta na minha cidade natal, São Paulo, mas a experiência toda lá foi excelente.&lt;/p&gt;

&lt;h2&gt;
  
  
  4 anos depois...
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Uma vez que você consegue um emprego como programador o crescimento na área fica mais fluído e natural.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Frequentemente você precisa aprender a usar uma ferramenta, linguagem ou recurso que você não conhece e aí você começa a estudar, praticar e implementar essas coisas novas e com isso vai montando um repertório cada vez maior de conhecimento.&lt;/p&gt;

&lt;p&gt;E foi exatamente assim que eu passei esses últimos 4 anos, desde que comecei a programar. No meu caso as coisas aconteceram mais ou menos assim:&lt;/p&gt;

&lt;p&gt;1) Primeiro emprego &lt;strong&gt;HTML&lt;/strong&gt; e &lt;strong&gt;CSS&lt;/strong&gt;, com uma pitada de &lt;strong&gt;PHP&lt;/strong&gt; e &lt;strong&gt;JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;2) Segundo, mergulhando um pouco mais no desenvolvimento de temas em WordPress e entendimento mais profundo em &lt;strong&gt;PHP&lt;/strong&gt;, &lt;strong&gt;MySQL&lt;/strong&gt; e &lt;strong&gt;JavaScript&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;3) Terceiro, agora trabalhando como Fullstack em &lt;strong&gt;PHP&lt;/strong&gt;, pude aprender a utilizar frameworks como: &lt;strong&gt;Laravel&lt;/strong&gt;, &lt;strong&gt;Symfony&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;4) Quarto, programador back-end em 3 linguagens principais: &lt;strong&gt;PHP&lt;/strong&gt;, &lt;strong&gt;Elixir&lt;/strong&gt; e &lt;strong&gt;Python&lt;/strong&gt;. Diversas outras ferramentas nessas linguagens aprendidas e utilizadas.&lt;/p&gt;

&lt;p&gt;É incrível ver como cada coisinha nova que aprendo vai se acumulando nesse, agora, grande repositório de conhecimento. O que me permite crescer cada vez mais.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;É claro que nessa contagem eu listei apenas as experiências que agregaram&lt;/strong&gt; todo mundo vai passar por perrengues, mas no meu caso eles foram exceções bem raras (ainda bem) e sinceramente não merecem o meu tempo - nem o seu.&lt;/p&gt;

&lt;h2&gt;
  
  
  A melhor profissão do mundo
&lt;/h2&gt;

&lt;p&gt;Ok, talvez não seja, mas eu amo o que faço.&lt;/p&gt;

&lt;p&gt;É muito legal ver o quanto eu era perdido, profissionalmente, e como estou agora... fazendo o que amo realmente!&lt;/p&gt;

&lt;p&gt;Apesar disso eu penso na programação como um &lt;strong&gt;meio&lt;/strong&gt; e não um fim. Eu descobri no que eu sou bom e quero utilizar dessa habilidade para construir uma vida melhor para mim e minha família.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pra mim, programação é uma habilidade, uma ferramenta e não um objetivo de vida.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;E espero tirar o máximo de proveito dessa habilidade e poder ajudar pessoas que também desejam aprender como dominá-la.&lt;/p&gt;

&lt;h2&gt;
  
  
  E pra encerrar
&lt;/h2&gt;

&lt;p&gt;O melhor de programar é a comunidade. Sempre muito colaborativa e preocupada em fornecer conteúdo de qualidade e acessível.&lt;/p&gt;

&lt;p&gt;Por isso, recentemente, passei a produzir conteúdo na esperança de conseguir devolver um pouco todo o conhecimento que adquiri para essa comunidade maravilhosa e ajudar tantos outros que estão começando nessa jornada.&lt;/p&gt;

&lt;p&gt;Se você gostou desse artigo, não deixe de me seguir aqui, e em outras plataformas onde eu  produzo conteúdo. Gosto de conversar sobre programação e se tiver alguma dúvida ou gostaria de algum conselho, não se acanhe! Pode me procurar!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Meu perfil aqui, na comunidade Dev: &lt;a href="https://dev.to/leonimella"&gt;leonimella&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Meu Twitter, praticamente a única rede social que uso ferquentemente &lt;a href="https://twitter.com/LeoniMella"&gt;@LeoniMella&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Meu canal de lives na Twitch: &lt;a href="https://twitch.tv/mrleoni"&gt;MrLeoni&lt;/a&gt;, essa é minha forma preferida de gerar conteúdo!&lt;/li&gt;
&lt;li&gt;E não podia faltar, meu perfil no Github: &lt;a href="https://github.com/leonimella"&gt;leonimella&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;E como sempre, obrigado pelo seu tempo e até a próxima 🖖&lt;br&gt;
&lt;a href="https://i.giphy.com/media/gtzIP3mpbzh16/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/gtzIP3mpbzh16/giphy.gif" width="300" height="168"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Docker e Docker Compose um guia para iniciantes.</title>
      <dc:creator>Leoni Mella</dc:creator>
      <pubDate>Mon, 11 May 2020 14:24:17 +0000</pubDate>
      <link>https://dev.to/ingresse/docker-e-docker-compose-um-guia-para-iniciantes-48k8</link>
      <guid>https://dev.to/ingresse/docker-e-docker-compose-um-guia-para-iniciantes-48k8</guid>
      <description>&lt;h1&gt;
  
  
  Docker e Docker Compose um guia para iniciantes.
&lt;/h1&gt;

&lt;p&gt;Quando comecei a usar &lt;em&gt;Docker&lt;/em&gt; e o &lt;em&gt;Docker Compose&lt;/em&gt; foi fácil entender quais eram suas funções, mas encontrei dificuldade em descobrir como eu poderia aplicá-los em meus projetos. Depois de muita leitura, tentativa e erro e algumas implementações eu consegui "decifrar" os &lt;strong&gt;pedaços que estavam faltando&lt;/strong&gt; e aprendi o básico para utilizá-lo.&lt;/p&gt;

&lt;p&gt;Nesse artigo tento explicar alguns desses pedaços que, os inciantes em &lt;em&gt;Docker&lt;/em&gt;, geralmente se confundem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Antes de começarmos
&lt;/h2&gt;

&lt;p&gt;Caso você não conheça nada sobre &lt;em&gt;Docker&lt;/em&gt;, sugiro que você leia a &lt;a href="https://docs.docker.com/"&gt;documentação oficial&lt;/a&gt; antes e se você ainda não tem &lt;em&gt;Docker&lt;/em&gt; e &lt;em&gt;Docker Compose&lt;/em&gt; instalado, aqui estão alguns links para ajuda-lo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/install/"&gt;Instalação&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/como-instalar-e-utilizar-o-docker-primeiros-passos-pt"&gt;Instalação em pt-br&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/engine/docker-overview/"&gt;Docker overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Docker Compose

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/install/"&gt;Instalação&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-install-docker-compose-on-ubuntu-18-04-pt"&gt;Instalação em pt-br&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.docker.com/compose/"&gt;Docker Compose overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dividi este artigo por partes que considero importante, sinta-se livre para pular as que você já esteja familiarizado.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;center&gt;Parte 01 - Dockerfile, Imagens e Containers&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Geralmente o arquivo &lt;code&gt;Dockerfile&lt;/code&gt; é o ponto de entrada para quem começa a utilizar o &lt;em&gt;Docker&lt;/em&gt;. Embora o &lt;a href="https://docs.docker.com/get-started/part2/"&gt;guia&lt;/a&gt; explique bem as instruções definidas no arquivo eu não conseguia entender muito bem o que eram as &lt;strong&gt;imagens&lt;/strong&gt; e o que eram os &lt;strong&gt;containers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;Dockerfile&lt;/code&gt; define uma &lt;strong&gt;imagem&lt;/strong&gt;. E o que é uma imagem? A &lt;strong&gt;imagem&lt;/strong&gt; é um conjunto de recursos responsável pela execução de um código ou uma aplicação. Geralmente a imagem que você define sempre tem outra imagem como base. Você pode pensar nela como se fosse um pacote semelhante a um módulo do &lt;code&gt;node_modules&lt;/code&gt;, ou um &lt;code&gt;package&lt;/code&gt; dentro do &lt;code&gt;vendor&lt;/code&gt; da sua aplicação, não é a forma mais correta de definir, mas pode ajudar a enxergar como ela funciona. Esses pacotes de recursos servem para executar alguma função dentro da sua aplicação, já as imagens servem para construir o &lt;strong&gt;container&lt;/strong&gt; que você vai rodar sua aplicação.&lt;/p&gt;

&lt;p&gt;Todo &lt;strong&gt;container&lt;/strong&gt; roda em cima de uma &lt;strong&gt;imagem&lt;/strong&gt;, é uma dependência direta, se tem um &lt;strong&gt;container&lt;/strong&gt; sendo executado tem uma &lt;strong&gt;imagem&lt;/strong&gt; por trás dele. Por exemplo, vamos supor que nós queremos executar o comando &lt;code&gt;elixir -v&lt;/code&gt;. Nós precisamos definir uma &lt;strong&gt;imagem&lt;/strong&gt; capaz de interpretar a linguagem Elixir e depois colocar um &lt;strong&gt;container&lt;/strong&gt; para executar essa imagem. Vamos criar o &lt;code&gt;Dockerfile&lt;/code&gt; e inserir nele o mínimo do mínimo para nosso exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; elixir:1.10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora vamos construir a imagem que estamos definindo com o comando &lt;code&gt;build&lt;/code&gt; (mais sobre a &lt;code&gt;--tag&lt;/code&gt; depois):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;elixir:example &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="c"&gt;# o ponto final é importante!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pronto! Temos a imagem criada, você pode conferir ela listando as imagens no seu sistema, executando &lt;code&gt;docker image ls&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Agora que temos uma imagem definida, vamos criar nosso container e executar o comando que queremos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; elixir:example elixir &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;E pronto! A imagem que criamos foi utilizada nesse container que executou o comando &lt;code&gt;elixir -v&lt;/code&gt; e foi destruído após essa execução graças a flag &lt;code&gt;--rm&lt;/code&gt; que passamos.&lt;/p&gt;

&lt;h3&gt;
  
  
  "Pegadinhas"
&lt;/h3&gt;

&lt;p&gt;Nosso &lt;code&gt;Dockerfile&lt;/code&gt; é muito muito simples e nesse caso não precisaríamos ter definido um. O mesmo resultado pode ser obtido ao executar o comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; elixir:1.10 elixir &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora ao invés rodar um container em cima da imagem que criamos com o &lt;code&gt;docker build ...&lt;/code&gt;, rodamos o container tendo como base a imagem padrão do Elixir 1.10: &lt;code&gt;elixir:1.10&lt;/code&gt;. Já que nossa imagem só tem como dependência a &lt;code&gt;elixir:1.10&lt;/code&gt; cortamos caminho e executamos o container direto com ela.&lt;/p&gt;

&lt;p&gt;Mas vamos supor que além da linguagem Elixir instalada, precisássemos também do Git. Ai sim declaramos um &lt;code&gt;Dockerfile&lt;/code&gt; que reuna as duas dependências:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; elixir:1.10&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install &lt;/span&gt;git &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma a imagem gerada contém esses dois recursos que seriam necessários pela nossa aplicação.&lt;/p&gt;

&lt;p&gt;E pra fechar essa primeira parte, e quanto a essa flag que utilizamos &lt;code&gt;--tag&lt;/code&gt;? Quando "tageamos" uma imagem estamos versionando ela, você pode fazer um paralelo com o sistema de &lt;strong&gt;branches&lt;/strong&gt; do Git. Ao tagear uma imagem nós salvamos tudo o que foi instalado nessa imagem naquela versão. Por exemplo, a imagem &lt;code&gt;elixir:1.10&lt;/code&gt; significa que estamos utilizando uma imagem com nome Elixir e que a versão dessa &lt;strong&gt;imagem&lt;/strong&gt; é a 1.10, &lt;strong&gt;por convenção a versão de Elixir sendo executada dentro dessa imagem também é a 1.10.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Isso se repete para todas as outras linguagens e recursos: &lt;code&gt;php:7.3&lt;/code&gt;, &lt;code&gt;python:3.8&lt;/code&gt;, &lt;code&gt;ubuntu:18.04&lt;/code&gt; e etc...&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;center&gt;Parte 02 - Operando o Container&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;O &lt;strong&gt;container&lt;/strong&gt; é a parte responsável por executar o que foi definido na sua imagem, sendo assim é recomendado evitar qualquer mudança ou edição diretamente. Caso você instale ou modifique alguma coisa no container a alteração feita fica disponível somente no próprio &lt;strong&gt;container&lt;/strong&gt; e não na &lt;strong&gt;imagem&lt;/strong&gt; base. Dito isso, de vez em quando precisamos debugar, modificar ou experimentar alguma coisa em nossas aplicações.&lt;/p&gt;

&lt;p&gt;Vamos cobrir algumas operações e configurações básicas que podem ajudar você a dar aquele ajuste fino na sua aplicação e ver o que está acontecendo dentro dela.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Criando
&lt;/h3&gt;

&lt;p&gt;O comando &lt;code&gt;docker run&lt;/code&gt; cria um container dada determinada imagem e ele ficará la até que você o remova. Se você usa a forma mais simples do comando, &lt;code&gt;docker run elixir:1.10&lt;/code&gt; o &lt;em&gt;Docker&lt;/em&gt; cria um container com um nome default gerado automaticamente, executa o que está definido na imagem, ou o comando que você passou com o output do comando no terminal.&lt;/p&gt;

&lt;p&gt;Podemos melhorar isso passando alguns parâmetros para o comando &lt;code&gt;docker run&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Dê um nome ao seu container usando a flag &lt;code&gt;--name&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;application elixir:1.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso facilita muito no manuseio, se você precisar executar um comando nesse container ou pausar, iniciar e remover ele, basta passar o nome selecionado ao invés do id. Por exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker start application

docker stop application

docker &lt;span class="nb"&gt;exec &lt;/span&gt;application &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executando o container em &lt;em&gt;detached&lt;/em&gt; mode usando a flag &lt;code&gt;-d&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;application &lt;span class="nt"&gt;-d&lt;/span&gt; elixir:1.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após a inicialização do container ele continua rodando em segundo plano, liberando o seu terminal. Provavelmente você vai usar muito essa flag. Você pode conferir o status atual do seu container com o comando &lt;code&gt;docker ps&lt;/code&gt; e ver que ele continua lá, rodando.&lt;/p&gt;

&lt;p&gt;Exponha uma porta de rede de seu container para que ele possa receber tráfego com a flag &lt;code&gt;--expose&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;application &lt;span class="nt"&gt;--expose&lt;/span&gt; 4000 &lt;span class="nt"&gt;-d&lt;/span&gt; elixir:1.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma o container deixa a porta &lt;code&gt;4000&lt;/code&gt; exposta para receber tráfego através dela. Provavelmente você vai expor a porta que sua aplicação está ouvindo. Ou você pode vincular com uma porta no seu &lt;code&gt;localhost&lt;/code&gt; para que toda vez que você faça um request para essa porta, por exemplo: &lt;code&gt;http://localhost:4000&lt;/code&gt; esse request seja encaminhado para o seu container.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;application &lt;span class="nt"&gt;-p&lt;/span&gt; 4000:4000 &lt;span class="nt"&gt;-d&lt;/span&gt; elixir:1.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A flag &lt;code&gt;-p 4000:4000&lt;/code&gt; indica que a porta &lt;code&gt;4000&lt;/code&gt; da sua máquina será encaminhada para a &lt;code&gt;4000&lt;/code&gt; do container. Resumindo &lt;code&gt;-p host_port:container_port&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;É importante entender a diferença entre o vinculo &lt;code&gt;-p&lt;/code&gt; e a exposição &lt;code&gt;--expose&lt;/code&gt; de portas do container&lt;/strong&gt;. Quando expomos uma porta do container, ela não está vinculada à nossa máquina, ela apenas está disponível para o request, dessa forma ao invés de fazer o request assim: &lt;code&gt;http://localhost:4000&lt;/code&gt; fazemos o request assim: &lt;code&gt;http://{container_ip}:4000&lt;/code&gt;. Demorei um tempo para entender isso!&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Gerenciando
&lt;/h3&gt;

&lt;p&gt;Quando um container está rodando é corriqueiro executarmos algumas operações nele durante o desenvolvimento. As vezes precisamos ver os logs da aplicação, modificar algum comportamento, checar alguma outra coisa, enfim... Problemas que aparecem durante o desenvolvimento.&lt;/p&gt;

&lt;p&gt;Vamos supor que criamos o container seguindo o exemplo do tópico anterior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--expose&lt;/span&gt; 4000 &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; application elixir:1.10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se quisermos ver os logs da aplicação que está sendo executada dentro do container, geralmente basta executar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executando esse comando todo o log que existe no seu container será exibido no seu terminal. Você pode aplicar a flag &lt;em&gt;follow&lt;/em&gt; &lt;code&gt;-f&lt;/code&gt;, isso fará com que o terminal fique "escutando" os logs e qualquer logs novos serão exibidos na sua tela.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs application &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Melhorando um pouco mais, podemos filtrar o output inicial desse comando com a quantidade de linhas que quiser ver. Fazemos isso com a flag &lt;code&gt;--tail=number&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker logs application &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;--tail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa forma seguimos os logs do container e será exibido somente as últimas 10 linhas.&lt;/p&gt;

&lt;p&gt;Outra operação muito comum é o "ssh login" nos containers. Para tal operação utilizamos o seguinte comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; application bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esse comando não faz um "ssh login". Na verdade ele vai modificar o input do seu terminal para que todos os comandos a seguir passem a rodar dentro do programa iniciado dentro do container, o &lt;code&gt;bash&lt;/code&gt; nesse caso. E também vincula o output do container ao seu terminal. Tudo isso é feito pelas flags &lt;code&gt;-it&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Você pode rodar comandos para o seu container sem essas flags. Algumas aplicações escrevem arquivos de logs ao invés de só exibi-los no terminal, para ler esses arquivos você poderia uilizar o &lt;code&gt;docker exec&lt;/code&gt; da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec &lt;/span&gt;application &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /path/to/log_file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora que temos um entendimento claro da diferença entre &lt;strong&gt;imagens&lt;/strong&gt; e &lt;strong&gt;containers&lt;/strong&gt; e de alguns comandos básicos, vamos falar sobre o &lt;em&gt;Docker Compose&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;center&gt;Parte 03 - Docker Compose não é Docker&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Pode parecer besteira, mas é importante ressaltar aqui que &lt;em&gt;Docker Compose&lt;/em&gt; e &lt;em&gt;Docker&lt;/em&gt; são coisas diferentes!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resumindo, o &lt;em&gt;Docker Compose&lt;/em&gt; é uma ferramenta de administração de containers&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Geralmente, no mundo de aplicações descentralizadas, os famosos &lt;em&gt;Micro Services&lt;/em&gt;, é comum que seu negócio esteja dividido em aplicações diferentes, as vezes em linguagens de programação diferentes. Por causa dessa separação, teoricamente, você precisaria de mais de uma imagem e mais de um container para que tudo funcione.&lt;/p&gt;

&lt;p&gt;Mesmo se sua aplicação for um monolito, a chance de você utilizar um banco de dados, web server, redis e outras tecnologias fora da sua aplicação é grande o que "força" você a dividir cada vez mais em containers e imagem menores que sejam responsáveis somente por uma tarefa.&lt;/p&gt;

&lt;p&gt;Então, se você tem uma aplicação monolítica, que se conecta a um banco de dados, o ideal seria ter um container com sua aplicação e outra com seu banco de dados, certo? Com o que vimos até agora você poderia criar esses dois containers rodando o &lt;code&gt;docker run&lt;/code&gt; com especificações um pouco diferentes.&lt;/p&gt;

&lt;p&gt;Mas vamos supor que além da aplicação e do banco de dados você também precise do Nginx. Ai você teria que criar mais um container. Percebe que começa a ficar complicado gerenciar esses containers "soltos" que estamos criando para nossa aplicação funcionar? Por causa dessa crescente complexidade você pode optar pelos seguintes cenários:&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Rodar todos os containers de forma independente
&lt;/h3&gt;

&lt;p&gt;Nesse cenário você sairia escrevendo &lt;code&gt;docker run&lt;/code&gt; no seu terminal como se não houvesse amanhã. Destruindo e modificando containers até que eles funcionem da maneira que você espera.&lt;/p&gt;

&lt;p&gt;Funciona, mas essa abordagem não é muito prática, imagina que para subir sua aplicação você tenha que iniciar cinco containers diferentes. Lá vai você &lt;code&gt;docker run ...&lt;/code&gt;, &lt;code&gt;docker run ...&lt;/code&gt;, &lt;code&gt;docker run ...&lt;/code&gt;, &lt;code&gt;docker run ...&lt;/code&gt; e por último &lt;code&gt;docker run ...&lt;/code&gt; com flags e imagens diferentes em cada comando... Acho que já deu preguiça em você só de pensar no trabalho desse método.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Agregar todas as tecnologias em uma única imagem
&lt;/h3&gt;

&lt;p&gt;Você poderia criar uma imagem que contenha todas as dependências do seu negócio. Parece interessante, certo?&lt;/p&gt;

&lt;p&gt;Mas imagine o tanto de configuração necessária no seu &lt;code&gt;Dockerfile&lt;/code&gt; para que você rode sua aplicação, seu banco de dados, seu web server e etc. Você acabaria tendo um &lt;code&gt;Dockerfile&lt;/code&gt; mega extenso e difícil de manter. Seria praticamente fazer o setup disso tudo no seu próprio computador. Bem cansativo também.&lt;/p&gt;

&lt;p&gt;Essa abordagem não é de todo o mal para ambientes de desenvolvimento ou homologação, mas imagine em um servidor de produção. Na AWS, por exemplo, você utilizar o seu banco de dados dentro de uma EC2 não parece uma boa ideia. Mas pode ser que você esteja usando &lt;em&gt;Docker&lt;/em&gt; só em desenvolvimento, nesse caso pode ser uma abordagem válida.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Criar um docker-compose.yml
&lt;/h3&gt;

&lt;p&gt;Essa provavelmente é a melhor abordagem para gerenciar vários containers dependentes. O arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt; é onde declaramos nossas instruções e o estado que cada container deve ser criado e operado bem como a comunicação entre eles.&lt;/p&gt;

&lt;p&gt;Esse tópico é um pouco extenso, vamos elaborar melhor ele na próxima parte deste artigo.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;center&gt;Parte 04 - Docker Compose&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Vimos que o &lt;em&gt;Docker Compose&lt;/em&gt; é uma ferramenta para gerenciar containers que tenham algum tipo de dependência entre si. Nós declaramos esses containers e seus parâmetros em um arquivo chamado &lt;code&gt;docker-compose.yml&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vamos supor que em uma empresa o negócio dela esteja dividido em três partes: Uma aplicação que utiliza o Phoenix (um &lt;em&gt;web framework&lt;/em&gt; feito com Elixir), um servidor web Nginx e um banco de dados Postgres.&lt;/p&gt;

&lt;p&gt;Dado esse cenário, vamos criar um &lt;code&gt;docker-compose.yml&lt;/code&gt; capaz de definir 3 containers diferentes para que cada tecnologia tenha seu próprio ambiente e sejam capazes de conversar entre si.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Criando o docker-compose.yml
&lt;/h3&gt;

&lt;p&gt;A primeira coisa que fazemos no arquivo é declarar os 3 containers que precisamos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.7"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mix&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;phx.server"&lt;/span&gt;

  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.17&lt;/span&gt;

  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:9.5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O bloco &lt;code&gt;version&lt;/code&gt; mostra pra gente qual versão do &lt;code&gt;docker-compose&lt;/code&gt; está sendo utilizada e o bloco &lt;code&gt;services&lt;/code&gt; declara os 3 containers necessários: app, nginx e postgres. Cada &lt;code&gt;service&lt;/code&gt; é um bloco indenpendente com as próprias declarações.&lt;/p&gt;

&lt;p&gt;No service &lt;code&gt;app&lt;/code&gt; temos duas declarações. A primeira é a &lt;code&gt;build: .&lt;/code&gt; essa declaração define que para construir esse container deve ser utilizado um &lt;code&gt;Dockerfile&lt;/code&gt; que deve estar no mesmo diretório que o arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt;. Por esse service representar o container da nossa aplicação, é comum que tenhamos um &lt;code&gt;Dockerfile&lt;/code&gt; que declara os recursos que precisamos em nossa imagem para que a aplicação rode corretamente.&lt;/p&gt;

&lt;p&gt;Nos demais services, nginx e postgres, nós substituímos a declaração &lt;code&gt;build&lt;/code&gt; pela declaração &lt;code&gt;image&lt;/code&gt;. Dessa forma ao invés de procurar outro &lt;code&gt;Dockerfile&lt;/code&gt; para construir uma imagem do Nginx e outro para construir a imagem do Postgres, nós utilizamos uma imagem pronta, fornecida pelo &lt;em&gt;Docker Hub&lt;/em&gt; que já possui essas duas tecnologias prontas para uso.&lt;/p&gt;

&lt;p&gt;Você poderia declarar &lt;code&gt;Dockerfiles&lt;/code&gt; diferentes para cada service, mas em nosso caso não é necessário, já que as imagens &lt;code&gt;nginx:1-17&lt;/code&gt; e a &lt;code&gt;postgres:9.5&lt;/code&gt; já tem tudo o que precisamos para as respectivas tecnologias.&lt;/p&gt;

&lt;p&gt;E a ultima declaração do &lt;code&gt;app&lt;/code&gt; é  a &lt;code&gt;command&lt;/code&gt;. Nela nós colocamos o valor &lt;code&gt;mix phx.server&lt;/code&gt;, que é um comando do Phoenix responsável por inicializá-lo. Assim, quando o container ficar pronto, esse comando será executado e nossa aplicação é iniciada dentro dele.&lt;/p&gt;

&lt;p&gt;Não utilizamos &lt;code&gt;command&lt;/code&gt; nos outros services pois as imagens que escolhemos já lidam com essa parte da inicialização do serviço dentro delas.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.2 Melhorando os serviços
&lt;/h3&gt;

&lt;h4&gt;
  
  
  4.2.1 App
&lt;/h4&gt;

&lt;p&gt;Além dos pedaços que já definimos no tópico anterior temos que nos preocupar com alguns outros aspectos da nossa aplicação e do nosso container. Precisamos expor a porta que nossa aplicação ouve, montar um "volume" que vai ligar os arquivos locais com os arquivos do container e também, por comodidade, definir um &lt;em&gt;working directory&lt;/em&gt; para facilitar a execução de alguns comandos da nossa aplicação.&lt;/p&gt;

&lt;p&gt;Para que todos os requisitos sejam atendidos, modificamos o bloco &lt;code&gt;app&lt;/code&gt; da seguinte forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/application/&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/www/application/"&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4000"&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mix&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;phx.server"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como vimos anteriormente &lt;code&gt;expose&lt;/code&gt; expõe a porta &lt;code&gt;4000&lt;/code&gt; do container para que ela receba tráfego. &lt;code&gt;working_dir&lt;/code&gt; define que o path que passamos à ela, &lt;code&gt;/var/www/application/&lt;/code&gt; daqui pra frente seja o diretório padrão onde os comandos serão executados. Então quando o container for executar o &lt;code&gt;mix phx.server&lt;/code&gt; ou qualquer outro comando passado à ele, ele vai executar no diretório &lt;code&gt;/var/www/application/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O &lt;code&gt;container_name&lt;/code&gt; é basicamente isso, estamos definindo um nome para nosso container.&lt;/p&gt;

&lt;p&gt;E por últimos temos o &lt;code&gt;volume&lt;/code&gt;, essa declaração faz uma "ligação" com o diretório da sua máquina (host) com o diretório do container. Então, nós estamos "ligando" o diretório em que o &lt;code&gt;docker-compose.yml&lt;/code&gt; está &lt;code&gt;./&lt;/code&gt; com o diretório &lt;code&gt;/var/www/application/&lt;/code&gt; dentro do container. Dessa forma todos os arquivos que tem em um diretório aparecerá no outro.&lt;/p&gt;

&lt;h4&gt;
  
  
  4.2.2 Nginx e Postgres
&lt;/h4&gt;

&lt;p&gt;Para concluir a definição do nosso &lt;code&gt;docker-compose.yml&lt;/code&gt; vamos complementar os serviços restantes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.17&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nginx"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx:/etc/nginx/conf.d&lt;/span&gt;
    &lt;span class="s"&gt;ports:t&lt;/span&gt;
      &lt;span class="s"&gt;- "80:80"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionamos o &lt;code&gt;volume&lt;/code&gt;, que colocará os arquivos de configuração do Nginx dentro do caminho correto do container. E por último adicionamos o &lt;code&gt;port&lt;/code&gt; que vai vincular o nosso &lt;code&gt;localhost&lt;/code&gt; ao container do &lt;code&gt;nginx&lt;/code&gt;. Dessa forma, sempre que fazemos um request &lt;code&gt;http://localhost&lt;/code&gt;, ele será encaminhado para o container do &lt;code&gt;nginx&lt;/code&gt; que, por sua vez, encaminhará o request para o container &lt;code&gt;app&lt;/code&gt;, conforme dita as configurações nos arquivos dentro da pasta&lt;code&gt;./nginx&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;E por último, completamos a definição do Postgres&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:9.5&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgres"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./postgres:/var/lib/postgres&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=your_db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER=your_user&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=your_secret&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A única descrição nova aqui é a &lt;code&gt;environment&lt;/code&gt;. Com ela você adiciona &lt;em&gt;env variables&lt;/em&gt; ao seu container. As três variáveis que adicionamos servem para o Postgres configurar um banco de dados, usuário e senha.&lt;/p&gt;

&lt;p&gt;Vinculamos as &lt;code&gt;ports&lt;/code&gt; do Postgres com o host para facilitar a conexão ao container do banco de dados. Dessa forma, se você possui algum programa para gerenciar banco de dados, por exemplo, facilita a conexão com esse container.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.3 Completando o docker-compose.yml
&lt;/h3&gt;

&lt;p&gt;Se você seguiu esse guia até agora, a versão final do seu &lt;code&gt;docker-compose.yml&lt;/code&gt; será assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.7"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/application/&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/www/application/"&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4000"&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;mix&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;phx.server"&lt;/span&gt;

  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.17&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nginx"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./nginx:/etc/nginx&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;

  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:9.5&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgres"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./postgres:/var/lib/postgres&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=your_db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER=your_user&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=your_secret&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Agora que temos o nosso arquivo do &lt;code&gt;docker-compose&lt;/code&gt; configurado, vamos ver como utilizá-lo!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;center&gt;Parte 05 - Usando o Docker Compose&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;No tópico anterior definimos um &lt;code&gt;docker-compose.yml&lt;/code&gt; com três containers para nossa aplicação ser executada, porém para que tudo funcione nesse momento, vamos fazer pequenas alterações na declaração do nosso serviço &lt;code&gt;app&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;elixir:1.10&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/application/&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/www/application/"&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4000"&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como não temos uma aplicação Phoenix pronta para rodar o comando &lt;code&gt;mix phx.server&lt;/code&gt; não vai funcionar e nosso container não conseguirá subir.&lt;/p&gt;

&lt;p&gt;Substituímos por um container criado a partir de uma image padrão de Elixir &lt;code&gt;elixir:1.10&lt;/code&gt; e trocamos a declaração &lt;code&gt;command&lt;/code&gt; por &lt;code&gt;tty&lt;/code&gt;. A declaração &lt;code&gt;tty&lt;/code&gt; faz com que o container fique em execução em segundo plano mesmo se nenhum comando for executado, o que é justamente o que queremos.&lt;/p&gt;

&lt;p&gt;Outra modificação que precisamos fazer é remover o &lt;code&gt;volume&lt;/code&gt; do serviço &lt;code&gt;nginx&lt;/code&gt;. Como não temos aplicação rodando, não precisamos configurar o Nginx para rotear o tráfego para o container desejado.&lt;/p&gt;

&lt;p&gt;Resumindo, o novo &lt;code&gt;docker-compose.yml&lt;/code&gt; fica assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.7"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;elixir:1.10&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./:/var/www/application/&lt;/span&gt;
    &lt;span class="na"&gt;working_dir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/var/www/application/"&lt;/span&gt;
    &lt;span class="na"&gt;expose&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;4000"&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;

  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:1.17&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nginx"&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;80:80"&lt;/span&gt;

  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres:9.5&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgres"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./postgres:/var/lib/postgres&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_DB=your_db&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_USER=your_user&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=your_secret&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Feito isso podemos colocar todos esses containers para rodar com o comando&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O &lt;em&gt;Docker&lt;/em&gt; vai validar nosso arquivo &lt;code&gt;yml&lt;/code&gt; e se tudo estiver ok vai começar a procurar as imagens que nossos containers precisam para serem executados. Aqui nós também adicionamos a flag &lt;code&gt;-d&lt;/code&gt; para que nosso terminal seja liberado após a conclusão desse comando.&lt;/p&gt;

&lt;p&gt;A primeira vez que você executa esse comando em um projeto pode demorar um pouco. O &lt;em&gt;Docker&lt;/em&gt; precisa preparar todas as imagens que esses containers utilizarão e dependendo da sua internet ou do seu computador essa etapa pode levar alguns minutos.&lt;/p&gt;

&lt;p&gt;Feito isso o &lt;em&gt;Docker&lt;/em&gt; começa a criar os containers na ordem e inicializá-los. E se tudo correu bem você pode listar os containers criados com &lt;code&gt;docker ps&lt;/code&gt;. O output desse comando mostra todos os containers que estão em execução, adiciona a flag &lt;code&gt;-a&lt;/code&gt; para ver todos os containers que existe na sua máquina.&lt;/p&gt;

&lt;p&gt;Deixo abaixo uma lista com os comandos mais corriqueiros do &lt;em&gt;Docker Compose&lt;/em&gt;:&lt;/p&gt;

&lt;p&gt;Parando todos os containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose stop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Removendo todos os containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vendo o log de todos os containers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose logs &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Construir os containers sem inicializá-los:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vale ressaltar que os containers criados pelo comando &lt;code&gt;docker-compose&lt;/code&gt; são "comuns", sendo assim os outros comandos de &lt;em&gt;Docker&lt;/em&gt; também são válidos. Você pode até parar e retomar a execução de um container em específico.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;center&gt;Parte 06 - Interação entre Containers&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Teoricamente, todos os containers que criamos no tópico anterior fazem parte da mesma aplicação e por isso precisam se comunicar. Quando criamos containers utilizando o &lt;code&gt;docker-compose&lt;/code&gt;, além dos containers, outras entidades são criadas. Uma das mais importantes é a &lt;strong&gt;&lt;em&gt;Network&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Na versão &lt;code&gt;2.x&lt;/code&gt; todos os containers de todos os arquivos &lt;code&gt;docker-compose.yml&lt;/code&gt; que eram criados se juntavam em uma mesma &lt;code&gt;network&lt;/code&gt; com nome &lt;code&gt;default&lt;/code&gt;. Na versão &lt;code&gt;3.x&lt;/code&gt; esse comportamento mudou, de modo que cada arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt; tem sua própria &lt;code&gt;network&lt;/code&gt;. O &lt;code&gt;docker-compose&lt;/code&gt; nomeia a &lt;code&gt;network&lt;/code&gt; do arquivo &lt;code&gt;docker-compose.yml&lt;/code&gt; utilizando o nome do diretório concatenado com a string &lt;code&gt;_default&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O tópico de &lt;code&gt;network&lt;/code&gt; do &lt;em&gt;Docker&lt;/em&gt; é muito extenso para esse artigo, então vou deixar ele para um post dedicado. O que você precisa saber aqui é que na versão &lt;code&gt;3.x&lt;/code&gt; do &lt;code&gt;docker-compose&lt;/code&gt; a &lt;code&gt;network&lt;/code&gt; é definida por arquivos &lt;code&gt;docker-compose.yml&lt;/code&gt; e um container de fora desse arquivo, por padrão, não se comunica com os que estão definidos nele. É possível conectá-lo à &lt;code&gt;network&lt;/code&gt;, mas não está no escopo deste artigo.&lt;/p&gt;

&lt;p&gt;Enfim, todos os nossos containers fazem parte da mesma &lt;code&gt;network&lt;/code&gt; e por isso a comunicação entre eles é muito fácil. O &lt;em&gt;Docker&lt;/em&gt; facilita nossa vida fornecendo um "DNS" para os containers da mesma rede. Vamos utilizar o container do Postgres como exemplo. Para a nossa aplicação usar o container do postgres, tudo o que precisamos fazer é colocar o &lt;strong&gt;nome do container no host do nosso banco de dados na aplicação&lt;/strong&gt;. Simples assim!&lt;/p&gt;

&lt;p&gt;Não se esqueça que outros parâmetros de rede também são importantes. Certifique-se de que a porta correta esteja exposta (&lt;code&gt;expose&lt;/code&gt;) no container desejado e que o request está sendo enviado para aquela porta!&lt;/p&gt;




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

&lt;p&gt;Espero ter ajudado você na compreensão dessa ótima ferramenta de desenvolvimento! Lidar com o &lt;em&gt;Docker&lt;/em&gt; pode ser complicado no começo, mas é uma excelente ferramenta para cuidar de um pedaço muito importante da aplicação que geralmente deixamos passar: &lt;strong&gt;A Infraestrutura!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Eu acho que o &lt;em&gt;Docker&lt;/em&gt; lida com esse lado de nosso trabalho de forma primorosa, possibilitando e facilitando muito do nosso dia-a-dia! Por isso, é uma ferramenta que vale muito a pena!&lt;/p&gt;

&lt;p&gt;Obrigado pelo seu tempo e até a próxima 🖖&lt;/p&gt;

</description>
      <category>docker</category>
      <category>beginners</category>
      <category>ptbr</category>
    </item>
    <item>
      <title>Learning Elixir with PHP help</title>
      <dc:creator>Leoni Mella</dc:creator>
      <pubDate>Tue, 18 Feb 2020 12:00:24 +0000</pubDate>
      <link>https://dev.to/ingresse/learning-elixir-with-php-help-47mn</link>
      <guid>https://dev.to/ingresse/learning-elixir-with-php-help-47mn</guid>
      <description>&lt;p&gt;🇧🇷 &lt;em&gt;Artigo original em português: &lt;a href="https://dev.to/leonimella/entendendo-elixir-com-ajuda-de-php-20n2"&gt;Entendendo Elixir com a ajuda de PHP&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After some years and differents experiences with PHP and some frameworks like WordPress, Laravel, Symfony and Phalcon, I had the opportunity to work with Elixir and since then it has been my go to language for new projects.&lt;/p&gt;

&lt;p&gt;For those who have never had a previous experience with a functional language this first contact could be a little confusing, that was my case when I first start with Elixir.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The "help" offered in this article by PHP it's just a merely comparison made between the two languages, which by the way are NOTHING similar.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article I've just implemented the same functionalities using both languages so you can compare the &lt;strong&gt;logic&lt;/strong&gt; of a new programming paradigm with a more familiar one offered by PHP.&lt;/p&gt;

&lt;p&gt;I will approach the Elixir functionalities that I most use on a daily basis applying the 80/20 rule, but I'm sure that with this simple knowledge you can read a &lt;code&gt;.ex&lt;/code&gt; or &lt;code&gt;.exs&lt;/code&gt; file and don't lose yourself on the way.&lt;/p&gt;

&lt;h4&gt;
  
  
  Before we begin...
&lt;/h4&gt;

&lt;p&gt;If you don't know Elixir at all I suggest that you read at least the &lt;a href="https://elixir-lang.org/getting-started/introduction.html"&gt;&lt;em&gt;Starting Guide&lt;/em&gt;&lt;/a&gt; on their docs. It will show the syntax, the primitives types and operators of the language.&lt;/p&gt;

&lt;p&gt;Without further ado, let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;Pattern Matching&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;The best &lt;em&gt;pattern matching&lt;/em&gt; definition is the following:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pattern matching is a powerful part of Elixir. It allows us to match simple values, data structures, and even functions - &lt;a href="https://elixirschool.com/en/lessons/basics/pattern-matching/"&gt;Elixir School&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what exactly does this mean? To better understand this we need to take a look at the &lt;em&gt;match operator&lt;/em&gt; &lt;code&gt;=&lt;/code&gt;. This operator can attribute values to variables and can be used to decompose more complex structures, like tuples and lists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iex&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;a, b, c&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;, &lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;, &lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;, &lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;, &lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; a
&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; b
&lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; c
&lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;

&lt;span class="c"&gt;# Another example&lt;/span&gt;
iex&lt;span class="o"&gt;(&lt;/span&gt;5&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;_, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, country&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Brasil"&lt;/span&gt;, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, &lt;span class="s2"&gt;"Chile"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Brasil"&lt;/span&gt;, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, &lt;span class="s2"&gt;"Chile"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;6&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; country
&lt;span class="s2"&gt;"Chile"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, you can fetch the first item of a list&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iex&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Olá"&lt;/span&gt;, &lt;span class="s2"&gt;"Hello"&lt;/span&gt;, &lt;span class="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Olá"&lt;/span&gt;, &lt;span class="s2"&gt;"Hello"&lt;/span&gt;, &lt;span class="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;span class="s2"&gt;"Olá"&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;tail&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Hello"&lt;/span&gt;, &lt;span class="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Case a tuple can't be match against the left hand side of the operator, that means, maybe a tuple don't have the same number of fields or the same expected value of the left side of the &lt;code&gt;=&lt;/code&gt; a exception will occur:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iex&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;a, b&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;, &lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;, &lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# ** (MatchError) no match of right hand side value: {"São Paulo", "Rio de Janeiro", "Fortaleza"}&lt;/span&gt;
&lt;span class="c"&gt;#    (stdlib) erl_eval.erl:453: :erl_eval.expr/5&lt;/span&gt;
&lt;span class="c"&gt;#    ...&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;_, &lt;span class="s2"&gt;"United States"&lt;/span&gt;, country&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Brasil"&lt;/span&gt;, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, &lt;span class="s2"&gt;"Chile"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# ** (MatchError) no match of right hand side value: {"Brasil", "Ecuador", "Chile"}&lt;/span&gt;
&lt;span class="c"&gt;#    (stdlib) erl_eval.erl:453: :erl_eval.expr/5&lt;/span&gt;
&lt;span class="c"&gt;#    ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code gave us an understanding of the first half of the &lt;em&gt;pattern matching&lt;/em&gt; definition. What about the other half that allow us to look for patterns in functions definitions? Let's take a look:&lt;/p&gt;

&lt;p&gt;To help with this part I'll create a PHP class so you can compare with the equivalent Elixir module. To start with let's just create a class and module that have a &lt;code&gt;hello/1&lt;/code&gt; function that receive the &lt;code&gt;user_name&lt;/code&gt; as parameter.&lt;/p&gt;

&lt;p&gt;PHP class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Elixir module&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far, so good, right? We have a &lt;code&gt;hello/1&lt;/code&gt; function that will print "Hello, Joe" both in PHP class and in Elixir module.&lt;/p&gt;

&lt;p&gt;But let's assume that the &lt;code&gt;user_name&lt;/code&gt; parameter could be &lt;code&gt;nil&lt;/code&gt; (&lt;code&gt;null&lt;/code&gt; in PHP). How can we adjust our code to attend this requirement?&lt;/p&gt;

&lt;p&gt;PHP class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&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="nb"&gt;is_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello world!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using PHP we could add a default value to the &lt;code&gt;$userName&lt;/code&gt; and handle this with a &lt;code&gt;if&lt;/code&gt; statement inside our function in case &lt;code&gt;$userName&lt;/code&gt; is really &lt;code&gt;null&lt;/code&gt; and display a different message.&lt;/p&gt;

&lt;p&gt;If execute &lt;code&gt;GreetUser.php&lt;/code&gt; we would get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s2"&gt;"Hello, Joe"&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;Although the same solution is possible in Elixir, we can use &lt;em&gt;pattern matching&lt;/em&gt; and remove the complexity of the code from our function by get rid of the &lt;code&gt;if&lt;/code&gt; statement:&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&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="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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As there are two functions with the same name, the chosen one will be the one that has the correct parameter value.&lt;/p&gt;

&lt;p&gt;This means that only when &lt;code&gt;user_name = nil&lt;/code&gt; the first function will be executed, in any other case it will skip this function definition and go to the next &lt;code&gt;hello/1&lt;/code&gt; declared within this module.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's important to say that due to function arity &lt;code&gt;GreetUser.hello(nil)&lt;/code&gt; is different then &lt;code&gt;GreetUser.hello()&lt;/code&gt;. In the former we would call &lt;code&gt;hello/1&lt;/code&gt; and the last we would call &lt;code&gt;hello/0&lt;/code&gt; which does not exists and would break. &lt;strong&gt;Always have the arity in mind&lt;/strong&gt;!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Any primitive of the language can be used in &lt;em&gt;pattern matching&lt;/em&gt;. So let's assume that the &lt;code&gt;GreetUser&lt;/code&gt; module now have to greet a specific message to users that have the name &lt;code&gt;"Jane"&lt;/code&gt;, we could achieve this by doing this:&lt;/p&gt;

&lt;p&gt;PHP Class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&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="nv"&gt;$userName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;"Jane"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Nice to see you, Jane!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Jane"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Elixir Module&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Jane"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_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;"Nice to see you, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Jane"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This time we specified the &lt;code&gt;user_name&lt;/code&gt; value and add the &lt;em&gt;match operator&lt;/em&gt; to the parameter: &lt;code&gt;("Jane" = user_name)&lt;/code&gt;. By doing this we are matching &lt;code&gt;user_name&lt;/code&gt; to &lt;code&gt;"Jane"&lt;/code&gt; and them we can use the variable inside our function. If you don't want to use the parameter inside your function you can dismiss it by prepending it with an &lt;em&gt;underscore&lt;/em&gt;: &lt;code&gt;("Jane" = _user_name)&lt;/code&gt;. Elixir understand that this variable will never be used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Declared variables that are not used will raise a warning in compilation time, keep that in mind!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I hope that with this example you began to see how &lt;em&gt;pattern matching&lt;/em&gt; can remove complexity away from our code. Doesn't Elixir module look more simple and better to read than the class in PHP? We no longer have to "calculate" &lt;code&gt;if&lt;/code&gt;s statement to know what a function will return, pretty good, right?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;Guards&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;If you enjoy the wonders of &lt;em&gt;pattern matching&lt;/em&gt; you can go beyond using &lt;em&gt;guards&lt;/em&gt;. It will allow you to make more complex parameter validation in your functions declaration.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Guards&lt;/em&gt; are defined using a &lt;code&gt;when&lt;/code&gt; after a function declaration. While &lt;em&gt;pattern matching&lt;/em&gt; is useful to check explicit values, with &lt;em&gt;guards&lt;/em&gt; we can apply some boolean logic to it. We can check a parameter's type, length, if it is &lt;code&gt;nil&lt;/code&gt;, if it is higher or lower given a determined number and some others validations.&lt;/p&gt;

&lt;p&gt;Back to our &lt;code&gt;GreetUser&lt;/code&gt;, we will use &lt;em&gt;guard&lt;/em&gt; to validate if &lt;code&gt;user_name&lt;/code&gt; is a &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Elixir module&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;is_binary/1&lt;/code&gt; function will return a boolean value and according to it (&lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;) &lt;code&gt;hello/1&lt;/code&gt; get invoked or not. Elixir has several &lt;a href="https://hexdocs.pm/elixir/Kernel.html#is_atom/1"&gt;type-checks&lt;/a&gt;” functions like this so you can check a expression type.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Here is a tip. Either using a &lt;em&gt;pattern matching&lt;/em&gt; or &lt;em&gt;guard&lt;/em&gt; it's always a good practice to at least think about a alternative in case of a parameter mismatch. You could get a runtime error if a parameter won't match a function&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;** (FunctionClauseError) no function clause matching in GreetUser.hello/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above error will happen if we call &lt;code&gt;hello/1&lt;/code&gt; with an integer: &lt;code&gt;GreetUser.hello(1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As an alternative we could add another declaration of &lt;code&gt;hello/1&lt;/code&gt; just dismissing the parameter, so everything that is not a &lt;code&gt;string&lt;/code&gt; will be direct to it:&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;_&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;"Only string is allowed in this function"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Important!
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;The function declaration order is extremely important!!&lt;/strong&gt;&lt;br&gt;
In the above example we restrict &lt;code&gt;hello/1&lt;/code&gt; to only accept &lt;code&gt;string&lt;/code&gt;. No problem there, but what if we had reversed the function declaration orders by placing &lt;code&gt;hello(_)&lt;/code&gt; before the &lt;code&gt;hello(user_name) when is_binary(user_name)&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&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="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;"Only string is allowed in this function"&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;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the code we would get the following:&lt;br&gt;
    warning: this clause cannot match because a previous clause at line 5 always matches&lt;/p&gt;

&lt;p&gt;Our code still run with no errors, but &lt;code&gt;hello/1&lt;/code&gt; with the &lt;em&gt;guard&lt;/em&gt; &lt;code&gt;when is_binary/1&lt;/code&gt; would never be called because &lt;code&gt;hello/1&lt;/code&gt; without the guard will &lt;strong&gt;ALWAYS&lt;/strong&gt; be evaluated first! &lt;strong&gt;So pay attention to function's declaration order&lt;/strong&gt;!!&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;center&gt;Pipe Operator&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;This one is a bit trick, but in a nutshell the &lt;em&gt;pipe operator&lt;/em&gt; is represented by the symbol &lt;code&gt;|&amp;gt;&lt;/code&gt; and all that it does is pass an expression evaluation (or result) as the first parameter to the next one.&lt;/p&gt;

&lt;p&gt;With this you can create a function &lt;em&gt;pipeline&lt;/em&gt; (get the name?) given a expression (variable or function).&lt;/p&gt;

&lt;p&gt;To illustrate this concept, now &lt;code&gt;GreetUser&lt;/code&gt; has a new requirement, we'll need to greet some users which their names will came in a list. To do that we'll create another function named &lt;code&gt;hello_group/1&lt;/code&gt;. This new function will receive the list of names as &lt;code&gt;users_name&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c1"&gt;# code&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_group&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="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;"Only lists are allowed"&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;We declared the function and added a &lt;em&gt;guard&lt;/em&gt; so we can validate that the parameter is indeed a list, and defined a "default" &lt;code&gt;hello_group/1&lt;/code&gt; in the chance that &lt;code&gt;users_name&lt;/code&gt; is not a list.&lt;/p&gt;

&lt;p&gt;The next step it's to handle the &lt;code&gt;users_name&lt;/code&gt; using the &lt;em&gt;pipe operator&lt;/em&gt;. First we'll go through the list and normalize the names. The first part can be achieve using the &lt;code&gt;map/2&lt;/code&gt; function from Elixir's &lt;code&gt;Enum&lt;/code&gt; module.&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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_group&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="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;"Only lists are allowed"&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;Let's breakdown this code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We called &lt;code&gt;users_name&lt;/code&gt; inside our function&lt;/li&gt;
&lt;li&gt;Then we added the &lt;code&gt;|&amp;gt;&lt;/code&gt; (&lt;em&gt;pipe operator&lt;/em&gt;) bellow &lt;code&gt;users_name&lt;/code&gt;. It could be called by the right side as well.&lt;/li&gt;
&lt;li&gt;To loop the list, we use the &lt;code&gt;map/2&lt;/code&gt;, that will return another list.&lt;/li&gt;
&lt;li&gt;As &lt;code&gt;map/2&lt;/code&gt; second parameter we gave a anonymous function &lt;code&gt;fn user_name -&amp;gt; ... end&lt;/code&gt; that will be executed for each element on the list&lt;/li&gt;
&lt;li&gt;Inside the anonymous function we called the &lt;a href="https://hexdocs.pm/elixir/String.html#capitalize/2"&gt;&lt;code&gt;capitalize/2&lt;/code&gt;&lt;/a&gt; from Elixir &lt;code&gt;String&lt;/code&gt; module to capitalize the names.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The bit that you need understand is that we pass only &lt;code&gt;map/2&lt;/code&gt; second parameter because the first parameter is passed by the &lt;code&gt;|&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Remember: "The &lt;em&gt;pipe operator&lt;/em&gt; forwards the result of an expression as the first parameter on to the next expression". In our case the first expression is the variable &lt;code&gt;users_name&lt;/code&gt; and when it gets evaluated will return the list of names. And our pipeline worked because &lt;code&gt;map/2&lt;/code&gt; expected as the first parameter a list!&lt;/p&gt;

&lt;p&gt;Using PHP we could achieve the same with this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Only arrays are allowed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameNormalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;ucfirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$usersName&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;The next step is to "glue" all the names in a single &lt;code&gt;string&lt;/code&gt;. We'll use &lt;code&gt;join/2&lt;/code&gt; which is another function from &lt;code&gt;Enum&lt;/code&gt; module. This function will receive in the first parameter a list and in the second parameter receives a string as the joiner element. We'll use just a &lt;code&gt;", "&lt;/code&gt; to separate the names.&lt;/p&gt;

&lt;p&gt;Elixir module&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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;join&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;end&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello_group&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="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;"Only lists are allowed"&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;PHP class&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Only arrays are allowed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameNormalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;ucfirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&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="nv"&gt;$usersNameNormalized&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;Our pipeline still functions because &lt;code&gt;map/2&lt;/code&gt; will return a new list and the &lt;code&gt;|&amp;gt;&lt;/code&gt; forwards it as the first parameter to the &lt;code&gt;join/2&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Great! &lt;code&gt;hello_group/1&lt;/code&gt; is able to normalize and glue together the names. Now we just need to print a message to the user.&lt;/p&gt;

&lt;p&gt;So far the result of &lt;code&gt;hello_group/1&lt;/code&gt; would be a string with the users names. We could use &lt;code&gt;hello/1&lt;/code&gt;, which receives a string as first parameter to print the message to our user.&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;_&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;"Only strings are allowed"&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_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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;join&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&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_group&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="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;"Only lists are allowed"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello_group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By adding &lt;code&gt;hello/1&lt;/code&gt; in the pipeline we fulfill all the requirements for &lt;code&gt;hello_group/1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Take a look at the same feature in PHP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Only arrays are allowed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameNormalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;ucfirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nv"&gt;$usersName&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&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="nv"&gt;$usersNameNormalized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersNameString&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We could make the above code better by splitting in different functions, but do notice that even if we make such change the code in Elixir has a LOT more readability and less complexity.&lt;/p&gt;

&lt;p&gt;Here is another way to visualize the same code without using the &lt;em&gt;pipe operator&lt;/em&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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;join&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&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_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:notpiped&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;hello&lt;/span&gt;&lt;span class="p"&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;join&lt;/span&gt;&lt;span class="p"&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;users_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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="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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello_group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello_group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;:notpiped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we defined another function: &lt;code&gt;hello_group/2&lt;/code&gt;, despite the arity, both functions will return the same result.&lt;br&gt;
But &lt;code&gt;hello_group/1&lt;/code&gt; is cleaner and easier to understand.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;center&gt;Control Structures&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;In Elixir we have access to certain tools that allow us to remove complexity from our code, but sometimes we have no other option and we have to use a &lt;code&gt;if&lt;/code&gt; or a &lt;code&gt;switch&lt;/code&gt;.&lt;br&gt;
The control structures available to us are: &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;unless&lt;/code&gt;, &lt;code&gt;case&lt;/code&gt;, &lt;code&gt;cond&lt;/code&gt; and &lt;code&gt;with&lt;/code&gt;. This article is an overview of the language and because of that I'm not write about all this structures. I'll focus in the &lt;code&gt;with&lt;/code&gt; because this one can be harder to understand than the others.&lt;/p&gt;

&lt;p&gt;The first thing that we need to understand is that in a functional language the result of a function is always the result of the last expression that get executed, we don't have the &lt;code&gt;return&lt;/code&gt; keyword in this functional world. Because of this, control structures will return the result of the last expression, so you need to be careful when write them. This can be challenging at first, but you get used to it quite fast.&lt;/p&gt;

&lt;p&gt;In a functional language we cannot do some like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;anotherFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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="nv"&gt;$condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PHP"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$param&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;In the above PHP code we are defining a default value to &lt;code&gt;$param&lt;/code&gt; and based on &lt;code&gt;$condition&lt;/code&gt;'s his value will change. This wouldn't work in a Elixir code because de &lt;code&gt;if&lt;/code&gt; is an expression! If this was an &lt;code&gt;Elixir&lt;/code&gt; code, all that this if expression was doing is to match &lt;code&gt;$param&lt;/code&gt; to &lt;code&gt;"PHP"&lt;/code&gt;, and the return of this expression would be an &lt;code&gt;:ok&lt;/code&gt; atom. The &lt;code&gt;$param&lt;/code&gt; variable would never match &lt;code&gt;"PHP"&lt;/code&gt; outside the &lt;code&gt;if&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;To this work in Elixir, one could do as the following:&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;another_function&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="s2"&gt;"Elixir"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="no"&gt;nil&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;By doing this, the &lt;strong&gt;return&lt;/strong&gt; of the &lt;code&gt;if&lt;/code&gt; would be matched to the &lt;code&gt;param&lt;/code&gt; variable.&lt;br&gt;
With that in mind, let's move on.&lt;/p&gt;
&lt;h2&gt;
  
  
  With
&lt;/h2&gt;

&lt;p&gt;You can think in &lt;code&gt;with&lt;/code&gt; like a pipeline that checks the result of each expression and if some of those return an unexpected value the code inside the &lt;code&gt;with&lt;/code&gt; block won't get executed. You can also add fallback clausules to handle some unexpected behaviour or errors.&lt;/p&gt;

&lt;p&gt;Let's add this structure in our &lt;code&gt;hello/1&lt;/code&gt; function and see how it works:&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;dummy_function&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="ss"&gt;:ok&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;user_name&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;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We created an &lt;code&gt;dummy_function/0&lt;/code&gt; that will only return an &lt;code&gt;:ok&lt;/code&gt; atom and we added an &lt;code&gt;with&lt;/code&gt; block to check the returned value. If the returned value was indeed an &lt;code&gt;:ok&lt;/code&gt; atom, them we print &lt;code&gt;"Hello, Joe"&lt;/code&gt; on the screen.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;dummy_function/0&lt;/code&gt; won't return an &lt;code&gt;:ok&lt;/code&gt; we could add a fallback clausule to handle this:&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;dummy_function&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="ss"&gt;:error&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;user_name&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;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;else&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;"dummy_functtion didn't return an :ok atom"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can match variables and other structures on the left side of the &lt;code&gt;&amp;lt;-&lt;/code&gt; operator, so we can use the value returned by the function inside de &lt;code&gt;with&lt;/code&gt; block:&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;dummy_function&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="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="s2"&gt;"dummy function"&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&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;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="n"&gt;_response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;else&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;message&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;"dummy_functtion return an error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&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="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;"I can't figure what dummy_function has returned"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We checked if &lt;code&gt;dummy_function/0&lt;/code&gt; will return an &lt;code&gt;{:ok, response}&lt;/code&gt; result, if it does the function proceed and print the greeting. If &lt;code&gt;dummy_function/0&lt;/code&gt; returns an &lt;code&gt;{:error, message}&lt;/code&gt; it prints the message with the error. And at last if &lt;code&gt;dummy_function/0&lt;/code&gt; returns something unexpected the last clausule, which matches everything, will be executed printing the generic error message. The last clausule will not match on the other cases (&lt;code&gt;{:ok, response}&lt;/code&gt; and &lt;code&gt;{:error, message}&lt;/code&gt;) because the others two clausules will match first, remember, &lt;strong&gt;the declaration other matter&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;With this knowledge we can create an &lt;em&gt;pipeline&lt;/em&gt; of functions that will be validated in each step and handle any possible error individually:&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;user_name&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;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="n"&gt;response1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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;_response2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reponse1&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;else&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;message&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;"dummy_functtion return an error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&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="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;"I can't figure what dummy_function has returned"&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;h2&gt;
  
  
  &lt;center&gt; And there you have it!&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;If you can wrap your mind around these Elixir's concepts I'm guarantee that you will have the basic knowledge to handle quite some understanding of an Elixir's code.&lt;/p&gt;

&lt;p&gt;Here are some topics for you to get deeper into the language and its ecosystem&lt;/p&gt;

&lt;h4&gt;
  
  
  Mix
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Task runner&lt;/em&gt; (similar to &lt;em&gt;composer&lt;/em&gt; on PHP), link to the &lt;a href="https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html"&gt;guide&lt;/a&gt; and &lt;a href="https://hexdocs.pm/mix/Mix.html"&gt;docs&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Phoenix
&lt;/h4&gt;

&lt;p&gt;Web framework (similar to &lt;em&gt;Symfony&lt;/em&gt;, &lt;em&gt;Laravel&lt;/em&gt;, etc... on PHP), link to the &lt;a href="https://www.phoenixframework.org/"&gt;site&lt;/a&gt; and &lt;a href="https://hexdocs.pm/phoenix/Phoenix.html"&gt;docs&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ecto
&lt;/h4&gt;

&lt;p&gt;ORM (similar to &lt;em&gt;Doctrine&lt;/em&gt; on php), link to the &lt;a href="https://elixirschool.com/pt/lessons/ecto/basics/"&gt;guide&lt;/a&gt; and &lt;a href="https://hexdocs.pm/ecto/Ecto.html"&gt;docs&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Hex
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Package repository&lt;/em&gt; (similar to &lt;em&gt;Packgist&lt;/em&gt; of &lt;em&gt;Composer&lt;/em&gt;), link to the &lt;a href="https://hex.pm/"&gt;site&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt; References &lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;And here, some usefull links and references that I used to write this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Official website: &lt;a href="https://elixir-lang.org/"&gt;https://elixir-lang.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elixir School: &lt;a href="https://elixirschool.com/pt/"&gt;https://elixirschool.com/pt/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tiny documentary of the language: &lt;a href="https://www.youtube.com/watch?v=lxYFOM3UJzo"&gt;https://www.youtube.com/watch?v=lxYFOM3UJzo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Elixir lang on twitter: &lt;a href="https://twitter.com/elixirlang"&gt;https://twitter.com/elixirlang&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I hope that you enjoyed read this article and that was useful to you. If you have any suggestion or feedback leave a comment. This is one of my first articles and I would like to know how I'm doing 😁&lt;/p&gt;

&lt;p&gt;Thank you for your time! See you soon 🖖&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>php</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Entendendo Elixir com ajuda de PHP</title>
      <dc:creator>Leoni Mella</dc:creator>
      <pubDate>Thu, 30 Jan 2020 16:32:31 +0000</pubDate>
      <link>https://dev.to/ingresse/entendendo-elixir-com-ajuda-de-php-20n2</link>
      <guid>https://dev.to/ingresse/entendendo-elixir-com-ajuda-de-php-20n2</guid>
      <description>&lt;p&gt;🇬🇧 &lt;em&gt;Would you like to read this article in english? &lt;a href="https://dev.to/leonimella/learning-elixir-with-php-help-47mn"&gt;Learning Elixir with PHP help&lt;br&gt;
&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Depois de alguns anos e diversas experiências em PHP utilizando WordPress, Laravel, Symfony e Phalcon, tive a oportunidade de trabalhar com Elixir e desde então ela tem sido a minha linguagem para desenvolvimento de novos projetos&lt;/p&gt;

&lt;p&gt;Para quem nunca teve contato com uma linguagem funcional pode ser um pouco difícil entender como Elixir funciona, foi o meu caso quando comecei a utilizá-la.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A “ajuda” oferecida por PHP, nesse artigo, não passa de uma mera comparação feita entre as duas linguagens que por sinal não são NADA semelhante.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O que fiz foi implementar a mesma funcionalidade com linguagens diferentes para que você possa comparar a &lt;strong&gt;lógica&lt;/strong&gt; de uma linguagem mais familiar com uma que talvez não seja.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vou abordar as funcionalidades do Elixir que mais utilizo no dia-a-dia&lt;/strong&gt;, meio que aplicando a regra 80/20, mas tenho certeza que com esse conhecimento você poderá ao menos ler um arquivo &lt;code&gt;.ex&lt;/code&gt; ou &lt;code&gt;.exs&lt;/code&gt; e não se perder completamente, caso você seja novo na linguagem.&lt;/p&gt;
&lt;h4&gt;
  
  
  Antes de começarmos...
&lt;/h4&gt;

&lt;p&gt;Caso você não conheça absolutamente nada sobre Elixir, como é a syntax, seus operadores e primitivos sugiro a leitura do &lt;a href="https://elixir-lang.org/getting-started/introduction.html"&gt;&lt;em&gt;Starting Guide&lt;/em&gt;&lt;/a&gt; na documentação oficial.&lt;/p&gt;

&lt;p&gt;Sem mais demoras, vamos ao código!&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;center&gt;Pattern Matching&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Acho que a melhor definição do conceito de &lt;em&gt;pattern matching&lt;/em&gt; é a seguinte:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pattern matching é uma poderosa parte de Elixir que nos permite procurar padrões simples em valores, estruturas de dados, e até funções - &lt;a href="https://elixirschool.com/pt/lessons/basics/pattern-matching/"&gt;Elixir School&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mas o que exatamente significa? Para entender melhor precisamos falar sobre o &lt;em&gt;match operator&lt;/em&gt; &lt;code&gt;=&lt;/code&gt;. Além de utilizado para atribuir valores à variáveis, ele também pode ser usado para decompor estruturas mais complexas como tuplas.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iex&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;a, b, c&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;, &lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;, &lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;, &lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;, &lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; a
&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; b
&lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;4&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; c
&lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;

&lt;span class="c"&gt;# Another example&lt;/span&gt;
iex&lt;span class="o"&gt;(&lt;/span&gt;5&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;_, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, country&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Brasil"&lt;/span&gt;, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, &lt;span class="s2"&gt;"Chile"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Brasil"&lt;/span&gt;, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, &lt;span class="s2"&gt;"Chile"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;6&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; country
&lt;span class="s2"&gt;"Chile"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ou obter o primeiro valor de uma lista&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iex&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Olá"&lt;/span&gt;, &lt;span class="s2"&gt;"Hello"&lt;/span&gt;, &lt;span class="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Olá"&lt;/span&gt;, &lt;span class="s2"&gt;"Hello"&lt;/span&gt;, &lt;span class="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;2&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;head&lt;/span&gt;
&lt;span class="s2"&gt;"Olá"&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;3&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;tail&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Hello"&lt;/span&gt;, &lt;span class="s2"&gt;"Hola"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso uma tupla não possa ser equiparada com o lado esquerdo do operador, isso é, caso a tupla tenha número de campos diferente ou algum valor que não condiz com o lado esquerdo do &lt;code&gt;=&lt;/code&gt; uma &lt;em&gt;exception&lt;/em&gt; acontecerá:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# iex&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;a, b&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"São Paulo"&lt;/span&gt;, &lt;span class="s2"&gt;"Rio de Janeiro"&lt;/span&gt;, &lt;span class="s2"&gt;"Fortaleza"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# ** (MatchError) no match of right hand side value: {"São Paulo", "Rio de Janeiro", "Fortaleza"}&lt;/span&gt;
&lt;span class="c"&gt;#    (stdlib) erl_eval.erl:453: :erl_eval.expr/5&lt;/span&gt;
&lt;span class="c"&gt;#    ...&lt;/span&gt;

iex&lt;span class="o"&gt;(&lt;/span&gt;1&lt;span class="o"&gt;)&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;_, &lt;span class="s2"&gt;"United States"&lt;/span&gt;, country&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"Brasil"&lt;/span&gt;, &lt;span class="s2"&gt;"Ecuador"&lt;/span&gt;, &lt;span class="s2"&gt;"Chile"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="c"&gt;# ** (MatchError) no match of right hand side value: {"Brasil", "Ecuador", "Chile"}&lt;/span&gt;
&lt;span class="c"&gt;#    (stdlib) erl_eval.erl:453: :erl_eval.expr/5&lt;/span&gt;
&lt;span class="c"&gt;#    ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os exemplos acima exemplificam a primeira parte da definição de &lt;em&gt;pattern matching&lt;/em&gt;. E quanto a parte que fala que podemos procurar padrões em funções? Vamos dar uma olhada.&lt;/p&gt;

&lt;p&gt;Para ajudar no entendimento dessa vez vou criar uma classe semelhante em PHP.&lt;/p&gt;

&lt;p&gt;Classe PHP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Módulo Elixir&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Até aqui, sem novidades, certo? Se chamarmos a função &lt;code&gt;hello/1&lt;/code&gt; ela vai exibir na tela a mensagem “Hello, Joe”. Mesma coisa com a função &lt;code&gt;hello()&lt;/code&gt; da classe em PHP.&lt;/p&gt;

&lt;p&gt;Mas vamos supor que nem sempre eu teria o nome do meu usuário disponível. Em determinadas vezes a variável &lt;code&gt;user_name&lt;/code&gt; poderia ser &lt;code&gt;nil&lt;/code&gt; (&lt;code&gt;null&lt;/code&gt; em PHP). Como podemos ajustar nosso código para esse requisito?&lt;/p&gt;

&lt;p&gt;Classe PHP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&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="nb"&gt;is_null&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello world!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em PHP poderíamos adicionar um valor default para o parâmetro &lt;code&gt;$userName&lt;/code&gt; e tratar esse caso com um &lt;code&gt;if&lt;/code&gt; dentro da nossa função exibindo uma mensagem diferente caso o argumento seja &lt;code&gt;null&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Executando &lt;code&gt;GreetUser.php&lt;/code&gt; obteríamos o resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s2"&gt;"Hello, Joe"&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;Embora a mesma solução seja possível, em Elixir podemos utilizar o &lt;em&gt;pattern matching&lt;/em&gt; ao nosso favor para simplificar o nosso código sem a necessidade do &lt;code&gt;if&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Módulo Elixir&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&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="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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como existem duas funções com o mesmo nome a escolhida será aquela que possuir o parâmetro correto.&lt;/p&gt;

&lt;p&gt;Isso quer dizer que somente quando &lt;code&gt;user_name = nil&lt;/code&gt; é que a primeira função será executada, caso contrário ele “pula” essa função e vai para a próxima &lt;code&gt;hello/1&lt;/code&gt; declarada neste módulo.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Importante dizer que devido à aridade da função, &lt;code&gt;GreetUser.hello(nil)&lt;/code&gt; é diferente de &lt;code&gt;GreetUser.hello()&lt;/code&gt;. Em uma expressão invocamos &lt;code&gt;hello/1&lt;/code&gt; e na outra &lt;code&gt;hello/0&lt;/code&gt;, que não existe e portanto nos retornaria um erro, fique atento a aridade!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Qualquer tipo primitivo da linguagem pode ser utilizado para &lt;em&gt;pattern matching&lt;/em&gt;. Se o módulo &lt;code&gt;GreetUser&lt;/code&gt; agora tem que enviar uma mensagem específica para usuários que tenham o nome &lt;code&gt;"Jane”&lt;/code&gt;, poderíamos fazer da seguinte forma&lt;/p&gt;

&lt;p&gt;Classe em PHP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&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="nv"&gt;$userName&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="s2"&gt;"Jane"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Nice to see you, Jane!"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Joe"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Jane"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Módulo Elixir&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Jane"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_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;"Nice to see you, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Jane"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dessa vez além de especificarmos qual seria o valor de &lt;code&gt;user_name&lt;/code&gt; nós também adicionamos o &lt;em&gt;match operator&lt;/em&gt; no parâmetro da função: &lt;code&gt;("Jane" = user_name)&lt;/code&gt;. Fizemos isso para que possamos utilizar o valor dentro da função. Caso não quiséssemos utilizar o parâmetro podemos omiti-lo &lt;code&gt;("Jane")&lt;/code&gt; ou adicionar um &lt;code&gt;_&lt;/code&gt; &lt;em&gt;underscore&lt;/em&gt; na frente dele &lt;code&gt;("Jane" = _user_name)&lt;/code&gt;. Com isso o Elixir entende que você está desprezando esse valor e que ele não será utilizado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variáveis declaradas, mas não utilizadas recebem um&lt;/strong&gt; &lt;code&gt;warning&lt;/code&gt; &lt;strong&gt;no momento da compilação do seu código, fique atento!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Aqui já é possível enxergar um pouco melhor como esse conceito reduz a complexidade em nossas funções. Agora que você entende pattern matching não fica melhor ler a função em Elixir do que em PHP? Não precisamos mais ficar “calculando” &lt;code&gt;if&lt;/code&gt;s para saber qual o resultado esperado, uma bela vantagem, não?&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;Guards&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Se você gostou do conceito de &lt;em&gt;pattern matching&lt;/em&gt; você pode ir além utilizando &lt;em&gt;guards&lt;/em&gt;. Eles permitem verificações mais completas dos parâmetros que sua função está recebendo.&lt;/p&gt;

&lt;p&gt;Guards são definidos com um &lt;code&gt;when&lt;/code&gt; após a declaração da função. Enquanto o &lt;em&gt;pattern matching&lt;/em&gt; é útil para valores explícitos, com &lt;em&gt;guards&lt;/em&gt; podemos criar diversas condições para serem checadas. Podemos checar o tipo de um parâmetro, o tamanho dele se ele é ou não &lt;code&gt;nil&lt;/code&gt;, se ele é maior ou menor que determinado valor entre outras.&lt;/p&gt;

&lt;p&gt;Voltando ao nosso exemplo &lt;code&gt;GreetUser&lt;/code&gt;, podemos utilizar um &lt;em&gt;guard&lt;/em&gt; para verificar se &lt;code&gt;user_name&lt;/code&gt; é uma &lt;code&gt;string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Módulo Elixir&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função utilizada no guard &lt;code&gt;is_binary/1&lt;/code&gt; retorna um booleano e com esse resultado (&lt;code&gt;true&lt;/code&gt; ou &lt;code&gt;false&lt;/code&gt;) &lt;code&gt;hello/1&lt;/code&gt; é invocada ou não. Elixir possui diversas funções “&lt;a href="https://hexdocs.pm/elixir/Kernel.html#is_atom/1"&gt;type-checks&lt;/a&gt;” como essa que usamos para checar tipos.&lt;/p&gt;

&lt;p&gt;Lembrando, que usando &lt;em&gt;guard&lt;/em&gt; ou &lt;em&gt;pattern matching&lt;/em&gt; você precisa pensar em uma alternativa para o caso em que um parâmetro não se enquadre em nenhuma validação caso contrário um &lt;em&gt;runtime error&lt;/em&gt; será lançado&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;** (FunctionClauseError) no function clause matching in GreetUser.hello/1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;O Erro acima aconteceria se nós invocarmos com um inteiro, por exemplo:&lt;code&gt;GreetUser.hello(1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como alternativa podemos adicionar mais uma declaração de &lt;code&gt;hello/1&lt;/code&gt; desprezando o parâmetro &lt;code&gt;user_name&lt;/code&gt;. Como vimos antes, basta adicionarmos o &lt;em&gt;undersocre&lt;/em&gt; na frente do nome do parâmetro: &lt;code&gt;_user_name&lt;/code&gt;. Ou simplesmente substituirmos pelo &lt;code&gt;_&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;_&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;"Only string is allowed in this function"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Importante!
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;A ordem de declaração das funções em linguagens funcionais é de extrema importância!&lt;/strong&gt;&lt;br&gt;
No exemplo acima o uso de &lt;code&gt;hello/1&lt;/code&gt; ficou restrita à parâmetros do tipo &lt;code&gt;string&lt;/code&gt;. Como alternativa declaramos novamente &lt;code&gt;hello/1&lt;/code&gt; &lt;strong&gt;desprezando&lt;/strong&gt; o parâmetro &lt;code&gt;user_name&lt;/code&gt;. Até ai tudo legal, mas e se tivéssemos invertido as ordens de declaração das funções colocando &lt;code&gt;hello(_)&lt;/code&gt; antes da &lt;code&gt;hello/1&lt;/code&gt; que possui &lt;em&gt;guard&lt;/em&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&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="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;"Only string is allowed in this function"&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;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Executando o código acima teríamos o seguinte aviso:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;warning: this clause cannot match because a previous clause at line 5 always matches
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Nosso código rodaria sem problemas, mas a função &lt;code&gt;hello/1&lt;/code&gt; com o &lt;em&gt;guard&lt;/em&gt; &lt;code&gt;when is_binary/1&lt;/code&gt; nunca seria executada porque a &lt;code&gt;hello/1&lt;/code&gt; sem &lt;em&gt;guard&lt;/em&gt; é sempre validada antes. Por isso preste sempre atenção à ordem de declaração de suas funções!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;Pipe Operator&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Esse pode ser um pouco mais complicado para entender, mas em resumo o &lt;em&gt;pipe operator&lt;/em&gt; é representado por esse símbolo &lt;code&gt;|&amp;gt;&lt;/code&gt; e o trabalho dele é passar o resultado de uma expressão como primeiro parâmetro de outra expressão.&lt;/p&gt;

&lt;p&gt;Com isso você pode criar &lt;em&gt;pipelines&lt;/em&gt; (sacou o nome?) de execução dada determinada expressão (variável ou função).&lt;/p&gt;

&lt;p&gt;Para exemplificar, agora nosso módulo &lt;code&gt;GreetUser&lt;/code&gt; deve ser capaz de cumprimentar diversas pessoas cujo os nomes serão enviados em forma de uma lista. Para fazer isso vamos criar uma função &lt;code&gt;hello_group/1&lt;/code&gt; que recebe como argumento &lt;code&gt;users_name&lt;/code&gt; que nada mais é do que uma lista contendo o nome dos usuários em string.&lt;/p&gt;

&lt;p&gt;Além disso precisamos também tratar os nomes dos usuários para que eles fiquem capitalizados, isso é, somente a primeira letra do seu nome em maiúsculo.&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="c1"&gt;# code&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_group&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="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;"Only lists are allowed"&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;Aproveitamos para adicionar um guard na nossa função para nos certificar de que o parâmetro é mesmo uma lista e também definimos uma &lt;code&gt;hello_group/1&lt;/code&gt; default para ser utilizada caso &lt;code&gt;users_name&lt;/code&gt; não seja uma lista.&lt;/p&gt;

&lt;p&gt;O próximo passo é manipular a lista aplicando os requisitos acima utilizando o &lt;em&gt;pipe operator&lt;/em&gt;. Como primeiro passo, vamos percorrer a lista e normalizar os nomes. Faremos isso com a ajuda do módulo &lt;code&gt;Enum&lt;/code&gt; que é um módulo nativo do Elixir para trabalhar com elementos enumeráveis, o que é o caso da nossa lista de nomes&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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_group&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="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;"Only lists are allowed"&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;Vamos quebrar o código acima em pontos chaves:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invocamos &lt;code&gt;users_name&lt;/code&gt; dentro da nossa função&lt;/li&gt;
&lt;li&gt;Invocamos &lt;code&gt;|&amp;gt;&lt;/code&gt; (pipe operator) abaixo de &lt;code&gt;users_name&lt;/code&gt; poderia ser do lado direito também.&lt;/li&gt;
&lt;li&gt;Invocamos &lt;code&gt;map/2&lt;/code&gt; do módulo &lt;code&gt;Enum&lt;/code&gt; para percorrer a lista de nomes e nos retornar uma lista&lt;/li&gt;
&lt;li&gt;Passamos como segundo parâmetro de &lt;code&gt;map/2&lt;/code&gt; uma função anônima &lt;code&gt;fn user_name -&amp;gt; end&lt;/code&gt; que será executada para cada nome da lista&lt;/li&gt;
&lt;li&gt;Dentro da função anônima utilizamos a função &lt;a href="https://hexdocs.pm/elixir/String.html#capitalize/2"&gt;&lt;code&gt;capitalize/2&lt;/code&gt;&lt;/a&gt; do módulo &lt;code&gt;String&lt;/code&gt; também nativo do Elixir para capitalizar os nomes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;O que precisa ser entendido desse código é que só passamos o segundo argumento para a função &lt;code&gt;map/2&lt;/code&gt; porque o primeiro argumento que deve ser uma lista (no nosso caso a lista com os nomes dos usuários) já foi passada à essa função pelo &lt;code&gt;|&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Lembre que: “O &lt;em&gt;pipe operator&lt;/em&gt; é responsável por passar o valor de uma expressão como o primeiro parâmetro da próxima expressão” No caso nossa primeira expressão é a variável &lt;code&gt;users_name&lt;/code&gt; que ao ser processada retorna nossa lista de nomes e uma lista é justamente o que &lt;code&gt;map/2&lt;/code&gt; recebe no primeiro parâmetro, por isso nossa pipeline funciona!&lt;/p&gt;

&lt;p&gt;E o segundo parâmetro passado ao &lt;code&gt;map/2&lt;/code&gt; foi uma função anônima (requerida por &lt;code&gt;map/2&lt;/code&gt;) que recebe como argumento o elemento da lista que está sendo percorrida para que possamos manipulá-lo.&lt;/p&gt;

&lt;p&gt;Em PHP podemos obter o mesmo resultado até aqui dessa forma:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Only arrays are allowed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameNormalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;ucfirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$usersName&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;O próximo passo nessa função é juntarmos todos os nomes em uma única string. Para isso utilizaremos outra função nativa do Elixir, a &lt;code&gt;join/2&lt;/code&gt; do módulo &lt;code&gt;Enum&lt;/code&gt;. Ela recebe como primeiro parâmetro uma lista e como segundo parâmetro um elemento de junção, no nosso caso utilizaremos uma vírgula seguida de espaço em branco, para separar os nomes dentro da string.&lt;/p&gt;

&lt;p&gt;Módulo Elixir&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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;join&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;end&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;hello_group&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="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;"Only lists are allowed"&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;Classe PHP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Only arrays are allowed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameNormalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;ucfirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&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="nv"&gt;$usersNameNormalized&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;Nossa pipeline continua funcionando porque &lt;code&gt;map/2&lt;/code&gt;, após ser executada, retorna uma lista e o &lt;code&gt;|&amp;gt;&lt;/code&gt; passa essa lista como primeiro parâmetro para a próxima função &lt;code&gt;join/2&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ótimo! &lt;code&gt;hello_group/1&lt;/code&gt; já consegue normalizar e juntar os nomes enviados como lista em uma única string! Agora só nos resta imprimir nossa mensagem para o usuário.&lt;/p&gt;

&lt;p&gt;Até agora o retorno de &lt;code&gt;hello_group/1&lt;/code&gt; seria uma string contendo os nomes de usuários que foi passado à ela. Podemos utilizar &lt;code&gt;hello/1&lt;/code&gt;, que recebe como primeiro parâmetro uma string, para exibir a mensagem padrã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="c1"&gt;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;_&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;"Only strings are allowed"&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_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_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_list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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;join&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&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_group&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="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;"Only lists are allowed"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello_group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adicionamos &lt;code&gt;hello/1&lt;/code&gt; no final de nossa pipeline concluindo os requisitos exigidos para &lt;code&gt;hello_group/1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Veja como ficaria o mesmo código em PHP&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="c1"&gt;// ./GreetUser.php&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello, "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$userName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&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="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersName&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Only arrays are allowed"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameNormalized&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;ucfirst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="nv"&gt;$usersName&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="nv"&gt;$usersNameString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;implode&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="nv"&gt;$usersNameNormalized&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$usersNameString&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="nv"&gt;$greetUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GreetUser&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$greetUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;helloGroup&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Poderíamos melhorar o código PHP quebrando-o em diferentes funções, mas repare que mesmo dessa forma em Elixir temos um código MUITO mais limpo e legível.&lt;/p&gt;

&lt;p&gt;Caso você ainda esteja um pouco confuso em como o &lt;em&gt;pipe operator&lt;/em&gt; funciona, aqui está uma outra forma de visualizar o mesmo código:&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&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;users_name&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="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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;join&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="o"&gt;|&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;hello&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_group&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;users_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:notpiped&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;hello&lt;/span&gt;&lt;span class="p"&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;join&lt;/span&gt;&lt;span class="p"&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;users_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;user_name&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;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&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="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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello_group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hello_group&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"joe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jane"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"jim"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;:notpiped&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Definimos duas funções &lt;code&gt;hello_group()&lt;/code&gt;. Uma com &lt;a href="https://elixirschool.com/en/lessons/basics/functions/#function-naming-and-arity"&gt;aridade&lt;/a&gt; &lt;code&gt;hello_group/1&lt;/code&gt; e outra com &lt;code&gt;hello_group/2&lt;/code&gt;. Apesar da aridade diferente, as duas executam o mesmo papel, mas a &lt;code&gt;hello_group/1&lt;/code&gt; cria uma &lt;em&gt;pipeline&lt;/em&gt; enquanto a &lt;code&gt;hello_group/2&lt;/code&gt; não, mas as duas chegam no mesmo resultado.&lt;/p&gt;

&lt;p&gt;Porém &lt;code&gt;hello_group/1&lt;/code&gt; é bem mais legível e de fácil entendimento se comparada a &lt;code&gt;hello_group/2&lt;/code&gt;, concordam? Esse é o propósito do &lt;em&gt;pipe operator&lt;/em&gt;, deixar nosso código mais legível.&lt;/p&gt;

&lt;p&gt;Para concluir aqui vai uma observação muito importante! Em linguagens funcionais nós não temos a opção de utilizar &lt;code&gt;return&lt;/code&gt;s dentro das funções. As funções retornarão o resultado da última expressão executada, vamos explorar mais sobre isso no próximo tópico.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;Estruturas de Controle&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Vimos que em Elixir é possível simplificar muito nossas funções removendo condicionais através do &lt;em&gt;pattern matching&lt;/em&gt; e &lt;em&gt;guards&lt;/em&gt;. Mas as vezes não temos outra alternativa a não ser utilizar um &lt;code&gt;if&lt;/code&gt; ou &lt;code&gt;switch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As estruturas de controles presentes em Elixir são: &lt;code&gt;if&lt;/code&gt;, &lt;code&gt;unless&lt;/code&gt;, &lt;code&gt;case&lt;/code&gt;, &lt;code&gt;cond&lt;/code&gt; e &lt;code&gt;with&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Como esse é um overview da linguagem, não vou me aprofundar em todas elas com exceção do  &lt;code&gt;with&lt;/code&gt;, talvez ele cause mais estranheza enquanto as outras são mais familiares.&lt;/p&gt;

&lt;p&gt;É importante notar que essas estruturas de controles se comportam como funções e por isso alguns hábitos de outras linguagens devem ser evitados em Elixir. Um exemplo disso é quando você define um valor default para uma variável e dentro de um &lt;code&gt;if&lt;/code&gt; você troca esse valor. Algo parecido com isso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;anotherFunction&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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="nv"&gt;$condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PHP"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$param&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;Esse código não funciona do jeito que você espera em Elixir, como &lt;code&gt;if&lt;/code&gt; se comporta como uma função ela vai retornar o resultado que foi executado dentro do seu body. Sendo assim o valor que você atribuiu dentro dele para a sua variável não será aplicado pois não faz parte do escopo da função.&lt;/p&gt;

&lt;p&gt;Para que isso funcionasse você teria que fazer algo desse gênero:&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;another_function&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
        &lt;span class="s2"&gt;"Elixir"&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="no"&gt;nil&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;Dessa forma o retorno de &lt;code&gt;if&lt;/code&gt; seria atribuído à nossa variável.&lt;/p&gt;

&lt;h2&gt;
  
  
  With
&lt;/h2&gt;

&lt;p&gt;Você pode pensar nele como uma &lt;em&gt;pipeline&lt;/em&gt; que checa o resultado de cada expressão e caso o resultado dessa expressão não foi o que você havia descrito ela não executa o código dentro dela. Ou você também pode validar o erro gerado pela expressão para tratá-lo de uma forma mais coerente.&lt;/p&gt;

&lt;p&gt;Para ilustrar melhor, vamos adicionar essa estrutura na nossa função &lt;code&gt;hello/1&lt;/code&gt;. Criaremos também uma &lt;code&gt;dummy_function/0&lt;/code&gt; que a única coisa que ela faz é retornar o &lt;em&gt;atom&lt;/em&gt; &lt;code&gt;:ok&lt;/code&gt;, e em &lt;code&gt;hello/1&lt;/code&gt; verificamos se &lt;code&gt;dummy_function/0&lt;/code&gt; realmente volta &lt;code&gt;:ok&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;dummy_function&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="ss"&gt;:ok&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;user_name&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;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima, a mensagem só será exibida caso &lt;code&gt;dummy_function/0&lt;/code&gt; retornar &lt;code&gt;:ok&lt;/code&gt;. Se o retorno for outro a mensagem não será exibida.&lt;/p&gt;

&lt;p&gt;Se &lt;code&gt;dummy_function/0&lt;/code&gt; não retornar o esperado, podemos adicionar uma cláusula para tratar o resultado.&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;dummy_function&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="ss"&gt;:error&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;user_name&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;with&lt;/span&gt; &lt;span class="ss"&gt;:ok&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;else&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;"dummy_functtion didn't return an :ok atom"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos também atribuir variáveis do lado esquerdo do &lt;code&gt;&amp;lt;-&lt;/code&gt; ou &lt;code&gt;-&amp;gt;&lt;/code&gt; que nem fizemos quando vimos sobre &lt;em&gt;pattern matching&lt;/em&gt;. Com isso é possível verificar o retorno da função e já atribuir uma variável&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;# ./greet_user.exs&lt;/span&gt;

&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;GreetUser&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;dummy_function&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="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="s2"&gt;"dummy function"&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;hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_name&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;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="n"&gt;_response&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;else&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;message&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;"dummy_functtion return an error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&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="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;"I can't figure what dummy_function has returned"&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="no"&gt;GreetUser&lt;/span&gt;&lt;span class="o"&gt;.&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;"Joe"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima checamos se &lt;code&gt;dummy_function/0&lt;/code&gt; retorna &lt;code&gt;{:ok, _response}&lt;/code&gt; Caso um erro ocorra e &lt;code&gt;dummy_function/0&lt;/code&gt; retornar &lt;code&gt;{:error, "dummy function"}&lt;/code&gt; nós vamos exibir &lt;code&gt;"dummy function"&lt;/code&gt;, que foi o erro retornado. E ainda adicionamos uma cláusula default se &lt;code&gt;dummy_function/0&lt;/code&gt; retornar algo totalmente inesperado.&lt;/p&gt;

&lt;p&gt;Agora que já temos um bom entendimento sobre o &lt;em&gt;with&lt;/em&gt; podemos criar uma &lt;em&gt;pipeline&lt;/em&gt; de funções cujo os retornos são verificados pelo with e podemos também tratar individualmente cada etapa:&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;user_name&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;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="n"&gt;response1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function&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;_response2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;dummy_function_2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reponse1&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, &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;user_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;else&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;message&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;"dummy_functtion return an error: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;message&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="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;"I can't figure what dummy_function has returned"&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;O código acima cria uma &lt;em&gt;pipeline&lt;/em&gt; que checa passo a passo o retorno das funções possibilitando o tratamento personalizado para cada erro que possa acontecer.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;And there you have it!&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Embora Elixir seja um mundo de funcionalidades e paradigmas diferentes se você possuir um bom entendimento dos tópicos acima você conseguirá se localizar muito bem no código escrito nessa linguagem.&lt;/p&gt;

&lt;p&gt;Estes são alguns tópicos importantes para você que deseja continuar interagindo com a linguagem:&lt;/p&gt;

&lt;h4&gt;
  
  
  Mix
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Task runner&lt;/em&gt; da linguagem (equivalente ao &lt;em&gt;composer&lt;/em&gt; em PHP), link para o &lt;a href="https://elixir-lang.org/getting-started/mix-otp/introduction-to-mix.html"&gt;guia&lt;/a&gt; e &lt;a href="https://hexdocs.pm/mix/Mix.html"&gt;documentação&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Phoenix
&lt;/h4&gt;

&lt;p&gt;Web framework (equivalente ao &lt;em&gt;Symfony&lt;/em&gt;, &lt;em&gt;Laravel&lt;/em&gt;, etc... em PHP), link para o &lt;a href="https://www.phoenixframework.org/"&gt;site&lt;/a&gt; e &lt;a href="https://hexdocs.pm/phoenix/Phoenix.html"&gt;documentação&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Ecto
&lt;/h4&gt;

&lt;p&gt;ORM (equivalente ao &lt;em&gt;Doctrine&lt;/em&gt; em php), link para o &lt;a href="https://elixirschool.com/pt/lessons/ecto/basics/"&gt;guia&lt;/a&gt; e &lt;a href="https://hexdocs.pm/ecto/Ecto.html"&gt;documentação&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Hex
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Package repository&lt;/em&gt; (equivalente ao &lt;em&gt;Packgist&lt;/em&gt; do &lt;em&gt;Composer&lt;/em&gt;), link para o &lt;a href="https://hex.pm/"&gt;site&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;center&gt;Referências&lt;/center&gt;
&lt;/h2&gt;

&lt;p&gt;Abaixo uma lista de sites, vídeos e outros materiais para você ler e que foram utilizados para compor esse artigo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Site oficial da linguagem: &lt;a href="https://elixir-lang.org/"&gt;https://elixir-lang.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Para aprender mais: &lt;a href="https://elixirschool.com/pt/"&gt;https://elixirschool.com/pt/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Mini documentário da origem da linguagem: &lt;a href="https://www.youtube.com/watch?v=lxYFOM3UJzo"&gt;https://www.youtube.com/watch?v=lxYFOM3UJzo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hipster ponto tech com o José Valim sobre Elixir: &lt;a href="https://hipsters.tech/elixir-a-linguagem-hipster-hipsters-48/"&gt;https://hipsters.tech/elixir-a-linguagem-hipster-hipsters-48/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Principal evento da linguagem no Brasil: &lt;a href="https://twitter.com/elixir_brasil"&gt;https://twitter.com/elixir_brasil&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Espero que esse artigo tenha sido útil para você. Caso tenha alguma sugestão e/ou feedback deixe nos comentários, esse é um dos meus primeiros artigos e gostaria de saber como estou me saindo 😁&lt;/p&gt;

&lt;p&gt;Obrigado pelo seu tempo e até a próxima 🖖&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>elixir</category>
      <category>php</category>
      <category>ptbr</category>
    </item>
  </channel>
</rss>
