<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Gabriel Schade Cardoso</title>
    <description>Blog pessoal sobre desenvolvimento de software e coisas afins
</description>
    <link>https://gabrielschade.github.io///</link>
    <atom:link href="https://gabrielschade.github.io//feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sun, 06 Jun 2021 16:21:42 +0000</pubDate>
    <lastBuildDate>Sun, 06 Jun 2021 16:21:42 +0000</lastBuildDate>
    <generator>Jekyll v3.9.0</generator>
    
      
      
      
      <item>
        <title>Elastic Map Reduce - EMR - Arquitetura Geral</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Depois de falarmos sobre Hadoop, que tal começar a falar sobre EMR, um dos serviços AWS que utiliza tudo que vimos no post anterior!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;O que é o EMR? Bom, pra começar a sigla significa Elastic Map Reduce, ele é um serviço que provê uma plataforma de clusters gerenciados para processar e analisar grandes quantidades de dados.&lt;/p&gt;

&lt;p&gt;Quase sempre quando temos um volume grande de dados nos deparamos com problemas para dar vazão ao processamento desses dados de forma eficiente, EMR utiliza Hadoop para quebrar esse problema em jobs menores e distribuí-los entre vários nós de processamento.&lt;/p&gt;

&lt;p&gt;Podemos aplicar EMR, por exemplo, para processarmos uma quantidade grande de logs, processamentos de machine learning e ETL (Extract, Transform e Load). Tudo isso podendo controlar o quanto queremos escalar (ou não) nossos clusters.&lt;/p&gt;

&lt;p&gt;Se você não viu o post passado, recomendo acessar &lt;a href=&quot;/2020/12/14/Hadoop.html&quot; target=&quot;_blank&quot;&gt;este link&lt;/a&gt;, afinal vamos utilizar vários conceitos mencionados lá, mas dessa vez, claro, sob o contexto do EMR.&lt;/p&gt;

&lt;h3 id=&quot;arquitetura&quot;&gt;Arquitetura&lt;/h3&gt;
&lt;p&gt;Existem algumas pequenas diferenças entre a arquitetura de um cluster &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hadoop&lt;/code&gt; e de um cluster &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EMR&lt;/code&gt;, vamos dar uma olhada geral na arquitetura:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/3m0d7aV.png&quot; class=&quot;materialboxed&quot; alt=&quot;Visão geral&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;É possível notar algumas diferenças, mas calma, vamos por partes.&lt;/p&gt;

&lt;p&gt;Primeiro ponto que pode chamar atenção é: todo o cluster está necessariamente dentro de uma mesma AZ (availability zone), entraremos em mais detalhes sobre isso ao longo do post, mas é importante por agora termos na cabeça que não há chamadas entre diferentes AZs em um mesmo cluster.&lt;/p&gt;

&lt;p&gt;Segundo ponto: Nossos nós secundários sumiram, agora eles viraram Core e Task nodes, existem algumas diferenças entre os dois, mas podemos considerar que tanto os tasks quanto os core nodes são sim nós secundários.&lt;/p&gt;

&lt;p&gt;Terceiro ponto: Agora temos essas caixinhas chamadas &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Instance Group&lt;/code&gt;, o que é isso?&lt;/p&gt;

&lt;h4 id=&quot;instance-groups&quot;&gt;Instance Groups&lt;/h4&gt;

&lt;p&gt;Instance groups é um conceito bem simples, basicamente é uma forma de organizar um grupo, ou coleção de instâncias EC2 e tratá-las como uma unidade única.&lt;/p&gt;

&lt;p&gt;Um cluster EMR pode conter até 50 &lt;em&gt;instance groups&lt;/em&gt;, onde apenas uma delas pode ser uma &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Master Instance Group&lt;/code&gt;, contendo seu nó principal. Uma &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Core Instance Group&lt;/code&gt; contendo multíplos Core nodes e por fim, você pode criar até 48 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task Instance Groups&lt;/code&gt;, onde cada um pode conter multíplos Task nodes.&lt;/p&gt;

&lt;p&gt;Por que criar multíplos Task nodes ao invés de simplesmente aumentar o número de instâncias? No EMR, cada &lt;em&gt;instance group&lt;/em&gt; utiliza um único tipo de instância EC2 para todos os nós. Então caso você queira utilizar diferentes tipos de instâncias, a opção de criar um novo grupo pode ser bastante útil.&lt;/p&gt;

&lt;p&gt;Agora assim como fizemos no post de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hadoop&lt;/code&gt;, vamos destrinchar cada um dos tipos de nós de um cluster EMR!&lt;/p&gt;

&lt;h4 id=&quot;master-node&quot;&gt;Master Node&lt;/h4&gt;

&lt;p&gt;Todo cluster EMR possui apenas um único &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Master Node&lt;/code&gt;, o que pode não parecer a melhor coisa do mundo, afinal, ele acaba sendo um ponto único de falha, mas existem formas de mitigar isso, podemos falar sobre isso em um post futuro.&lt;/p&gt;

&lt;p&gt;Este nó é responsável por gerenciar os recursos do cluster, isso inclui: coordenar e distribuir a execução paralela entre os nós secundários; Gerenciamento do sistema de arquivos (falaremos sobre os tipos de sistemas de arquivos mais para frente, não se preocupe com isso agora), e ah, você ainda lembra do &lt;strong&gt;Resource Manager&lt;/strong&gt;? Pois é, é aqui que ele fica no EMR, com todas as responsabilidades descritas no post anterior.&lt;/p&gt;

&lt;p&gt;Por fim, o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Master Node&lt;/code&gt; também é responsável por monitorar a saúde dos Core e Task nodes.&lt;/p&gt;

&lt;h4 id=&quot;core-node&quot;&gt;Core Node&lt;/h4&gt;

&lt;p&gt;Um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Core Node&lt;/code&gt; é basicamente o mesmo que os nós secundários que aprendemos no post anterior. São responsáveis por executar tarefas enviadas pelo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Master Node&lt;/code&gt;, eles armazenam dados utilizando o sistema de arquivos.&lt;/p&gt;

&lt;p&gt;Também é aqui que fica o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Node Manager&lt;/code&gt; e o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Application Master&lt;/code&gt; normalmente, assim como os nós secundários do Hadoop, com as mesmas funções e responsabilidades.&lt;/p&gt;

&lt;p&gt;Existem algumas operações extras que podem ser realizadas aqui, mas novamente, isso ficará para um post futuro.&lt;/p&gt;

&lt;h4 id=&quot;task-node&quot;&gt;Task Node&lt;/h4&gt;

&lt;p&gt;Se o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Core Node&lt;/code&gt; é o mesmo que um nó secundário, o que diabos é um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task Node&lt;/code&gt;? Bom, na prática o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task Node&lt;/code&gt; também é um nó secundário, mas com algumas particularidades.&lt;/p&gt;

&lt;p&gt;Começando com o fato de ser opcional, ou seja, você pode ter um cluster sem que ele tenha um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task Node&lt;/code&gt;. Além disso, esses nós não possuem nenhum acesso ao sistema de arquivos.&lt;/p&gt;

&lt;p&gt;Para que servem? - Bom, o nome é bastante sugestivo, estes nós podem ser adicionados ou removidos de um cluster em execução para trazer mais poder computacional à eles. Imagine um cenário em que você precisa adicionar mais memória ou CPU durante uma execução, sem a flexibilidade do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task Node&lt;/code&gt; você poderia se colocar em uma situação onde não há recursos suficientes e teria de reiniciar o cluster alterando as configurações de seus &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Core Nodes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Mon, 21 Dec 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/12/21/EMR-intro.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/12/21/EMR-intro.html</guid>
        
        <category>AWS</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Introdução à Apache Hadoop</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Depois de um bom tempo fora, estou de volta!&lt;/p&gt;

&lt;p&gt;Depois de uma virada na minha carreira, agora vamos começar uma série sobre serviços AWS e tecnologias envolvidas!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;O primeiro assunto que quero tratar é o Apache Hadoop, sim, eu sei, não é um serviço AWS, mas vai servir de base para o próximo assunto, então vamos começar por ele.&lt;/p&gt;

&lt;p&gt;O que é o Apache Hadoop? Bom, uma forma de resumir ele é simplesmente dizer que ele é um framework open-source que permite processar grandes quantidades de dados de forma distribuída entre clusters de computadores. Ele é projetado principalmente para escalabilidade, ou seja, podemos utilizá-lo em clusters com centenas ou até milhares de máquinas ao invés de utilizarmos uma super máquina para fazer tudo. Além disso, Hadoop também é projetado para detectar e lidar com falhas nos nós de processamento na camada de aplicação.&lt;/p&gt;

&lt;p&gt;Vamos fazer um overview dos componentes do Hadoop, seus módulos e como eles interagem entre si.&lt;/p&gt;

&lt;p&gt;Normalmente um Hadoop cluster é composto por um nó principal(master) e N nós secundários(slave).&lt;/p&gt;

&lt;p&gt;O nó principal é responsável por gerenciar os recursos do cluster a agendar as tarefas entre os nós secundários usando Hadoop Distribuited File System (HDFS).&lt;/p&gt;

&lt;p&gt;Os nós secundários são responsáveis por executar tarefas em conjunto com o nó principal e por seus pares.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/7JkrydC.png&quot; class=&quot;materialboxed&quot; alt=&quot;Visão geral&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Vamos agora falar da arquitetura do Hadoop! Ele é dividido entre módulos, não vou falar de todos aqui, mas vamos focar nos que considero mais importante.&lt;/p&gt;

&lt;h3 id=&quot;hadoop-core&quot;&gt;Hadoop Core&lt;/h3&gt;

&lt;p&gt;Como o nome sugere, o módulo &lt;em&gt;core&lt;/em&gt; contém as bibliotecas e utilitários consumidos pelos outros módulos, ou seja, ele funciona como uma peça base dentro da arquitetura Hadoop.&lt;/p&gt;

&lt;p&gt;Ele é responsável por coisas como: abstrair o sistema de arquivos do sistema operacional e iniciar o Hadoop própriamente dito.&lt;/p&gt;

&lt;p&gt;Em alguns locais você também pode ver o nome desse módulo como &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hadoop Common&lt;/code&gt;, eles são basicamente a mesma coisa.&lt;/p&gt;

&lt;h3 id=&quot;hadoop-distribuited-file-system-hdfs&quot;&gt;Hadoop Distribuited File System (HDFS)&lt;/h3&gt;

&lt;p&gt;Os nomes dos módulos são bastante sugestivos, nessa altura você já deve ter percebido que o HDFS é um sistema de arquivos distribuído, certo? Mas o que isso quer dizer?&lt;/p&gt;

&lt;p&gt;Bom, ele é o modo de armazenamento base do framework, isso significa que ele pode armazenar arquivos gigantescos através de diversas máquinas em um cluster. Cada arquivo é armazenado como um sequência de blocos de mesmo tamanho (com exceção do último) e são duplicados para garantir tolerância à falhas. Tanto o tamanho dos blocos como o fator de duplicação são completamente configuráveis.&lt;/p&gt;

&lt;p&gt;Isso tudo provendo uma alta taxa de transferência (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;throughput&lt;/code&gt;) para acesso dos dados para processamento e análise de grandes volumes de dados.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/DZ4YNCE.png&quot; class=&quot;materialboxed&quot; alt=&quot;Visão geral - 2&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;h3 id=&quot;hadoop-yarn&quot;&gt;Hadoop Yarn&lt;/h3&gt;

&lt;p&gt;Esse é um dos nomes não tão claros, YARN significa (Yet Another Resource Negotiator), este módulo basicamente serve para o agendamento de jobs e resource-management do cluster.&lt;/p&gt;

&lt;p&gt;Vamos dar uma olhada nos componentes do YARN:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/0Yypa1y.png&quot; class=&quot;materialboxed&quot; alt=&quot;Visão geral - 3 - Yarn&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;h4 id=&quot;resource-manager&quot;&gt;Resource Manager&lt;/h4&gt;

&lt;p&gt;O primeiro componente é parte do nó principal, o &lt;strong&gt;Resource Manager&lt;/strong&gt;, ele é um agendador para alocação de recursos no cluster para executar processos que podem competir entre si. Isso porque um mesmo cluster Hadoop pode executar multiplos processos, como mais de um MapReduce ou até mesmo processos diferentes como MapReduce + Spark.&lt;/p&gt;

&lt;h4 id=&quot;node-manager&quot;&gt;Node Manager&lt;/h4&gt;

&lt;p&gt;Em cada nó secundário temos um &lt;strong&gt;Node Manager&lt;/strong&gt;, este componente responde diretamente instruções do &lt;strong&gt;Resource Manager&lt;/strong&gt;. Ele é responsável por gerenciar os recursos do nó secundário de maniera mais local, enquanto que o &lt;strong&gt;Resource Manager&lt;/strong&gt; se preocupa com isso no contexto do cluster.&lt;/p&gt;

&lt;h4 id=&quot;application-master&quot;&gt;Application Master&lt;/h4&gt;

&lt;p&gt;Este componente também faz parte dos nós secundários, ele é responsável por negociar recursos com o &lt;strong&gt;Resource Manager&lt;/strong&gt; e &lt;strong&gt;Node Manager&lt;/strong&gt; para executar e monitorar os &lt;strong&gt;Containers&lt;/strong&gt;.&lt;/p&gt;

&lt;h4 id=&quot;container&quot;&gt;Container&lt;/h4&gt;
&lt;p&gt;Todo o processamento de dados e onde a aplicação realmente executa são nos &lt;strong&gt;Containers&lt;/strong&gt; dos nós secundários que são executados pelo &lt;strong&gt;Application Master&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Os containers também são responsáveis por garantir acessos de memóra e CPU à aplicação.&lt;/p&gt;

&lt;h3 id=&quot;mapreduce&quot;&gt;MapReduce&lt;/h3&gt;

&lt;p&gt;MapReduce é um framework para processar grandes volumes de dados utilizando processamento paralelo distribuido em um cluster. Esse processamento pode ser desestruturado (utilizando um sistema de arquivos) ou estruturado (utilizando um banco de dados).&lt;/p&gt;

&lt;p&gt;Mas por que se chamar MapReduce? - O nome se refere às duas principais tarefas: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reduce&lt;/code&gt;. Se você já utilizou alguma biblioteca de programação funcional já deve ter se deparado com estes métodos (menos em C#, que eles se chamam respectivamente &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Aggregate&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Note que eu utilizei a palavra “principais”, isso quer dizer que existem mais tarefas? - Sim.&lt;/p&gt;

&lt;p&gt;O &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MapReduce&lt;/code&gt; possui as seguintes tarefas: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Input&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Split&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Map&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Shuffle&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Reduce&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Result&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Vamos entender o que cada fase é responsável por.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Input&lt;/strong&gt;: Nesta etapa temos apenas a entrada de dados, normalmente desestruturada;
&lt;strong&gt;Split&lt;/strong&gt;: Nesta etapa a entrada é dividida entre múltiplos nós, simplesmente para acelerar o processamento;
&lt;strong&gt;Map&lt;/strong&gt;: Nesta etapa cada registro da entrada é transformada em um key value pair, neste ponto o &lt;strong&gt;Resource Manager&lt;/strong&gt; irá atribuir os recursos necessários aos nós para realizar o processamento distribuído, como resultado dessa fase, uma saída intermediária é gerada;
&lt;strong&gt;Shuffle&lt;/strong&gt;: Nesta etapa a saída intermediária é processada para que cada key value pair seja enviado para um local específico para seu processamento final;
&lt;strong&gt;Reduce&lt;/strong&gt;: Nesta etapa obtemos a saída da etapa &lt;strong&gt;Shuffle&lt;/strong&gt; e a processamos com a função &lt;strong&gt;Reduce&lt;/strong&gt;, fazendo com que os dados possam ser agregados, filtrados e assim por diante;
&lt;strong&gt;Result&lt;/strong&gt;: Nesta etapa o programa pode escrever o arquivo de saída.&lt;/p&gt;

&lt;p&gt;Vamos fazer um exemplo, imagine que você está utilizando o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MapReduce&lt;/code&gt; em uma conta do GitHub, com múltiplos repositórios, escritos em linguagens diferentes, poderíamos ter essa pipeline de execução conforme a imagem a seguir:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/gnMbk6q.png&quot; class=&quot;materialboxed&quot; alt=&quot;MapReduce Pipeline&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Dec 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/12/14/Hadoop.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/12/14/Hadoop.html</guid>
        
        <category>AWS</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Café Debug:  Algoritmos e Estrutura de Dados!</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Eu participei de mais um podcast Café Debug, dessa vez sobre algoritmos e estrutura de dados!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Neste episódio eu, &lt;a href=&quot;https://twitter.com/JessicaNathanyF&quot;&gt;Jéssica Nathany&lt;/a&gt; e meu grande amigo &lt;a href=&quot;https://www.linkedin.com/in/andrelms91/&quot;&gt;André Santana&lt;/a&gt; conversamos sobre a importância de algoritmos e estrutura de dados.&lt;/p&gt;

&lt;p&gt;Segue o episódio:&lt;/p&gt;
&lt;div&gt;
    &lt;iframe src=&quot;https://open.spotify.com/embed-podcast/episode/5YcsvdH6hqqGRAbPCTohex&quot; width=&quot;100%&quot; height=&quot;232&quot; frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; allow=&quot;encrypted-media&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Queria também aproveitar para agradecer o convite e que venham mais parcerias!&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Thu, 13 Aug 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/08/13/cafeDebug2.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/08/13/cafeDebug2.html</guid>
        
        <category>Discussões</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Um projeto novo: Elidriel - Meu JRPG</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Se você já ouviu minha história em algum podcast ou por aí no YouTube, já sabe que comecei na área por conta da minha vontade de desenvolver jogos. Bom, esse é meu novo projeto.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Como falei na chamada do post, desde que me lembro tenha a vontade de desenvolver um jogo. Entre todas as escolhas acabei decidindo por começar um projeto para o gênero que mais gosto: “JRPG”.&lt;/p&gt;

&lt;p&gt;Ok, eu não sou japonês, então é claro que não é exatamente um JRPG. Mas bebe das mesmas fontes e tem as mesmas características. A minha ideia é fazer minha versão dos RPGs antigos, lá pelo SNES, como Final Fantasy IV, v e VI.&lt;/p&gt;

&lt;p&gt;Por motivos óbvios, é claro que eu não espero que saia na mesma qualidade que estes clássicos, até porque, é um projeto de um homem só.&lt;/p&gt;

&lt;p&gt;Como cheguei no ponto em que tenho uma build estável com todas as mecânicas implementadas, achei que era a hora de lançar.
Você terá aproximadamente 5 horas de gameplay e eu espero muito que a experiência seja satisfatória (e desafiadora).&lt;/p&gt;

&lt;p&gt;Você pode fazer o download &lt;a href=&quot;https://drive.google.com/file/d/1kktFMYJH4wWIn6JAjXChg9-KpCtAN2TH/view?usp=sharing&quot;&gt;neste link&lt;/a&gt; e se divertir!&lt;/p&gt;

&lt;p&gt;De qualquer modo, aqui vai um resumão do jogo com prints, personagens e sinopse, eu espero que você goste!&lt;/p&gt;

&lt;h2 id=&quot;projeto---elidriel&quot;&gt;Projeto - Elidriel&lt;/h2&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/Bgj3KtI.png&quot; class=&quot;materialboxed&quot; alt=&quot;Logo do jogo&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;
&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/2cZOVNf.png&quot; class=&quot;materialboxed&quot; alt=&quot;Troféu&quot; style=&quot;max-width: 10%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;CGA - Vencedor categoria Aventura&lt;/p&gt;

&lt;p&gt;4º Lugar (Demo 1) - Projeto Valente Verão 2020&lt;/p&gt;

&lt;p&gt;4º Lugar (Demo 1) - Protótipo Premiado 18&lt;/p&gt;

&lt;p&gt;Gênero: RPG / Fantasia&lt;/p&gt;

&lt;p&gt;Data de início: Dezembro 2018&lt;/p&gt;

&lt;h3 id=&quot;introdução&quot;&gt;Introdução&lt;/h3&gt;

&lt;p&gt;Este projeto é meu passatempo, mas estou tomando todo cuidado possível em seu desenvolvimento, para que mesmo tendo as limitações de um projeto tocado por uma pessoa só, ele tenha seu valor e possa prover uma experiência legal ao jogador.&lt;/p&gt;

&lt;h3 id=&quot;sinopse&quot;&gt;Sinopse&lt;/h3&gt;

&lt;p&gt;Onde a paz reinava por séculos um atentado ao governante atual muda tudo, a ascenção do chanceler Arthur O’Caddler ao poder torna a seita do Grifo de Platina lei e todos os julgados pecadores, se tornam condenados e foras da lei.&lt;/p&gt;

&lt;p&gt;Ada, uma ex agente do império exilada no vilarejo Valefor, recebe de surpresa a visita de um velho amigo que mudará tudo. Kell membro ativista contra o império convoca Ada para uma missão e nela encontram novos aliados e seu envolvimento com o divino e com as forças de Elidriel mudam seus destinos mudam para sempre.&lt;/p&gt;

&lt;p&gt;Os heróis não estão mais envolvidos apenas na guerra humana, existe algo maior. Uma ligação entre a seita do Grifo de Platina e os Eternos de Elidriel podem decidir o destino de toda a humanidade.&lt;/p&gt;

&lt;h3 id=&quot;personagens&quot;&gt;Personagens&lt;/h3&gt;

&lt;h4 id=&quot;ada&quot;&gt;Ada&lt;/h4&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/Wp7Q2HX.png&quot; class=&quot;materialboxed&quot; alt=&quot;Ada&quot; style=&quot;max-width: 50%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Ex membro do grupo militar fantasma.&lt;/p&gt;

&lt;p&gt;O grupo fantasma sofreu uma perseguição agressiva pelo império após a posse do chanceler, tendo boa parte de seus integrantes mortos.&lt;/p&gt;

&lt;p&gt;Por sorte Ada recebeu ajuda de Kell, um guerreiro de Ankrah e com isso conseguiu sobreviver.&lt;/p&gt;

&lt;p&gt;Atualmente, declarada como morta, ela vive exilada na cidade de Valefor.
Ada é uma pessoa gentil e ponderada, tem um perfil conciliador e tenta ter uma perspectiva sobre tudo antes de tomar suas decisões. Ela se importa com seus amigos e é capaz de criar vínculos com facilidade.&lt;/p&gt;

&lt;h4 id=&quot;kell&quot;&gt;Kell&lt;/h4&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/g9qSceG.png&quot; class=&quot;materialboxed&quot; alt=&quot;Kell&quot; style=&quot;max-width: 50%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Um dos líderes da Armada, um grupo formado por soldados de Ankrah e Hetios que atua contra o chanceler e o império.&lt;/p&gt;

&lt;p&gt;Possui uma força física acima da média e é capaz de utilizar uma lança como poucos.&lt;/p&gt;

&lt;p&gt;Kell é taxado de extremista e até de terrorista por alguns, mas mesmo com isso, ele continua lutando contra a desigualdade e o ódio disseminado pelo chanceler e seu império. Ele possui um ódio latente no peito por conta das cicatrizes de seu passado, o que o faz, por vezes, perder a razão e partir para a força bruta.&lt;/p&gt;

&lt;h4 id=&quot;erling&quot;&gt;Erling&lt;/h4&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/ACIhZ0K.png&quot; class=&quot;materialboxed&quot; alt=&quot;Erling&quot; style=&quot;max-width: 50%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;É um alquimista formado na universidade de Alberta.&lt;/p&gt;

&lt;p&gt;Se auto declara o melhor alquimista do mundo. É capaz de combinar suas habilidades mágicas com a tecnologia de Alberta.&lt;/p&gt;

&lt;p&gt;Possui um grande senso de humor, é muito despreocupado e possui uma confiança excessiva que pode causar problemas.&lt;/p&gt;

&lt;h4 id=&quot;emmy&quot;&gt;Emmy&lt;/h4&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/POnMhXs.png&quot; class=&quot;materialboxed&quot; alt=&quot;Emmy&quot; style=&quot;max-width: 50%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Emmy teve uma infância muito feliz em Alberta, ao longo de sua vida ela percebeu que possuia uma conexão muito forte com o Elidriel, mas sem saber o real motivo por trás disso.
(Isso será revelado ao longo do jogo e não quero estragar a surpresa).&lt;/p&gt;

&lt;p&gt;Esse vínculo faz com que ela possua um conjunto de habilidades únicas!&lt;/p&gt;

&lt;p&gt;Emmy é uma pessoa hostil, ela tem dificuldades em confiar nas pessoas e julga a Armada e o Império como lados de uma mesma moeda. Passou por um longo período sendo prisioneira do império, isso fez com que ela criasse uma raiva latente dentro de si, e ao mesmo tempo uma paixão forte pela liberdade.&lt;/p&gt;

&lt;h3 id=&quot;mecânicas-e-sistemas&quot;&gt;Mecânicas e Sistemas&lt;/h3&gt;

&lt;h4 id=&quot;temperamento-das-criaturas&quot;&gt;Temperamento das Criaturas&lt;/h4&gt;

&lt;p&gt;As batalhas são iniciadas ao encontrar-se com a criatura no mapa.&lt;/p&gt;

&lt;p&gt;O comportamento das criaturas no mapa podem variar de acordo com seu temperamento, enquanto algumas podem querer evitar batalhar, outras poderão lhe seguir a todo custo!&lt;/p&gt;

&lt;p&gt;Cada criatura possui um dos quatro temperamentos possíveis: dócil, normal, agressivo e parado.&lt;/p&gt;

&lt;p&gt;Elas podem ser identificadas de acordo com a cor do ícone acima do inimigo.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/qsRPxE1.png&quot; class=&quot;materialboxed&quot; alt=&quot;Temperamento&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Dócil&lt;/strong&gt;: Estas são as criaturas mais dóceis, elas sempre tentarão fugir de você, para iniciar uma batalha é necessário seguí-las.
Geralmente estas batalhas são mais fáceis, mas podem existir criaturas poderosas que não gostam de batalhar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Normal&lt;/strong&gt;: Estas criaturas vagam livremente pelo ambiente e tentam aproximações curtas, geralmente é fácil evitá-las.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agressivo&lt;/strong&gt;: Estas criaturas são as mais selvagens, sempre que o virem tentarão uma aproximação para iniciar uma batalha.
São as mais difíceis de evitar e o seguem por mais tempo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parado&lt;/strong&gt;: Estas criaturas geralmente são as mais poderosas, é comum estarem protegendo um tesouro ou alguém. Irão se manter imovéis e a batalha só será
iniciada por sua iniciativa.&lt;/p&gt;

&lt;h4 id=&quot;talentos&quot;&gt;Talentos&lt;/h4&gt;

&lt;p&gt;Cada um dos protagonistas possui um talento próprio, isso são habilidades que podem ser utilizadas fora de batalhas para interação com o ambiente.&lt;/p&gt;

&lt;p&gt;É possível visualizar no canto esquerdo da tela uma barra contendo o nome do talento do líder da equipe e a energia para utilizá-lo. Você só pode utilizar o talento quando a energia estiver no máximo, ao esgotar-se ela reiniciará automaticamente.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/xa2sFH3.png&quot; class=&quot;materialboxed&quot; alt=&quot;Talentos&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Ada - Modo Furtivo:&lt;/strong&gt; O talento de Ada permite que ela ande por locais sem ser notada por criaturas ou outras pessoas, utilizada em missões de espionagem ao longo do projeto.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kell - Super Força:&lt;/strong&gt; Permite empurrar ou quebrar objetos que estão bloqueando o caminho.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Erling - Detecção Mágica:&lt;/strong&gt;: Permite visualizar ítens e passagens ocultas no mapa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Emmy - Manipulação Temporal:&lt;/strong&gt; Permite alterar a forma que o tempo passa em determinados objetos (incluindo na pescaria).&lt;/p&gt;

&lt;h4 id=&quot;ferramentas&quot;&gt;Ferramentas&lt;/h4&gt;

&lt;p&gt;As ferramentas são um equipamento especial do projeto, assim como os talentos elas permitem que os personagens interajam com o ambiente de diferentes formas. Você pode utilizar apenas a ferramenta equipada no líder da equipe.&lt;/p&gt;

&lt;p&gt;Outra característica das ferramentas é que cada um dos personagens possui um nível de habilidade em cada uma delas, este nível aumenta conforme o uso da ferramenta específica:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/K6SIDxQ.png&quot; class=&quot;materialboxed&quot; alt=&quot;Ferramentas&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/ct7PAl2.png&quot; class=&quot;materialboxed&quot; alt=&quot;Mineração&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;
&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/NohFRr3.png&quot; class=&quot;materialboxed&quot; alt=&quot;Pescaria&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;h3 id=&quot;batalha&quot;&gt;Batalha&lt;/h3&gt;

&lt;p&gt;O jogo utiliza batalha lateral com uma mecânica de manipulação de turnos, através de técnicas você pode alterar a ordem das ações dos personagens e dos inimigos, cancelar ações e até mesmo realizar mais de uma ação no mesmo turno.&lt;/p&gt;

&lt;p&gt;Além disso, o jogo conta com um sistema de atordoamento de inimigos, você possui mecânismos para explorar as fraquezas do oponente e remover a resistência de sua defesa.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/03LKG38.png&quot; class=&quot;materialboxed&quot; alt=&quot;Sob pressão&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Normalmente a resistência é representada por uma barra branca abaixo do HP do inimigo, ao acertar o inimigo com um golpe que causa dano significativo à resistência o inimigo entrará no estado de Pressionado, neste estado a barra fica com uma colocaração rosada e os danos na resistência aumentam significativamente.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/DEnoXW8.png&quot; class=&quot;materialboxed&quot; alt=&quot;Atordoado&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Quando você quebra toda a resistência de um inimigo com sucesso a barra ficará vermelha, ele entrará no estado Atordoado e ficará duas ações sem jogar.&lt;/p&gt;

&lt;h3 id=&quot;galeria&quot;&gt;Galeria&lt;/h3&gt;

&lt;div class=&quot;row&quot;&gt;
&lt;div class=&quot;col s12&quot;&gt;
 &lt;div class=&quot;carousel&quot; style=&quot;height:450px;margin-bottom:40px;margin-top:-150px;&quot;&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/DsvHSCB.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/DsvHSCB.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/Yvcj5QB.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/Yvcj5QB.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/py9jMOJ.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/py9jMOJ.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/iEuP6g5.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/iEuP6g5.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/9K499tF.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/9K499tF.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/pNheUW8.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/pNheUW8.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://imgur.com/PVGJ5Cv.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/PVGJ5Cv.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/B5J5pjf.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/B5J5pjf.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/BwqwOv0.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/BwqwOv0.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/plZIX9O.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/plZIX9O.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/t8RPd78.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/t8RPd78.png&quot; /&gt;
    &lt;/a&gt;
    &lt;a class=&quot;carousel-item&quot; href=&quot;https://i.imgur.com/EpuLs0N.png&quot; target=&quot;_blank&quot;&gt;
        &lt;img src=&quot;https://imgur.com/EpuLs0N.png&quot; /&gt;
    &lt;/a&gt;
  &lt;/div&gt;
  &lt;/div&gt; 
&lt;/div&gt;

&lt;p&gt;Você pode fazer o download &lt;a href=&quot;https://drive.google.com/file/d/1kktFMYJH4wWIn6JAjXChg9-KpCtAN2TH/view?usp=sharing&quot;&gt;neste link&lt;/a&gt; via Google Drive e &lt;a href=&quot;https://www.mediafire.com/file/vq8maf0lsx9fuxk/Elidriel.rar/file&quot;&gt;neste link&lt;/a&gt; via MediaFire.&lt;/p&gt;

&lt;p&gt;Eu espero muito que você se divirta nessas 5 horas e por favor, deixe seu feedback aqui!&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Tue, 02 Jun 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/06/02/Elidriel.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/06/02/Elidriel.html</guid>
        
        <category>Discussões</category>
        
        <category>JavaScript</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Café Debug:  Programação funcional, um jeito diferente de programar!</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Eu participei do podcast Café Debug sobre programação funcional, que tal dar uma olhada?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Neste episódio eu e a queridíssima &lt;a href=&quot;https://twitter.com/JessicaNathanyF&quot;&gt;Jéssica Nathany&lt;/a&gt; conversamos sobre programação funcional. Ok, mas qual parte?&lt;/p&gt;

&lt;p&gt;Passamos uma visão macro por quase tudo sobre o tema nesse bate papo super tranquilo.&lt;/p&gt;

&lt;p&gt;Segue o episódio:&lt;/p&gt;
&lt;div&gt;
    &lt;iframe src=&quot;https://open.spotify.com/embed-podcast/episode/3ZjaWvrZm1tghAjYOBslji&quot; width=&quot;100%&quot; height=&quot;232&quot; frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; allow=&quot;encrypted-media&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Queria também aproveitar para agradecer o convite e que venham mais parcerias!&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Sun, 10 May 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/05/10/cafeDebug.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/05/10/cafeDebug.html</guid>
        
        <category>Discussões</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>5 coisas que eu queria que tivessem me contado no início da carreira</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Eu participei da live do Geek Hunter um tempão atrás, que tal tirar um tempo para dar uma olhada nela?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Nesta live tentei passar um pouco da minha experiência para quem está começando agora.&lt;/p&gt;

&lt;p&gt;Nela eu falo sobre cinco coisas que acho que é importante ter ciência desde o início da carreira, mas lembrando claro, que isso tem muito a ver com a minha experiência pessoal e não é necessariamente uma verdade para todo mundo.&lt;/p&gt;

&lt;p&gt;Segue o vídeo:&lt;/p&gt;

&lt;div&gt;
&lt;iframe class=&quot;z-depth-2&quot; style=&quot;margin: 0 auto;display: block;margin-bottom:15px;&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/6NM_Tb-LVIM&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Queria também aproveitar para agradecer o convite para participar e que venham mais parcerias!&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Tue, 14 Apr 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/04/14/geekhunter.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/04/14/geekhunter.html</guid>
        
        <category>Discussões</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Hipsters ponto tech: Algoritmos e estrutura de dados</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Se você viu o post passado, sabe que minha vida deu uma boa mudada, sei não estou dando tanta atenção por aqui, mas a frequência de publicações voltará a aumentar assim que tudo estabilizar novamente.&lt;/p&gt;

&lt;p&gt;Para quem não viu, semana passada participei do Hipsters ponto tech!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;No podcast falamos sobre um assunto que adoro discutir por aqui: Algoritmos e estrutura de dados!&lt;/p&gt;

&lt;p&gt;É importante? Não é? Como ganhar 1 milhão de dólares resolvendo um problema de computação?&lt;/p&gt;

&lt;p&gt;Discutimos essas coisas por lá, dá uma conferida no &lt;a href=&quot;https://hipsters.tech/algoritmos-e-estrutura-de-dados-hipsters-186/&quot; target=&quot;_blank&quot;&gt;episódio&lt;/a&gt;:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/K9n3qE3.png&quot; class=&quot;materialboxed&quot; alt=&quot;Banner episodio&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;
&lt;div class=&quot;frame-layer-responsive&quot;&gt;
    &lt;iframe class=&quot;z-depth-2&quot; style=&quot;margin: 0 auto;margin-bottom:15px;&quot; width=&quot;320&quot; height=&quot;40&quot; src=&quot;https://hipsters.tech/?powerpress_embed=2916-podcast&amp;amp;powerpress_player=mediaelement-audio&quot; frameborder=&quot;0&quot;&gt;&lt;/iframe&gt;
    &lt;blockquote&gt;
        &lt;p&gt;&lt;strong&gt;Atenção&lt;/strong&gt;&lt;/p&gt;
        &lt;p class=&quot;mobile-message&quot;&gt;
            Como você está em um dispositivo móvel a visualização do gráfico pode ser comprometida, acesse &lt;a href=&quot;https://hipsters.tech/?powerpress_embed=2916-podcast&amp;amp;powerpress_player=mediaelement-audio&quot; target=&quot;_blank&quot;&gt;este link&lt;/a&gt; para ver o gráfico em tela cheia.
        &lt;/p&gt;
    &lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Queria também aproveitar para agradecer o convite para participar e que venham os próximos!&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, tenham todos um feliz novo e um ótimo recomeço e que final de 2020 eu e você possamos comemorar mais um monte de conquistas!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Wed, 12 Feb 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/02/12/hispters.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/02/12/hispters.html</guid>
        
        <category>Discussões</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Minha Retrospectiva 2019</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Esse ano foi demais, teve muita, mas muita coisa boa acontecendo.&lt;/p&gt;

&lt;p&gt;Passou aqui pelo blog aproximadamente &lt;strong&gt;200 mil visitas únicas&lt;/strong&gt; e &lt;strong&gt;20 mil leituras&lt;/strong&gt; lá no medium. Além de palestras ao vivo, viagens para 7 países diferentes e algumas conquistas que me enchem de orgulho!&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Como não pretendo fazer esse post muito longo, vamos direto para os &lt;em&gt;highlights&lt;/em&gt;!&lt;/p&gt;

&lt;h4 id=&quot;microsoft-mvp-summit&quot;&gt;Microsoft MVP Summit&lt;/h4&gt;

&lt;p&gt;O primeiro grande &lt;em&gt;highlight&lt;/em&gt; do ano certamente foi o Microsoft MVP Summit, um evento que rola todo ano lá na matriz da Microsoft em Seattle, onde os Microsoft MVPs do mundo todo são convidados para uma série de palestras técnicas e anúncios do que chega de novo para o próximo ano nas tecnologias Microsoft.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/UAogxvb.png&quot; class=&quot;materialboxed&quot; alt=&quot;Microsoft&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Como recebi esse prêmio ano passado, esse foi o meu primeiro ano no evento e apesar de ter escutado reclamações, para mim tudo foi fantástico! Não tem como descrever a experiência de conhecer uma galera tão foda.&lt;/p&gt;

&lt;p&gt;As pessoas que constroem as ferramentas que eu usava no dia a dia para trabalhar. E não só isso, ter a oportunidade de se encontrar com outros MVPs do Brasil e do mundo.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/Ugn6cfZ.png&quot; class=&quot;materialboxed&quot; alt=&quot;MVP Summit&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Fiz diversas amizades nessa viagem e sem dúvida nenhuma, esse evento vai ficar na memória!&lt;/p&gt;

&lt;p&gt;Antes do primeiro dia de evento fiz um passeio rápido por Toronto, foi só um diazinho, mas deu para aproveitar algumas coisas, como a CB Tower por exemplo, uma das maiores torres do mundo! (E vencer o medo de altura, como faz?)&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/tvPjRUq.png&quot; class=&quot;materialboxed&quot; alt=&quot;CB Tower&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Depois de um dia de passeio, o evento começou pra valer!&lt;/p&gt;

&lt;p&gt;Teve muito conteúdo e claro, uma dose de realidade para ver o quanto a gente ainda precisa aprender. De quebra, ainda tive a oportunidade de conhecer o estúdio do &lt;a href=&quot;https://channel9.msdn.com/Browse&quot; target=&quot;_blank&quot;&gt;Channel 9&lt;/a&gt;, um canal de vídeos de treinamentos da Microsoft.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/E67j14x.png&quot; class=&quot;materialboxed&quot; alt=&quot;Channel 9&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Aproveitando Seattle, fiz mais alguns rolês, até porque ninguém é de ferro né? Teve Space Needle, museu da cultura pop e tudo mais que tinha direito.&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/aGi9JTO.png&quot; class=&quot;materialboxed&quot; alt=&quot;Space Needle&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;h4 id=&quot;eventos-técnicos-de-abril&quot;&gt;Eventos Técnicos de Abril&lt;/h4&gt;

&lt;p&gt;Abril foi um mês com alguns eventos bem legais, logo no início palestrei sobre Machine Learning no InterOP, lá em Florianópolis. Um pouco depois, junto com a galera da Qualyteam, organizei o evento de lançamento do Visual Studio 2019 em Balneário Camboriu e por último e não menos importante, aconteceu o TDC (The Developer’s Conference) mais um vez em Floripa.&lt;/p&gt;

&lt;p&gt;Neste último evento tive a honra de ministrar quatro palestras e ser coordenador das trilhas .NET e INSPIRE.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;INSPIRE&lt;/strong&gt; é uma trilha fantástica focada em introduzir jovens e adolescentes à área de tecnologia. Falei isso alguma vezes no evento e acho que vale repetir aqui: &lt;strong&gt;O objetivo disso não é dizer que a área de tecnologia é o único caminho, mas sim, mostrar para os jovens que se eles quiserem seguir essa área, tem gente disposta a estender a mão&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Tenho muito orgulho de ter participado disso e aqui fica um vídeo para quem tiver curiosidade sobre essa trilha do evento:&lt;/p&gt;

&lt;div&gt;
&lt;iframe class=&quot;z-depth-2&quot; style=&quot;margin: 0 auto;display: block;margin-bottom:15px;&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/NfGmwsUe0Z4?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Além disso, esse TDC também teve um outro momento bastante especial para mim.&lt;/p&gt;

&lt;p&gt;Apesar de participar do evento há alguns anos, foi a primeira vez que tive a honra de poder palestrar no palco principal. Minha palestra foi sobre reconhecimento de letras em libras através de algoritmos de &lt;em&gt;machine learning&lt;/em&gt; (AI).&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/jTlzkIj.png&quot; class=&quot;materialboxed&quot; alt=&quot;TDC&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;h4 id=&quot;nerdologia&quot;&gt;Nerdologia&lt;/h4&gt;

&lt;p&gt;Ainda em abril decidi fazer &lt;a href=&quot;/2019/04/04/avengers-joia-tempo-heuristica.html&quot; target=&quot;_blank&quot;&gt;este post&lt;/a&gt; sobre como o Doutor Estranho dos Vingadores poderia navegar pelas possibilidades vistas pela jóia do tempo de maneira eficiente.&lt;/p&gt;

&lt;p&gt;Esse post foi feito com base em um vídeo do &lt;a href=&quot;https://www.youtube.com/nerdologia&quot;&gt;Nerdologia&lt;/a&gt;, que na minha visão é um dos melhores canais do YouTube. E imagine a minha felicidade quando fui citado por lá?&lt;/p&gt;

&lt;div&gt;
&lt;iframe class=&quot;z-depth-2&quot; style=&quot;margin: 0 auto;display: block;margin-bottom:15px;&quot; width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/lrtVyvgmN_I&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;

&lt;p&gt;Bem no finalzinho o Átila, biólogo, pesquisador e pessoa que me deixou maluco ao me citar, comenta sobre esse meu post.&lt;/p&gt;

&lt;p&gt;Para me deixar ainda mais animado, isso tudo aconteceu em um dos vídeos que mais gosto (mas talvez eu tenha um pouco de viés né?)&lt;/p&gt;

&lt;h4 id=&quot;open-source-e-publicações-imasters-e-no-microsoft-tech&quot;&gt;Open Source e Publicações iMasters e no Microsoft Tech&lt;/h4&gt;

&lt;p&gt;Também foi em 2019 que a minha biblioteca de programação funcional a &lt;a href=&quot;https://github.com/gabrielschade/tango&quot; target=&quot;_blank&quot;&gt;Tango&lt;/a&gt;, “explodiu”. Nesse ano a biblioteca atingiu a marca de mais de 55 mil downloads, tendo uma média de 50 instalações por dia.&lt;/p&gt;

&lt;p&gt;É inacreditável pensar que 50 instalações são feitas todos os dias de algo que eu criei.&lt;/p&gt;

&lt;p&gt;Ainda em 2019 que comecei a publicar artigos pelo site &lt;a href=&quot;https://imasters.com.br/perfil/gabrielschade&quot; target=&quot;_blank&quot;&gt;iMasters&lt;/a&gt; e desde então aproximadamente 17 mil pessoas começaram a ler meus posts por lá! É sempre muito maneiro poder alcançar mais gente.&lt;/p&gt;

&lt;p&gt;No blog da Microsoft, o Microsoft Tech minha ação foi bem mais pontual. Tive só um &lt;a href=&quot;http://www.microsofttech.com.br/pt-br/microsofttech/ml-net-inteligencia-artificial-ia-para-ajudar-o-detetive-pikachu-com-descobertas-sobre-pokemon/&quot; target=&quot;_blank&quot;&gt;post&lt;/a&gt; publicado por lá, mas confesso que é um dos que eu mais tenho orgulho de ter feito aqui no blog.&lt;/p&gt;

&lt;p&gt;Este &lt;a href=&quot;/2019/06/10/ml-net-ii-pikachu-detective.html&quot; target=&quot;_blank&quot;&gt;post sobre IA aplicada à uma base de dados de pokémon&lt;/a&gt; deu um trabalho monstro, mas acho que o resultado ficou bem bacana, se ainda não viu, dá uma conferida lá.&lt;/p&gt;

&lt;h4 id=&quot;intercâmbio-na-irlanda-e-viagens&quot;&gt;Intercâmbio na Irlanda e Viagens&lt;/h4&gt;

&lt;p&gt;Em maio foi onde o maior ponto de virada aconteceu, eu e minha esposa viemos para &lt;strong&gt;Dublin, Irlanda&lt;/strong&gt; para fazer um intercâmbio para melhorar o inglês.&lt;/p&gt;

&lt;p&gt;Isso significou: largar o emprego e ficar longe da família e de amigos. Mas é impossível não se sentir super privilegiado por ter uma oportunidade dessas.&lt;/p&gt;

&lt;p&gt;Porque apesar do que eu falei, isso tornou possível conhecer muito mais gente, muito mais lugares, culturas e ter várias novas experiências.&lt;/p&gt;

&lt;p&gt;Desde que cheguei aqui, minha esposa e eu visitamos: Amsterdam (um diazinho só), Londres, Paris e Belfast. É até difícil de descrever o quão transformador isso foi e está sendo para mim.&lt;/p&gt;

&lt;h4 id=&quot;renovação-do-programa-microsoft-mvp&quot;&gt;Renovação do Programa Microsoft MVP&lt;/h4&gt;

&lt;p&gt;Em julho recebi a notícia que minha premiação como &lt;a href=&quot;https://mvp.microsoft.com/&quot;&gt;Microsoft MVP&lt;/a&gt; tinha sido renovada, mais uma vez na categoria &lt;em&gt;Developer Technologies&lt;/em&gt;. Fiquei muito feliz em receber o prêmio por mais um ano, apesar de ser um pouco de vaidade, sempre dá um quentinho no coração ser reconhecido por compartilhar conhecimento.&lt;/p&gt;

&lt;p&gt;Mesmo estando bem feliz com a premiação, me mantive no programa por bem pouco tempo após a renovação. Já em outubro, eu mesmo fiz a ligação pedindo para ser desligado do programa da Microsoft.&lt;/p&gt;

&lt;p&gt;Normalmente sair do programa MVP seria uma coisa muito triste, mas neste caso específico foi por conta de uma conquista, então definitivamente não era tempo de ficar triste, mas sim, de &lt;strong&gt;celebrar&lt;/strong&gt;!&lt;/p&gt;

&lt;h4 id=&quot;me-tornei-um-amazonian&quot;&gt;Me tornei um Amazonian&lt;/h4&gt;

&lt;p&gt;Bom, o motivo de eu ter saído do programa Microsoft MVP é por ter recebido (e aceitado, claro) uma oferta para trabalhar como &lt;em&gt;software engineer&lt;/em&gt; na Amazon aqui em Dublin!&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/TVHatR3.png&quot; class=&quot;materialboxed&quot; alt=&quot;AWS&quot; style=&quot;max-width: 100%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Eu não consigo descrever o tamanho dessa conquista, de verdade. Parece surreal.&lt;/p&gt;

&lt;p&gt;Foi uma mudança gigantesca de carreira, troquei praticamente todo o conjunto de tecnologias que eu estava acostumado a trabalhar, mas sabe do que mais? Está sendo &lt;strong&gt;maravilhoso&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Eu sei que pode soar um pouco clichê, mas sair da zona de conforto e conseguir impactar literalmente milhões/bilhões de pessoas é inacreditavelmente recompensador.&lt;/p&gt;

&lt;h4 id=&quot;que-venha-2020&quot;&gt;Que venha 2020&lt;/h4&gt;

&lt;p&gt;Novo ano, novos tempos e eu não quero cair no papo de auto-ajuda, mas esse ano foi de fato, recheado de realizações e vitórias. Eu sei que não é assim tão simples, e que o caminho pode ser mais difícil pra uns do que para os outros, mas corre atrás do sonho, &lt;strong&gt;sério&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Eu sei que tive a sorte de conhecer muita gente incrível ao longo da minha carreira e isso foi algo que abriu muitas portas. Além disso, também tento ser ciente de que tive a sorte de ter muitos privilégios: nasci em uma família classe média, o que já implica em: nunca passar fome, não viver em uma área perigosa, nunca faltou grana em casa (até tivemos momentos de bastante fartura) e todas essas coisas.&lt;/p&gt;

&lt;p&gt;Além disso, eu sei que também tive a sorte de ter os pais que tive. Apesar das dificuldades, meus pais fizeram de tudo e mais um pouco para que eu tivesse uma &lt;strong&gt;educação&lt;/strong&gt; de qualidade. Eles terem se importado tanto com isso é uma coisa que eu até vou tentar, mas acho que nunca vou ser capaz de retribuir.&lt;/p&gt;

&lt;p&gt;Eu não quero tentar politizar nada, mas é impossível falar de educação sem falar dos tempos atuais, em que infelizmente várias teorias da conspiração, obscurantismos e movimentos anticiência (terra plana, antivacina e por aí vai) vem ganhando força.&lt;/p&gt;

&lt;p&gt;Sério, se você realmente quer fazer algo contra “o sistema”, estudar e entender como a ciência funciona ainda é uma das maiores revoluções que você pode fazer.&lt;/p&gt;

&lt;p&gt;Eu compartilho o pouco do que sei aqui no blog, porque foi saber esse pouquinho, que tornou possível que, eu, o filho da dona de casa Eulália e do pescador João, morasse na Europa e começasse trabalhar como &lt;em&gt;software engineer&lt;/em&gt; em uma das maiores empresas do mundo.&lt;/p&gt;

&lt;p&gt;Mais uma vez: corre atrás do seu sonho.&lt;/p&gt;

&lt;p&gt;Tá, talvez eu tenha caído um pouco no auto-ajuda, mas de qualquer forma, se eu puder ajudar uma pessoa com essa mensagem, já valeu a pena.&lt;/p&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, tenham todos um feliz novo e um ótimo recomeço e que final de 2020 eu e você possamos comemorar mais um monte de conquistas!&lt;/p&gt;

&lt;p&gt;E até o próximo post!&lt;/p&gt;
</description>
        <pubDate>Tue, 07 Jan 2020 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2020/01/07/2019-retro.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2020/01/07/2019-retro.html</guid>
        
        <category>Discussões</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Construindo Uma Lista Encadeada (Linked List)</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Vamos continuar a série sobre estrutura de dados? -Dessa vez com listas encadeadas (ou listas ligadas).&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;a id=&quot;github-link&quot; title=&quot;Github&quot; href=&quot;https://github.com/gabrielschade/algorithms/blob/master/DataStructures/DataStructures.JavaScript/LinkedList.js&quot; target=&quot;_blank&quot; class=&quot;github-fixed-button none-decoration&quot;&gt;
    &lt;img class=&quot;icon&quot; src=&quot;/public/icons/GitHub.png&quot; style=&quot;display:inline;border-radius: 0;&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Este é o terceiro post sobre estrutura de dados aqui no blog, dessa vez falaremos sobre listas encadeadas ou &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Linked Lists&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Se ainda não leu, recomendo que você também leia o post sobre &lt;a href=&quot;/2019/06/24/algoritmos-ii.html&quot; target=&quot;_blank&quot;&gt;pilhas&lt;/a&gt; e &lt;a href=&quot;/2019/07/08/algoritmos-iii.html&quot; target=&quot;_blank&quot;&gt;filas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Agora vamos ao assunto do post.&lt;/p&gt;

&lt;h4 id=&quot;linked-list&quot;&gt;Linked List&lt;/h4&gt;

&lt;p&gt;O conceito principal de listas encadeadas ou &lt;strong&gt;linked lists&lt;/strong&gt; é bastante simples, nessa estrutura de dados os elementos não são armazenados em memória contígua, assim como um array. Mas peraí, o que é uma memória contígua?&lt;/p&gt;

&lt;p&gt;Em poucas palavras, memória contígua é um bloco de memória subsequente alocado de uma vez só. Esse é um dos motivos pelo qual normalmente precisamos explicitar o tamanho de um array para alocá-lo. O programa irá reservar um bloco contínuo de acordo com o tamanho do array.&lt;/p&gt;

&lt;p&gt;Por que fazemos isso? A resposta simples é, porque é, de maneira geral, mais rápido. Afinal, o programa não irá precisar procurar fisicamente na memória o próximo elemento, ele está alocado fisicamente ao lado do anterior.&lt;/p&gt;

&lt;p&gt;Maaaas, se a memória não é alocada de maneira unificada, como saberemos onde está o próximo elemento?&lt;/p&gt;

&lt;p&gt;As listas encadeadas são baseadas em máquinas de ponteiros, de maneira MUITO resumida, isso significa que cada elemento possui o endereço da memória (&lt;em&gt;ponteiro&lt;/em&gt;) para o elemento seguinte.&lt;/p&gt;

&lt;p&gt;Se você acompanhou os posts anteriores, deve ter notado que quando criamos a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stack&lt;/code&gt; e a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Queue&lt;/code&gt; já utilizamos essa abordagem, isso quer dizer que elas também eram listas encadeadas?&lt;/p&gt;

&lt;p&gt;Não exatamente, porque possuíam comportamentos encapsulados que as definem como pilhas e filas, mas a maneira como os nós estavam organizados era exatamente igual à uma lista encadeada.&lt;/p&gt;

&lt;p&gt;Diferente das pilhas e filas, nós podemos acessar qualquer elemento da lista encadeada, sem exceção.&lt;/p&gt;

&lt;h4 id=&quot;linkedlistnode&quot;&gt;LinkedListNode&lt;/h4&gt;

&lt;p&gt;Para esta estrutura de dados, talvez o nó seja mais importante do que a própria estrutura. Isso fica ainda mais evidente quando resolvemos exercícios sobre listas encadeadas, normalmente nos é oferecido apenas um nó, ao invés de um objeto com a lista. Isso porque através do primeiro nó, podemos percorrer a lista completa.&lt;/p&gt;

&lt;p&gt;Vamos definir essa classe, ela é bastante simples, basta armazenarmos o valor e o ponteiro para o próximo nó.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LinkedListNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h4 id=&quot;estrutura-principal&quot;&gt;Estrutura Principal&lt;/h4&gt;

&lt;p&gt;Como mencionei antes, em vários momentos não precisamos de uma estrutura principal para trabalharmos com listas encadeadas, mas para deixar o post um pouco mais completo, vamos criá-la:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Podemos dar uma pequena incrementada, fazendo com que nosso construtor também aceite um array como parâmetro:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LinkedList&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;element&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Você já deve ter notado que estamos usando o método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt; que ainda não existe, mas não se preocupe com isso agora. Vamos só assumir que ele adiciona um elemento na última posição da lista encadeada.&lt;/p&gt;

&lt;p&gt;Agora vamos criar as propriedades para mantermos a lista:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;isEmpty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As propriedades são bastante simples de entender, temos uma que define o tamanho da lista, uma para identificar se a lista está vazia ou não e a outra para identificar o primeiro elemento da lista. Só isso.&lt;/p&gt;

&lt;p&gt;Agora vamos começar a implementar os métodos!&lt;/p&gt;

&lt;p&gt;Vamos precisar de algumas operações nessa classe: adicionar um novo elemento em qualquer posição, remover um elemento de uma posição e claro, obter o valor de um elemento em uma posição específica.&lt;/p&gt;

&lt;p&gt;Um ponto de atenção aqui é que tanto para adicionar um novo elemento, quanto para remover, precisaremos antes, encontrar a posição para fazer isso. Portanto, é justo começarmos a implementação pelo método de busca.&lt;/p&gt;

&lt;h4 id=&quot;get---on&quot;&gt;Get - O(n)&lt;/h4&gt;

&lt;p&gt;Esse é um ponto que define a principal diferença entre uma lista encadeada e uma lista “normal”. Em uma lista normal podemos acessar o elemento em complexidade O(1), basta sabermos seu índice. No caso da lista encadeada precisamos necessariamente começar no primeiro elemento e percorrer a lista até o índice informado.&lt;/p&gt;

&lt;p&gt;O que nos leva ao pior caso, onde percorremos a lista completa: O(n).&lt;/p&gt;

&lt;p&gt;Nossa função de busca não irá definir comportamento nenhum, ela simplesmente vai retornar o nó atual e o nó anterior (para a operação de exclusão).&lt;/p&gt;

&lt;p&gt;Para fazer isso, basta utilizarmos um laço de repetição e continuarmos obtendo o próximo elemento da lista até chegarmos no índice definido:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;_getByIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;previousNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Com este método implementado, podemos criar uma variação para retornar apenas o valor do nó informado de maneira bastante simples:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_getByIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Agora vamos para as operações onde a lista encadeada brilha!&lt;/p&gt;

&lt;h4 id=&quot;insert---o1--on&quot;&gt;Insert - O(1) / O(n)&lt;/h4&gt;

&lt;p&gt;Diferente de uma lista comum, na lista encadeada a operação de inserção possui complexidade constante. Isso porque em uma lista comum teríamos que copiar todos os elementos do array para o próximo índice, enquanto que na lista encadeada apenas reorganizamos os ponteiros.&lt;/p&gt;

&lt;p&gt;Assim como fizemos no método de busca, primeiro vamos implementar um método que esconde boa parte da complexidade de inserção. Este método recebe por parâmetro o nó anterior ao nó que será adicionado e o valor do novo nó. Com isso podemos reorganizar os ponteiros e fazer com que a lista continue íntegra.&lt;/p&gt;

&lt;p&gt;Além disso, precisamos lembrar de duas coisas: alterar o valor da propriedade &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;head&lt;/code&gt; nos casos onde o nó anterior ao nó que será inserido seja nulo e incrementarmos a propriedade &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;size&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LinkedListNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;newNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Agora que este método está implementado precisamos implementar o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insertAt&lt;/code&gt;, método que recebe o valor a ser inserido e o índice para inserção. Podemos obter o nó através da função de busca criada anteriormente:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;insertAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previous&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_getByIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previous&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Também podemos criar métodos para inclusão no início (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt;) e fim (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt;) da lista:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;insertAt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;Importante&lt;/strong&gt;&lt;/p&gt;

  &lt;p&gt;O método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insert&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add&lt;/code&gt; possuem complexidade O(1), o método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;insertAt&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;append&lt;/code&gt; possuem complexidade O(n), visto que utilizamos internamente o método de busca.
No entanto, vale lembrar que é muito comum utilizarmos os nós diretamente, como já mencionei antes, por conta disso, a complexidade de uma lista encadeada é comumente referida como O(1), porque nos casos onde você possui o nó, ela é de fato constante.
Isso também vale para a função de exclusão.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4 id=&quot;remove---o1--on&quot;&gt;Remove - O(1) / O(n)&lt;/h4&gt;

&lt;p&gt;Para a função de exclusão, iremos implementar apenas a função baseada no índice, ela é bastante simples em termos de entendimento. Basta localizarmos o nó que desejamos excluir e o nó anterior (a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getByIndex&lt;/code&gt; já nos entrega isso) e reorganizarmos os ponteiros, veja:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_getByIndex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;index&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousNode&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;previousNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_head&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentNode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_size&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Com isso completamos nossas funcionalidades básicas de uma lista encadeada. No entanto ainda podemos criar interfaces para melhorar o consumo dela.&lt;/p&gt;

&lt;p&gt;A primeira coisa é fazer ela ser iterável através do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;for of&lt;/code&gt; como fizemos no array no construtor, veja:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Symbol&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;iterator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Agora podemos percorrer os elementos como se ela fosse um array normal:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;linkedList&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;LinkedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;linkedList&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;){&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;//10&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//2&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//3&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//5&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Legal né?&lt;/p&gt;

&lt;p&gt;Ainda podemos finalizar com o famoso &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;toArray&lt;/code&gt;, onde simplesmente iremos percorrer os nós e inserir seus respectivos valores em um array:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nx&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[];&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;node&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Bom, o post de hoje era isso!&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até mais.&lt;/p&gt;
</description>
        <pubDate>Wed, 13 Nov 2019 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2019/11/13/linkedlists.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2019/11/13/linkedlists.html</guid>
        
        <category>JavaScript</category>
        
        <category>Algoritmos</category>
        
        
      </item>
      
    
      
      
      
      <item>
        <title>Async em F#</title>
        <description>&lt;p&gt;Olá pessoa!&lt;/p&gt;

&lt;p&gt;Que tal entendermos como funciona uma pipeline usando o Async em F#?&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;a id=&quot;github-link&quot; title=&quot;Github&quot; href=&quot;https://github.com/gabrielschade/posts-blog/blob/master/AsyncWorkflow/AsyncWorkflow/Program.fs&quot; target=&quot;_blank&quot; class=&quot;github-fixed-button none-decoration&quot;&gt;
    &lt;img class=&quot;icon&quot; src=&quot;/public/icons/GitHub.png&quot; style=&quot;display:inline;border-radius: 0;&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A ideia principal deste post é cobrir os fundamentos básicos para programação assíncrona em F#.&lt;/p&gt;

&lt;p&gt;Ué, mas F# não é .NET? -É só utilizarmos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tasks&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;Ok, F# é sim .NET e você pode sim utilizar &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt;, mas temos alguns probleminhas nisso. O primeiro é que a classe &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt; foi feita para trabalhar com o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;delegate Action&lt;/code&gt;. No C# até temos uma conversão implícita entre uma função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;void&lt;/code&gt; e esse delegate, mas isso não é verdade para F#, então teríamos que converter na mão.&lt;/p&gt;

&lt;p&gt;Outro ponto que é inclusive mais importante que esse primeiro é o fato de que geralmente operações mais longas em F# são realizadas através de pipelines, veja um exemplo:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atualizarCliente&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;verificaSeClienteExiste&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;verificaNomeOuSobrenomeEmBranco&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;verificaFormatoEmail&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;verificaFormatoCPF&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformarInicialNomeEmMaiusculo&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;atualizarClienteNoBanco&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transformarListaEmResposta&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Não precisamos entender o código interno da função, basta entendermos que geralmente um funcionalidade é implementada através da composição de diferentes funções menores.&lt;/p&gt;

&lt;p&gt;Simplesmente não conseguimos utilizar um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; como no C#, porque todas as chamadas resultam em uma única expressão e não vários &lt;em&gt;statements&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Uma outra diferença que vale a pena ser destacada aqui é que uma &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt; em .NET produz um valor depois de seu processamento e se encerra, enquanto um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; é apenas um bloco que explicitamente precisa ser avaliado. Isso significa que, se você quiser o fazer qualquer tipo de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cache&lt;/code&gt; no resultado, é necessário fazer isso explicitamente.&lt;/p&gt;

&lt;p&gt;Como último lembrete, como praticamente tudo no C# e F# são “conversáveis”, temos transformações do tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Task&lt;/code&gt; para o tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; dentro do módulo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; através das funções: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async.StartAsTask&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async.AwaitTask&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Existem mais complexidades no meio disso e até alguns comportamentos inesperados que podem acontecer quando utilizamos &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tasks&lt;/code&gt; dentro do F# sem prestar as devidas atenções, mas isso fica para um outro post.&lt;/p&gt;

&lt;p&gt;Para deixar o código com mais cara de F#, temos outro recurso para programação assíncrona chamado &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt;. Ele é trazido para o F# no formato de um &lt;em&gt;computation express&lt;/em&gt;, eu falei disso brevemente aqui no blog &lt;a href=&quot;/2018/11/27/computation-express-1.html&quot; target=&quot;_blank&quot;&gt;neste post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Vamos começar fazendo um exemplo bastante simples e depois disso, vamos paralelizar sua execução. A tarefa será simplesmente lermos o HTML de alguns sites diferentes, só isso.&lt;/p&gt;

&lt;p&gt;Para podermos fazer isso, precisamos importar o namespace &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Net&lt;/code&gt; e &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.IO&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Net&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;open&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;IO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Depois disso, vamos criar uma função que receba uma URL por parâmetro e fazer uma requisição para a página:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fetchUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;WebRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponse&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponseStream&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReadToEnd&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished reading %s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Esse código é relativamente simples, mas vamos lembrar de algumas coisas aqui:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Estamos fazendo uma requisição HTTP normal para obter a página informada na URL;&lt;/li&gt;
  &lt;li&gt;Estamos usando o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReadToEnd&lt;/code&gt; para simplificar, mas no “mundo real”, leia linha por linha sempre que possível, isso pode evitar problemas com consumo de memória.&lt;/li&gt;
  &lt;li&gt;Entender a diferença entre o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let&lt;/code&gt; e o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use&lt;/code&gt; é bastante importante. Sempre que você tiver um recurso que implemente a interface &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDisposable&lt;/code&gt; você deve utilizar o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use&lt;/code&gt; para que o método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt; seja chamado quando o programa encerrar a execução do escopo.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Agora vamos ao método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; para executar essa função passando diferentes endereços:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sites&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;https://www.github.com/&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;https://www.google.com/&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;https://www.amazon.com/&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;https://gabrielschade.github.io/&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    
    &lt;span class=&quot;n&quot;&gt;sites&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Assim como em C#, podemos utilizar um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Stopwatch&lt;/code&gt; para medirmos o tempo de execução dessa tarefa:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sites&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stopwatch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Diagnostics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Stopwatch&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;stopwatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Start&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;sites&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fetchUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Elapsed Time: %i&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stopwatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ElapsedMilliseconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Vamos executar para ver o resultado:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/pifx5ag.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Agora vamos tornar essa execução paralela com alguns ajustes. Para manter duas funções separadas, vamos copiar a função original e renomeá-la para &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asyncFetchUrl&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Depois disso, vamos envolvê-la no &lt;em&gt;computation express&lt;/em&gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;. Pera, como assim?&lt;/p&gt;

&lt;p&gt;Calma, eu explico. Todo &lt;em&gt;computation express&lt;/em&gt; precisa de um contexto, esse contexto é definido pelo nome do &lt;em&gt;computation&lt;/em&gt; e por chaves envolvendo o bloco, veja:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncFetchUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;WebRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponse&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponseStream&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReadToEnd&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished reading %s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Até aqui nossa função praticamente não mudou, certo? -Mais ou menos.&lt;/p&gt;

&lt;p&gt;Se formos checar o tipo dela, podemos verificar que ele passou de: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string -&amp;gt; string&lt;/code&gt; para &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;string -&amp;gt; Async&amp;lt;unit&amp;gt;&lt;/code&gt;. Peraí, por que &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unit&lt;/code&gt; se a última linha estamos retornando o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;html&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;Na verdade, quando estamos dentro de um &lt;em&gt;computation&lt;/em&gt; precisamos explicitar a palavra reservada &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;, veja:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncFetchUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;WebRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponse&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponseStream&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReadToEnd&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished reading %s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Agora sim temos um método que retorna &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;string&amp;gt;&lt;/code&gt;. Vamos testar?&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/xoPO7jw.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result 2&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Foi super rápido! Mas também não fez nada…&lt;/p&gt;

&lt;p&gt;O motivo disso é bastante claro, lembra que no início do post eu falei que o bloco &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; precisa ser explicitamente avaliado? Então… Esse é o problema. Tudo que nossa função está fazendo é envolvendo um bloco de código para identificá-lo como assíncrono.&lt;/p&gt;

&lt;p&gt;Na prática o que temos é uma lista de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;string&amp;gt;&lt;/code&gt; que precisa ser executada. Existem diversas formas de fazer isso, uma delas é executando um a um em ordem, ou seja, realizando as tarefas de forma síncrona:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; &lt;span class=&quot;n&quot;&gt;sites&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asyncFetchUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asynchronous&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RunSynchronously&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asynchronous&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;É claro que isso é só para demonstrar que precisamos explicitamente executar um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt;, porque não faz absolutamente NENHUM sentido executarmos todos eles um a um de forma síncrona.&lt;/p&gt;

&lt;p&gt;O que podemos fazer utilizando o módulo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; é transformar nossa lista de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Asyncs&lt;/code&gt; em um único &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; com uma lista de tarefas, ou seja, podemos paralelizar nossas chamadas:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;sites&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asyncFetchUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Parallel&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RunSynchronously&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/GOjk3na.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result 3&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Agora sim! Note que a ordem das respostas está diferente e o tempo está relativamente menor.&lt;/p&gt;

&lt;p&gt;Maaaaas, ainda não estamos fazendo as coisas de maneira síncrona, na prática cada um das chamadas ainda estão bloqueando suas respectivas threads durante a operação de requisição. Estamos paralelizando várias funções síncronas.&lt;/p&gt;

&lt;p&gt;É como se estivessemos usando em C# uma chamada à um método &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;, que internamente não realiza nenhuma outra chamada assíncrona, ou seja, um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt; sem um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; (não por opção, mas por não poder utilizar).&lt;/p&gt;

&lt;p&gt;Então vamos alterar nossa função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;asyncFetchUrl&lt;/code&gt; mais uma vez, incluindo UM caracter: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!&lt;/code&gt; e alterando uma chamada:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncFetchUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;WebRequest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Create&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Uri&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AsyncGetResponse&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//use! &amp;amp;&amp;amp; AsyncGetResponse&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;GetResponseStream&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StreamReader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ReadToEnd&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished reading %s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;html&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Vamos executar de novo:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/DPFSnmN.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result 4&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Agora sim! Mas o que aconteceu?&lt;/p&gt;

&lt;p&gt;Bom, agora estamos de fato utilizando uma chamada assíncrona e liberando que o programa continue executando. Além disso, note que estamos utilizando o &lt;em&gt;Bang&lt;/em&gt; (!) após o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use&lt;/code&gt;. Isso significa que estamos escolhando a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Use&lt;/code&gt; do &lt;em&gt;computation express&lt;/em&gt; ao invés da função do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use&lt;/code&gt; padrão do F#.&lt;/p&gt;

&lt;p&gt;Vamos entender melhor sobre a sintaxe do &lt;em&gt;Bang&lt;/em&gt; (no contexto Async, afinal sua funcionalidade pode mudar de acordo com o &lt;em&gt;computation express&lt;/em&gt;):&lt;/p&gt;

&lt;h4 id=&quot;sintaxe-bang&quot;&gt;Sintaxe Bang(!)&lt;/h4&gt;

&lt;p&gt;Essa sintaxe existe para qualquer &lt;em&gt;computation express&lt;/em&gt;, mas vamos focar nas funcionalidades providas pelo &lt;strong&gt;Async&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Dentro de um escopo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; devemos utilizar o operador &lt;em&gt;Bang (!)&lt;/em&gt; sempre que interagirmos com algo assíncrono, em muitos casos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;!&lt;/code&gt; funcionará como um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; para essa sintaxe. Vamos ver o que podemos com esse operador:&lt;/p&gt;

&lt;h5 id=&quot;do&quot;&gt;&lt;strong&gt;Do&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;O &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do&lt;/code&gt; normalmente funciona como um &lt;em&gt;statement&lt;/em&gt; isolado, ele é quase que um caso especial de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let&lt;/code&gt; onde não precisamos atribuir um resultado. Na prática utilizamos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do&lt;/code&gt; para executar uma função que não retorna nada, ou seja, que retorna um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unit&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionDoExample&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;O que geralmente nos faz estranhar o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do&lt;/code&gt; é por que ele pode ser completamente omitido e o código continua funcionando da mesma maneira:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionDoExample&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello World&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;No entanto, apesar de podermos omití-lo em nosso código tradicional, precisamos saber da existência dele no caso de processamentos assíncronos, isso porque ele se torna útil quando precisarmos realizar um “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;”. Nesse caso, precisamos da sintaxe &lt;em&gt;bang&lt;/em&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do!&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Vamos fazer a prova real disso, primeiro usaremos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async.Sleep&lt;/code&gt; sem o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do!&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;before working&quot;&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Sleep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;after working&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EntryPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;started&quot;&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RunSynchronously&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ao executar podemos notar que o resultado é imediato, mesmo que o código esteja dizendo para aguardarmos 20 segundos. Isso porque não estamos realizando um “&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt;”, ou seja, não estamos esperando a operação terminar.&lt;/p&gt;

&lt;p&gt;Simplesmente inserindo o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do!&lt;/code&gt; podemos notar que a função agora precisa esperar o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Sleep&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;before working&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Sleep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;after working&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Isso é especialmente útil quando precisamos orquestrar processamentos assíncronos ou paralelos.&lt;/p&gt;

&lt;h5 id=&quot;let&quot;&gt;&lt;strong&gt;Let&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;Como você já deve saber em F#, o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let&lt;/code&gt; funciona como uma forma de atribuirmos ou vincularmos um valor de função ou um valor discreto para uma variável. No contexto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; podemos utilizar o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let!&lt;/code&gt; sempre que precisarmos esperar uma operação assíncrona que retorna valor terminar, ele é basicamente o mesmo que o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;do!&lt;/code&gt; com operações que retornam valor.&lt;/p&gt;

&lt;p&gt;Geralmente aqui usa-se exemplos fakes para simplificar, mas vamos lá, não vai ser complicado. Vamos fazer uma função assíncrona para utilizar a API do GitHub e obtermos o número de repositórios públicos de um perfil.&lt;/p&gt;

&lt;p&gt;Primeiro vamos instalar o pacote &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Fsharp.Data&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Install-Package FSharp.Data
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Agora basta criarmos os types providers, se você não sabe o que eu estou falando, acessa &lt;a href=&quot;(/2017/12/28/web-data-json.html){:target=&amp;quot;_blank&amp;quot;}&quot;&gt;este post&lt;/a&gt; e depois volta aqui!&lt;/p&gt;

&lt;p&gt;Agora vamos criar o tipo para o perfil do github:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Literal&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;githubUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://api.github.com/users/gabrielschade&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GitHubProfile&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;JsonProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;githubUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;E vamos fazer nossa função assíncrona a partir usando a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLoad&lt;/code&gt; do nosso tipo:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;printNumberOfRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://api.github.com/users/&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%s%s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;GitHubProfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AsyncLoad&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%s Repos: %i&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PublicRepos&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Note que se não utilizarmos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let!&lt;/code&gt; na chamada assíncrona nós nem conseguimos acessar a propriedade &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PublicRepos&lt;/code&gt;, porque estaríamos lidando com um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;GitHubProfile&amp;gt;&lt;/code&gt; ao invés de um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GitHubProfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;O interessante disso é que o &lt;em&gt;bang&lt;/em&gt; faz com que a operação seguinte dentro do bloco precise esperar a conclusão do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AsyncLoad&lt;/code&gt;, mas isso não é necessariamente verdade para quem chamar essa função. Vamos fazer um teste:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EntryPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;started&quot;&lt;/span&gt;
    &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Start&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;printNumberOfRepos&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;gabrielschade&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Qual o resultado esperado aqui?&lt;/p&gt;

&lt;p&gt;Bom, como a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Start&lt;/code&gt; não determina que a thread precise aguardar o término do processamento, o resultado será esse:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://i.imgur.com/rQcjLdT.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result my repo&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;É claro que podemos aguardar o processamento se quisermos, basta alterarmos a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Start&lt;/code&gt; para &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RunSynchronously&lt;/code&gt;. Além disso, também podemos fazer o mesmo que o exemplo anterior e carregarmos essas informações de diferentes usuários, veja:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EntryPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;gabrielschade&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;google&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;microsoft&quot;&lt;/span&gt;
        &lt;span class=&quot;s2&quot;&gt;&quot;dotnet&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;started&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;printNumberOfRepos&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Parallel&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RunSynchronously&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;finished&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/RiAgWEG.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result multiples repos&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Como já utilizamos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;use!&lt;/code&gt; anteriormente e ele é praticamente o mesmo que o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let!&lt;/code&gt;, com o adendo do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dispose&lt;/code&gt;, vamos omití-lo aqui, mas é sempre bom lembrarmos da existência dele!&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disposableValue&lt;/span&gt; 
&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;disposableValue&lt;/span&gt; 
    &lt;span class=&quot;k&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resource&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncDisposableValue&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;match&quot;&gt;&lt;strong&gt;Match&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;O &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match&lt;/code&gt; é a palavra reservada para realizarmos o tão famoso &lt;em&gt;pattern matching&lt;/em&gt;, essa é uma inclusão relativamente nova na linguagem, mas agora temos um &lt;em&gt;syntax sugar&lt;/em&gt; para realizarmos um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;await&lt;/code&gt; dentro da expressão do &lt;em&gt;pattern matching&lt;/em&gt; utilizando &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match!&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionOrValue&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;functionOrValue&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncFunctionOrValue&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;É importante ressaltar que isso é apenas um atalho sintático para o código abaixo:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncFunctionOrValue&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Vamos fazer uma função nova que ao invés de imprimir o número de repositórios ela simplesmente retorna-os. Por enquanto vamos simplesmente fazer uma outra versão da função para simplificar as coisas, mas a forma mais correta seria criarmos um pipeline de execução.&lt;/p&gt;

&lt;p&gt;Mas para mantermos as coisas um pouquinho mais simples, vamos simplesmente gerar uma outra função, conforme código:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNumberOfRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://api.github.com/users/&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%s%s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;GitHubProfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AsyncLoad&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PublicRepos&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;É basicamente a mesma função, com um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; ao invés do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;printfn&lt;/code&gt;. Agora vamos utilizar o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;match!&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluateRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%s: %s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNumberOfRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Fantastic&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Huge&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Great&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Meh&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Agora é só alterarmos a função lá na &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; e vermos o novo resultado:&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/eL54MuZ.png&quot; class=&quot;materialboxed&quot; alt=&quot;Result evaluate repos&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EntryPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;evaluateRepos&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;//&amp;lt;-&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Parallel&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RunSynchronously&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignore&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h5 id=&quot;return&quot;&gt;&lt;strong&gt;Return&lt;/strong&gt;&lt;/h5&gt;

&lt;p&gt;Por fim, temos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; que é um pouco diferente do resto. Mas nada super complicado. 
Diferente dos anteriores o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; já faz parte do bloco &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;async&lt;/code&gt;, peraí, como assim?&lt;/p&gt;

&lt;p&gt;Como mostrei nos exemplos acima, podemos utilizar os comandos: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;let, use, do e match&lt;/code&gt; fora de um &lt;em&gt;computation express&lt;/em&gt; sem problemas, na verdade, utilizamos eles toda hora!&lt;/p&gt;

&lt;p&gt;No caso do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; ele só existe aqui dentro mesmo, e o que pode tornar isso confuso, é que além dele, também temos sua versão com o &lt;em&gt;bang&lt;/em&gt;: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return!&lt;/code&gt;. O que isso quer dizer?&lt;/p&gt;

&lt;p&gt;Bom, o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; é o que faz com que um valor seja “envelopado” em um objeto &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt;, por exemplo:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Se avaliarmos essa expressão, ela retornará &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;int&amp;gt;&lt;/code&gt;. Lembram do &lt;a href=&quot;/2019/07/15/funcional-stranger-things.html&quot; target=&quot;_blank&quot;&gt;meu post sobre os conceitos de programação funcional utilizando Stranger Things&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Pois é, lá falamos sobre o conceito do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;, que nesse caso é literalmente o uso da palavra &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;.
Já vimos isso em uma das funções criadas anteriormente: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getNumberOfRepos&lt;/code&gt;, conforme código:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNumberOfRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;https://api.github.com/users/&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sprintf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%s%s&quot;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;baseUrl&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;let&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;GitHubProfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;AsyncLoad&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;PublicRepos&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Originalmente o campo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PublicRepos&lt;/code&gt; é do tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt;, mas ao analizarmos a função veremos que ela retorna um tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;int&amp;gt;&lt;/code&gt;. Isso porque precisamos sinalizar para quem irá consumir a função que ela ainda não foi executada e que trata-se de uma operação assíncrona, mesmo não estando diretamente ligada com o retorno.&lt;/p&gt;

&lt;p&gt;No nosso exemplo acima, a operação assíncrona é a busca das informações no perfil do GitHub, uma operação necessário para obtermos o número de repositórios, mesmo que ela não seja o retorno direto.&lt;/p&gt;

&lt;p&gt;Agora vamos imaginar uma outra situação. Para fins de exemplo, vamos fazer com que a cada novo usuário que obtermos o número de repositórios precisaremos esperar um determinado tempo.&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waitAndDo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Para fazer isso vamos reaproveitar a lista de usuários do GitHub e utilizarmos o índice dos elementos como tempo. Para obtermos o índice e o elemento vamos utilizar a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List.mapi&lt;/code&gt; ao invés de &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;List.map&lt;/code&gt;, além disso, vamos imprimir todos os números retornados pela função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;waitAndDo&lt;/code&gt;, conforme código.&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;[&amp;lt;&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;EntryPoint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argv&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;users&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;List&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mapi&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;fun&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waitAndDo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Parallel&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;RunSynchronously&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;iter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;printfn&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%i&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;//...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Se executarmos da forma que está iremos imprimir o número 1 quatro vezes. Precisamos alterar a função para realizar sua tarefa real. O que faremos é simplesmente esperarmos o tempo em segundos e depois vamos imprimir o número de repositórios do usuário usando a função.&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waitAndDo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Sleep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNumberOfRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Ao fazermos isso o compilador já irá reclamar do nosso pipeline. A partir de agora a última parte &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Array.iter&lt;/code&gt; esperando um inteiro irá causar problemas. Você consegue descobrir o motivo?&lt;/p&gt;

&lt;p&gt;Na prática o que está acontecendo é o seguinte: a função &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getNumberOfRepos&lt;/code&gt; já retorna um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;int&amp;gt;&lt;/code&gt;, logo, quando utilizamos o &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt; novamente estamos criando um objeto do tipo &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&amp;lt;Async&amp;lt;int&amp;gt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Para não encapsularmos o resultado novamente em um &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt; utilizamos a versão &lt;em&gt;bang&lt;/em&gt; do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return&lt;/code&gt;, ou seja, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;return!&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-fsharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;waitAndDo&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Async&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Sleep&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;seconds&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getNumberOfRepos&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;userName&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;E a partir de agora tudo funciona conforme o esperado!&lt;/p&gt;

&lt;p&gt;E essa é a &lt;em&gt;bang&lt;/em&gt; sintax do &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Async&lt;/code&gt;!&lt;/p&gt;

&lt;div&gt;
    &lt;img src=&quot;https://imgur.com/vJ3uMPY.gif&quot; class=&quot;materialboxed&quot; alt=&quot;Bang&quot; style=&quot;max-width: 80%;margin: 0 auto;display: block;margin-bottom:15px;&quot; /&gt;
    &lt;/div&gt;

&lt;p&gt;Apesar de ter muito mais coisa para explorar, como cancelamentos, workflows aninhados e por aí vai. 
Mas por enquanto ficaremos por aqui.&lt;/p&gt;

&lt;p&gt;Espero que tenham gostado, qualquer dúvida, correção ou sugestão, deixem nos comentários!&lt;/p&gt;

&lt;p&gt;E até mais.&lt;/p&gt;
</description>
        <pubDate>Mon, 23 Sep 2019 00:00:00 +0000</pubDate>
        <link>https://gabrielschade.github.io//2019/09/23/fsharp-async.html</link>
        <guid isPermaLink="true">https://gabrielschade.github.io//2019/09/23/fsharp-async.html</guid>
        
        <category>F#</category>
        
        
      </item>
      
    
  </channel>
</rss>
