<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Guilherme Rodrigues de Melo</title>
    <description>The latest articles on DEV Community by Guilherme Rodrigues de Melo (@guilhermelo).</description>
    <link>https://dev.to/guilhermelo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F556155%2Fb8550ecb-7a0d-4a0a-9836-6fc85fd6c4a6.jpeg</url>
      <title>DEV Community: Guilherme Rodrigues de Melo</title>
      <link>https://dev.to/guilhermelo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/guilhermelo"/>
    <language>en</language>
    <item>
      <title>Clojure na Web com Ring</title>
      <dc:creator>Guilherme Rodrigues de Melo</dc:creator>
      <pubDate>Fri, 08 Jan 2021 18:48:45 +0000</pubDate>
      <link>https://dev.to/guilhermelo/clojure-na-web-com-ring-4ki9</link>
      <guid>https://dev.to/guilhermelo/clojure-na-web-com-ring-4ki9</guid>
      <description>&lt;p&gt;Ring é uma biblioteca baseada no WSGI do Python e no Rack do Ruby que nos ajuda na criação de aplicações web em Clojure, abstraindo os detalhes do HTTP. Ring é a base para muitas aplicações e bibliotecas do mundo web em Clojure, pois ele trabalha com o baixo nível das requisições HTTP. Ring possui três conceitos principais: &lt;strong&gt;Handler, Adapter e Middleware.&lt;/strong&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Handler
&lt;/h1&gt;

&lt;p&gt;Para trabalhar com as requisições, precisamos criar handlers, que nada mais são do que funções que recebem uma requisição e devolvem uma resposta. As requisições e as repostas são mapas que contém informações como chaves baseadas na API de Servlet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requisição
&lt;/h3&gt;

&lt;p&gt;Uma requisição contém informações que são acessadas através das chaves, onde as principais são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;:server-port: Porta do servidor que está recebendo a requisição&lt;/li&gt;
&lt;li&gt;:server-name: Nome ou IP do servidor que está recebendo a requisição&lt;/li&gt;
&lt;li&gt;:query-string: Query string da requisição (?q=name)&lt;/li&gt;
&lt;li&gt;:request-method: Método HTTP utilizado na requisição (:post, :get, etc)&lt;/li&gt;
&lt;li&gt;:body: Corpo da requisição&lt;/li&gt;
&lt;li&gt;:headers: Headers da requisição&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Resposta
&lt;/h3&gt;

&lt;p&gt;Uma resposta contém apenas três informações que são:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;:body: Corpo da resposta&lt;/li&gt;
&lt;li&gt;:headers: Header da resposta contendo um mapa com chave/valor&lt;/li&gt;
&lt;li&gt;:status: Status da resposta (200, 404, 500, etc)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Adapter
&lt;/h1&gt;

&lt;p&gt;Um adapter é uma ponte entre a aplicação Ring e os detalhes de implementação do protocolo HTTP. O adapter recebe uma requisição, transforma a requisição em um mapa e passa esse mapa para a aplicação Ring realizar o processamento. Após processar o mapa recebido, a aplicação Ring retorna um mapa de resposta que é usado pelo adapter para retornar a resposta HTTP.&lt;/p&gt;

&lt;p&gt;Alguns exemplos de adapter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/ring-clojure/ring/tree/master/ring-jetty-adapter"&gt;Jetty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mmcgrana/ring-httpcore-adapter"&gt;Apache HttpCore&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Middleware
&lt;/h1&gt;

&lt;p&gt;Um middleware permite que alteremos a forma como a requisição é processada. Middlewares são utilizados para ampliar a funcionalidade dos handlers. Um middleware é uma função que recebe um handler e outros parâmetros opcionais, processa-os e retornando um novo handler com novos comportamentos. No exemplo a seguir veremos como criar e utilizar middlewares existentes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Criando um projeto com Ring
&lt;/h1&gt;

&lt;p&gt;Para criar um servidor com o Ring, precisamos primeiramente criar um projeto. No nosso caso, utilizaremos o Leiningen para a criação do projeto. Para instalar e configurar o Leiningen, acesse o &lt;a href="https://leiningen.org/"&gt;site &lt;/a&gt; e siga as instruções. Após instalar o Leiningen, execute o seguinte comando no seu terminal:&lt;/p&gt;

&lt;p&gt;*lein new hello-ring&lt;/p&gt;

&lt;p&gt;Será gerado um projeto com a seguinte estrutura:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m7CX2k7W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p5ti066tf1at7rtvdiva.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m7CX2k7W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/p5ti066tf1at7rtvdiva.png" alt="Alt Text" width="418" height="296"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Diretórios mais importantes para nós nesse momento:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;doc: Diretório onde é colocada a documentação do projeto&lt;/li&gt;
&lt;li&gt;src: Diretório onde fica o código fonte do projeto&lt;/li&gt;
&lt;li&gt;test: Diretório onde ficam os testes&lt;/li&gt;
&lt;li&gt;project.clj: Arquivo responsável por toda configuração do projeto (semelhante ao pom.xml de projetos Java com Maven)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Abra o arquivo &lt;strong&gt;project.clj&lt;/strong&gt;. Começaremos adicionando novas dependências para o projeto. No vetor :dependencies, adicione duas dependências do Ring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:dependencies [[org.clojure/clojure "1.10.0"]
               ; principais funções do Ring
               [ring/ring-core "1.8.1"]
               ; adapter Jetty para Ring
               [ring/ring-jety-adapter "1.8.1"]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Após adicionar as duas dependências, execute o comando para baixa-las no seu reposítorio local do Leiningen.&lt;/p&gt;

&lt;p&gt;*lein deps&lt;/p&gt;

&lt;p&gt;Agora, abra o arquivo &lt;strong&gt;core.clj&lt;/strong&gt; que está dentro do diretório &lt;strong&gt;src/hello_ring&lt;/strong&gt;. Nesse arquivo temos a declaração do namespace &lt;strong&gt;hello-ring.core&lt;/strong&gt; e a importação do adapter do servidor Jetty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ns hello-ring.core
  (:require [ring.adapter.jetty :as jetty]))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vamos adicionar nosso primeiro handler que retornará um mapa como resposta contendo o status, o corpo da requisição e um header de Content-Type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn ola-web [request]
  {:status 200
   :body "Olá web"
   :headers {"Content-Type" "text/plain; charset=utf-8"}})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por fim, criamos uma função chamada &lt;strong&gt;-main&lt;/strong&gt; que será chamada pelo Leiningen. Dentro da função main, iniciamos o servidor Jetty associando a ele o handler &lt;strong&gt;(ola-web)&lt;/strong&gt; e um mapa com a configuração da porta (3000).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ns hello-ring.core
  (:require [ring.adapter.jetty :as jetty]))

(defn ola-web [request]
  {:status 200
   :body "Olá web"
   :headers {"Content-Type" "text/plain; charset=utf-8"}})

(defn -main [&amp;amp; args]
  (jetty/run-jetty ola-web {:port 3000}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para inicializar o servidor pelo terminal, precisamos fazer uma configuração a mais. Abra o arquivo &lt;strong&gt;project.clj&lt;/strong&gt; e adicione uma linha &lt;strong&gt;(:main hello-ring.core)&lt;/strong&gt; para dizer ao Leiningen que o projeto inicializará pelo namespace &lt;strong&gt;hello-ring.core&lt;/strong&gt; através da função &lt;strong&gt;-main&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defproject hello-ring "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.10.0"]
                 [ring/ring-core "1.8.1"]
                 [ring/ring-jetty-adapter "1.8.1"]]
  :main hello-ring.core
  :repl-options {:init-ns hello-ring.core})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, abra novamente o terminal e execute o comando para incializar o projeto.&lt;/p&gt;

&lt;p&gt;*lein run&lt;/p&gt;

&lt;p&gt;O servidor será inicializado. Abra o navegador e digite localhost:3000. Deve ser mostrada a mensagem "Olá web".&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando um middleware
&lt;/h2&gt;

&lt;p&gt;Criaremos um middleware que adicionará a chave &lt;strong&gt;:query-params&lt;/strong&gt; ao header da requisição com os dados da &lt;strong&gt;query-string&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn parse-query
  "Transforma a query-string em um mapa de parâmetros"
  [query-string]
  (if (&amp;gt; (count query-string) 0)
    (apply hash-map (str/split query-string #"[&amp;amp;=]"))))

(defn wrap-query-param
  "Adiciona a chave :query-param ao header da requisição"
  [handler]
  (fn [request]
    (let [query-param (parse-query (:query-string request))
          nova-req (assoc request :query-params query-param)]
      (handler nova-req))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima, criamos a função &lt;strong&gt;parse-query&lt;/strong&gt; responsável por quebrar os parâmetros da requisição e criar um mapa de chave/valor. Nosso middleware &lt;strong&gt;(wrap-query-param)&lt;/strong&gt; captura os parâmetros, recebe o mapa criado pela função anterior e associa esse mapa a requisição atual, criando uma nova requisição e passando-a para o handler recebido como parâmetro do middleware.&lt;/p&gt;

&lt;p&gt;Para utilizar nosso middleware, passamos nosso handler como parâmetro para ele, que por sua vez, é passado como parâmetro para a função que cria o servidor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn -main [&amp;amp; args]
  (jetty/run-jetty (wrap-query-param ola-web) {:port 3000}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alteramos o código da função &lt;strong&gt;ola-web&lt;/strong&gt; para pegar o parâmetro e retornar a mensagem. Abaixo o código completo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ns hello-ring.core
  (:require [ring.adapter.jetty :as jetty]
            [clojure.string :as str]))

(defn ola-web [request]
  (let [nome (get (:query-params request) "nome")]
    {:status 200
     :body (str "Olá " nome)
     :headers {"Content-Type" "text/plain; charset=utf-8"}}))

(defn parse-query
  "Transforma a query-string em um mapa de parâmetros"
  [query-string]
  (if (&amp;gt; (count query-string) 0)
    (apply hash-map (str/split query-string #"[&amp;amp;=]"))))

(defn wrap-query-param
  "Adiciona a chave :query-param ao header da requisição"
  [handler]
  (fn [request]
    (let [query-param (parse-query (:query-string request))
          nova-req (assoc request :query-params query-param)]
      (handler nova-req))))

(defn -main [&amp;amp; args]
  (jetty/run-jetty (wrap-query-param ola-web) {:port 3000}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute novamente o comando para subir o servidor:&lt;/p&gt;

&lt;p&gt;*lein run&lt;/p&gt;

&lt;p&gt;No navegador, digite &lt;strong&gt;localhost:3000/?nome=Guilherme&lt;/strong&gt; e veja o resultado.&lt;/p&gt;

&lt;h2&gt;
  
  
  Utilizando um middleware pronto para retornar JSON
&lt;/h2&gt;

&lt;p&gt;Agora utilizaremos dois middlewares existentes. Um vai capturar os dados da query-string como fizemos no nosso middleware e o outro retornará os dados da requisição como JSON. Abra o arquivo &lt;strong&gt;project.clj&lt;/strong&gt; e adicione a seguinte dependência responsável pelo middleware de JSON:&lt;/p&gt;

&lt;p&gt;*[ring/ring-json "0.5.0"]&lt;/p&gt;

&lt;p&gt;No nosso namespace &lt;strong&gt;hello-ring.core&lt;/strong&gt;, vamos adicionar as dependências dos dois middlewares, sendo o &lt;strong&gt;wrap-params&lt;/strong&gt; pertencente à biblioteca &lt;strong&gt;ring-core&lt;/strong&gt; e o &lt;strong&gt;wrap-json-response&lt;/strong&gt; à biblioteca &lt;strong&gt;ring-json&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ns hello-ring.core
  (:require [ring.adapter.jetty :as jetty]
            [ring.middleware.params :refer [wrap-params]]
            [ring.middleware.json :refer [wrap-json-response]]))

(defn ola-web [request]
  (let [nome (get (:query-params request) "nome")]
    {:status 200
     :body {:nome nome}
     :headers {}}))

(defn -main [&amp;amp; args]
  (jetty/run-jetty
    (-&amp;gt; ola-web
        wrap-params
        wrap-json-response)
    {:port 3000}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No nosso código acima temos algo um pouco diferente na inicialização do servidor. Utilizamos uma &lt;strong&gt;thread-fist&lt;/strong&gt; para processar nosso handler utilizando os dois middlewares. Thread-first é uma forma que temos em Clojure de processar informações de forma clara e encadeada, pois o resultado da primeira linha é passado como parâmetro para a função da linha de baixo. Nesse caso, passamos nosso handler como parâmetro para o middleware &lt;strong&gt;wrap-params&lt;/strong&gt; e o resultado do retorno desse middleware é passado como parâmetro para o middleware de baixo &lt;strong&gt;(wrap-json-response).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Execute novamente o comando para subir o servidor:&lt;/p&gt;

&lt;p&gt;*lein run&lt;/p&gt;

&lt;p&gt;No navegador, digite &lt;strong&gt;localhost:3000/?nome=Guilherme&lt;/strong&gt;. O resultado é mostrado no formato JSON.&lt;/p&gt;

&lt;p&gt;Podemos melhorar o retorno do nosso handler adicionando uma biblioteca para utilizar os métodos HTTP. No arquivo &lt;strong&gt;project.clj&lt;/strong&gt;, adicione a dependência abaixo:&lt;/p&gt;

&lt;p&gt;*[metosin/ring-http-response "0.9.1"]&lt;/p&gt;

&lt;p&gt;No namespace &lt;strong&gt;hello-ring.core&lt;/strong&gt;, adicione a dependência do http-response para a utilização da função &lt;strong&gt;ok&lt;/strong&gt;. Passamos o mesmo mapa para a função &lt;strong&gt;ok&lt;/strong&gt;, que retornará o status 200 juntamente com o corpo da resposta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ns hello-ring.core
  (:require [ring.adapter.jetty :as jetty]
            [ring.middleware.params :refer [wrap-params]]
            [ring.middleware.json :refer [wrap-json-response]]
            [ring.util.http-response :refer [ok]]))

(defn ola-web [request]
  (let [nome (get (:query-params request) "nome")]
    (ok {:nome nome})))

(defn -main [&amp;amp; args]
  (jetty/run-jetty
    (-&amp;gt; ola-web
        wrap-params
        wrap-json-response)
    {:port 3000}))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ring é uma biblioteca potente e básica para inicializar o desenvolvimento web em Clojure, porém é a base para outras bibliotecas que veremos mais pra frente, como Compojure, Reitit e Pedestal. Nos vemos num próximo post. :)&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>ring</category>
      <category>web</category>
    </item>
    <item>
      <title>Programação Funcional em Clojure</title>
      <dc:creator>Guilherme Rodrigues de Melo</dc:creator>
      <pubDate>Fri, 08 Jan 2021 18:24:08 +0000</pubDate>
      <link>https://dev.to/guilhermelo/programacao-funcional-em-clojure-212c</link>
      <guid>https://dev.to/guilhermelo/programacao-funcional-em-clojure-212c</guid>
      <description>&lt;p&gt;Olá! Nesse post falaremos um pouco sobre programação funcional em Clojure. Bora? :)&lt;/p&gt;

&lt;h1&gt;
  
  
  Imutabilidade
&lt;/h1&gt;

&lt;p&gt;Imutabilidade é útil quando desejamos evitar a mudança de estado em nosso sistema, principalmente quando temos que trabalhar com concorrência, pois caso haja alguma falha, torna-se difícil de debugar o mesmo para encontrar a verdadeira causa. Em Clojure, toda vez que manipulamos uma estrutura de dados, retornamos não a estrutura manipulada, mas sim uma nova versão da estrutura com as mudanças realizadas. Clojure utiliza de certas estruturas de dados internamente para que essa copia não tenha uma performance ruim.&lt;/p&gt;

&lt;h1&gt;
  
  
  Transparência Referencial
&lt;/h1&gt;

&lt;p&gt;Transparência Referencial é quando podemos substituir uma expressão pelo seu valor sem mudar o comportamento do programa, ou seja, é quando definimos uma função que recebe um argumento e sempre retorna o mesmo resultado quando dado o mesmo argumento.&lt;/p&gt;

&lt;p&gt;Exemplo de uma função referencialmente transparente:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn multiplicacao [x y]
    (* x y))

(multiplicacao 10 5)
; =&amp;gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, sempre que passarmos os mesmos argumentos, o resultado será o mesmo.&lt;/p&gt;

&lt;h1&gt;
  
  
  Funções Puras
&lt;/h1&gt;

&lt;p&gt;Funções puras são aqueles que atendem a dois requisitos. O primeiro deles é que a função deve retornar sempre o mesmo resultado dado os mesmos argumentos. O segundo requisito é que a função não deve causar nenhum efeito colateral, ou seja, ela não deve fazer nenhuma mudança fora da função em si, como por exemplo, mudando o valor de uma variável externa. Se a função alterar algum valor dentro dela ou algo afetar o resultado da função, então essa função não é pura. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def numeros '(1 2 3 4 5))

(defn incrementa-numeros []
    (map inc numeros))

(incrementa-numeros)
; =&amp;gt; (2 3 4 5 6)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, a função &lt;strong&gt;incrementa-numeros&lt;/strong&gt; não recebe parâmetros, porém ela utiliza uma variável externa que poderia ser modificada antes dela ser invocada, podendo não retornar os mesmos valores dados os mesmos argumentos. No exemplo abaixo podemos ver uma versão pura da função anterior, onde a função recebe a sequência como parâmetro.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def numeros '(1 2 3 4 5))

(defn incrementa-numeros [sequencia]
   (map inc sequencia))

(incrementa-numeros numeros)
; =&amp;gt; 2 3 4 5 6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Se uma função lê um arquivo, ela não é referencialmente transparente porque o conteúdo do arquivo pode se modificar. Nos exemplos abaixo existem as funções &lt;strong&gt;conta-caracteres&lt;/strong&gt; e &lt;strong&gt;analisa-arquivo&lt;/strong&gt;, sendo respectivamente, uma pura e outra não.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn conta-caracteres [texto]
    (str "Quantidade de caracteres:" (count texto)))

(defn analisa-arquivo [arquivo]
    (conta-caracteres (slurp arquivo)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Funções puras tornam a manutenção e a leitura do sistema mais clara, pois as funções ficam isoladas, sem impactar as demais funções e valores do sistema. Além de serem consistentes, pois utilizam do conceito de transparência referencial.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trabalhando com Estrutura de Dados imutáveis
&lt;/h1&gt;

&lt;p&gt;Todo programa deve ter funções impuras, porém essas funções devem ser em menor quantidade e bem isoladas. Clojure nos ajuda provendo estruturas de dados imutáveis em seu core que veremos a seguir.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursão em vez de for/while
&lt;/h2&gt;

&lt;p&gt;Diferente de outras linguagens que utilizam de efeitos colaterais em loops como &lt;strong&gt;for&lt;/strong&gt; e &lt;strong&gt;while&lt;/strong&gt;, Clojure nos proporciona a alterativa para a mutação através da recursão. O exemplo abaixo demonstra a soma dos valores de um vetor através de recursão:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn soma 
    ([numeros] (soma numeros 0))
    ([numeros total]
        (if (empty? numeros)
            total
            (soma (rest numeros) (+ (first numeros) total)))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima é verificado se o vetor passado como parâmetro é vazio. Caso seja vazio o total da soma é retornado. No entanto, se o vetor ainda não é vazio, chama-se a função novamente passando como parâmetros o restante dos valores do vetor e a soma do primeiro item do vetor com o total acumulado até o momento. A função &lt;strong&gt;rest&lt;/strong&gt; sempre devolve todos os itens do vetor, exceto o primeiro. Abaixo podemos ver como ocorrem as chamadas recursivas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(soma [1 2 3 4 5])
(soma [1 2 3 4 5] 0)
(soma [2 3 4 5] 1)
(soma [3 4 5] 3)
(soma [4 5] 6)
(soma [5] 10)
(soma [] 15)
; =&amp;gt; 15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A cada chamada recursiva, um novo escopo é criado onde &lt;strong&gt;numeros&lt;/strong&gt; e &lt;strong&gt;total&lt;/strong&gt; são associados a diferentes valores, sem a necessidade de alterar os valores originais. Se executamos essa função para somar apenas do 0 até o 1000, tudo funciona corretamente.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(soma (range 1000))
; =&amp;gt; 499500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém, se executamos a soma do 0 até 100 mil, temos um StackOverflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(soma (range 100000))
; Execution error (StackOverflowError) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por razões de performance e para evitar problemas desse tipo, Clojure recomenda a utilização da função &lt;strong&gt;recur&lt;/strong&gt; se você estiver processando recursivamente uma coleção com milhares ou milhões de valores. Exemplo da função anterior utilizando &lt;strong&gt;recur&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn soma 
 ([numeros] (soma numeros 0))
 ([numeros total]
     (if (empty? numeros)
         total
         (recur (rest numeros) (+ (first numeros) total)))))

(soma (range 100000))
; =&amp;gt; 4999950000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Composição de função
&lt;/h1&gt;

&lt;p&gt;Composição de função é o ato de combinar funções passando valores de uma função para outra. Ao utilizar composição de funções, passamos a ter um código mais reutilizável. Clojure oferece algumas funções que ajudam o desenvolvedor como a função &lt;strong&gt;comp&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comp
&lt;/h2&gt;

&lt;p&gt;A função comp tem o objetivo de criar uma nova função através de outras funções. Abaixo um exemplo simples de utilização:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;((comp clojure.string/capitalize clojure.string/lower-case clojure.string/reverse) "GUILHERME")
; =&amp;gt; "Emrehliug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As funções passadas como parâmetro para &lt;strong&gt;comp&lt;/strong&gt; são executadas da direita para a esquerda, ou seja, sendo a ordem de execução: reverse, lower-case e capitalize. O código anterior é uma versão mais concisa do código abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(clojure.string/capitalize 
    (clojure.string/lower-case 
        (clojure.string/reverse "GUILHERME")))
; =&amp;gt; "Emrehliug"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Devemos usar &lt;strong&gt;comp&lt;/strong&gt; para deixar nosso código mais fácil de entender e mais reutilizável. No exemplo a seguir vemos como a utilização de &lt;strong&gt;comp&lt;/strong&gt; deixa tudo mais claro.&lt;/p&gt;

&lt;p&gt;Utilizando comp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(map (comp keyword str) ["Brasil" "França"])
; =&amp;gt; (:Brasil :França)
Sem utilizar comp:

(map #(keyword (str %)) ["Brasil" "França"])
; =&amp;gt; (:Brasil :França)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nos dois casos o resultado é o mesmo, porém no primeiro exemplo fica mais claro como as coisas acontecem.&lt;/p&gt;

&lt;h1&gt;
  
  
  Aplicação parcial com partial
&lt;/h1&gt;

&lt;p&gt;A função partial recebe uma função e vários argumentos. Com isso, partial retorna uma nova função que, ao ser invocada, retorna a função original passada como parâmetro utilizando os parâmetros originais. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def adiciona-cem (partial + 100))

(adiciona-cem 200)
; =&amp;gt; 300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo, quando chamamos adiciona-cem, ela chama a função + passando o valores 100 e 200 como parâmetro.&lt;/p&gt;

&lt;p&gt;A função partial é útil quando desejamos reutilizar uma determinada combinação de funções e argumentos. No exemplo abaixo utilizamos partial para reaproveitar a geração do log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn log 
    [nivel mensagem]
    (condp = nivel
        :erro (clojure.string/upper-case mensagem)
        :sucesso (clojure.string/lower-case mensagem)))

(def mensagem-erro (partial log :erro))

(def mensagem-sucesso (partial log :sucesso))

(mensagem-erro "Erro ao tentar acessar recurso")

(mensagem-sucesso "Recurso salvo")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Memoize
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Memoization&lt;/em&gt; nos da a vantagem da transparência referencial que citei no início do post, pois &lt;strong&gt;memoize&lt;/strong&gt; guarda os parâmetros e o retorno da função. Dessa forma, quando houver várias chamadas para a mesma função com os mesmos argumentos, o resultado é retornado imediatamente. Em casos de funções que levam muito tempo para serem executadas, a função memoize é muito útil.&lt;/p&gt;

&lt;p&gt;No exemplo abaixo temos uma primeira versão da função &lt;strong&gt;exibe&lt;/strong&gt; que exibe a mensagem após 1 segundo. Na segunda versão da função utilizamos &lt;strong&gt;memoize&lt;/strong&gt; para retornar o valor imediatamente após a primeira chamada.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn exibe [mensagem]
    (Thread/sleep 1000)
    mensagem)

(def exibe-com-memoize (memoize (defn exibe [mensagem]
    (Thread/sleep 1000)
    mensagem)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Espero que esse post tenha te ajudado a entender um pouco mais sobre Clojure e como usamos programação funcional nessa linguagem. Nos vemos num post futuro. :)&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Sequências e a importância das funções em Clojure</title>
      <dc:creator>Guilherme Rodrigues de Melo</dc:creator>
      <pubDate>Fri, 08 Jan 2021 18:16:33 +0000</pubDate>
      <link>https://dev.to/guilhermelo/sequencias-e-a-importancia-das-funcoes-em-clojure-5h9c</link>
      <guid>https://dev.to/guilhermelo/sequencias-e-a-importancia-das-funcoes-em-clojure-5h9c</guid>
      <description>&lt;p&gt;Olá! Nesse post veremos sobre sequências e a importância das funções para as sequências e para Clojure.&lt;/p&gt;

&lt;h1&gt;
  
  
  O que são sequências?
&lt;/h1&gt;

&lt;p&gt;Sequências são tipos de dados que abstraem os tipos de dados concretos que armazenam múltiplos valores. Ou seja, listas, mapas, sets e vetores são sequências que podem fazer uso de diversas funções da biblioteca de sequências do Clojure, pois podemos chamar funções iguais para diferentes tipos concretos de sequências. Veremos a seguir exemplos de funções que utilizam desse conceito.&lt;/p&gt;

&lt;p&gt;Antes de mostrar os exemplos, devemos entender um outro conceito que já foi implementado no post anterior e que tem o objetivo de deixar o post um pouco mais claro.&lt;/p&gt;

&lt;h1&gt;
  
  
  Funções de primeira classe e de grandeza superior
&lt;/h1&gt;

&lt;p&gt;Funções são de extrema importância para linguagens que utilizam o paradigma de programação funcional (não me diga, hehe). Mas por que elas são tão importantes? Funções são cidadãs de primeira classe em Clojure, pois são tratadas como valores. Ou seja, podemos passa-las como parâmetro para outras funções, como fazemos com textos e números, por exemplo.&lt;/p&gt;

&lt;p&gt;Com a possibilidade de passar funções como parâmetro de outras funções, temos ainda um novo recurso da linguagem que são as funções de grandeza superior. Funções de grandeza superior são funções que recebem outras funções como parâmetro ou que retornam uma função como resultado.&lt;/p&gt;

&lt;p&gt;A seguir serão apresentadas funções para manipulação de dados que utilizam os conceitos explicados acima.&lt;/p&gt;

&lt;h1&gt;
  
  
  Map
&lt;/h1&gt;

&lt;p&gt;A função map nos ajuda a mapear sequências para novos valores. Map recebe como parâmetros uma função e uma sequência. Será aplicada a função para cada item da sequência. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(map inc [1 2 3 4 5])
; (2 3 4 5 6)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima a função &lt;strong&gt;inc&lt;/strong&gt; incrementa um em cada item da sequência (nesse caso send um vetor).&lt;/p&gt;

&lt;p&gt;É muito comum precisarmos recuperar apenas um valor de um mapa. No exemplo a seguir utilizamos a keyword &lt;strong&gt;:nome&lt;/strong&gt; como uma função para criar uma nova sequência através do mapa.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;; define vetor de mapas de jogadores
(def jogadores 
    [{:nome "Ronaldo"    :idade 43},
     {:nome "Rivaldo"    :idade 47},
     {:nome "Ronaldinho" :idade 40},
     {:nome "Kaká"          :idade 37}])

; Mapeando apenas os nomes dos jogadores 
(map :nome jogadores)  
; ("Ronaldo" "Rivaldo" "Ronaldinho" "Kaká")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos utilizar também a função map para criar novos mapas utilizando mais de uma sequência.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def jogadores ["Ronaldo" "Rivaldo" "Ronaldinho" "Kaká"])

(def idades [43 47 40 37])

(defn define-jogadores [jogador idade]
    {:nome jogador
     :idade idade})

(map define-jogadores jogadores idades)
; ({:nome "Ronaldo", :idade 43} {:nome "Rivaldo", :idade 47} {:nome "Ronaldinho", :idade 40} {:nome "Kaká", :idade 37})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Reduce
&lt;/h1&gt;

&lt;p&gt;Reduce é uma função que combina todos os itens de uma coleção em um só valor. Reduce, assim como as outras funções, também aplica uma função para cada item da coleção, porém para cada aplicação da função o resultado é acumulado. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(reduce + [1 2 3 4 5])
; 15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, a cada item que foi somado, o valor somado foi salvo em uma variável interna que é o acumulador. Quando não houver mais itens na coleção o valor acumulado é retornado. É como se estivessemos fazendo assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(+ (+ (+ (+ 1 2) 3) 4) 5)
; 15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reduce aceita também um valor inicial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(reduce + 10 [1 2 3 4 5])
; 25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos unificar uma sequência de sequências utilizando reduce:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(reduce concat [] [[1 2 3 4 5] [6 7 8 9 10]])
; (1 2 3 4 5 6 7 8 9 10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Filter
&lt;/h1&gt;

&lt;p&gt;A função filter é utilizada para filtrar valores de uma sequência de acordo com a regra definida pela função passada como parâmetro juntamente com a sequência. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def pacientes-hospital [{:mes 1 :pacientes-atendidos 150}
    {:mes 2 :pacientes-atendidos 233}
    {:mes 3 :pacientes-atendidos 298}
    {:mes 4 :pacientes-atendidos 144}
    {:mes 5 :pacientes-atendidos 128}])


(filter #(&amp;lt; (:mes %) 3) pacientes-hospital)
; ({:mes 1, :pacientes-atendidos 150} {:mes 2, :pacientes-atendidos 233})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Take-while
&lt;/h1&gt;

&lt;p&gt;A função take-while recebe uma função e uma sequência como parâmetro. A função passada para take-while deve retornar true ou false de acordo com algum critério. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(take-while #(&amp;lt; (:mes %) 3) pacientes-hospital)
;({:mes 1, :pacientes-atendidos 150} {:mes 2, :pacientes-atendidos 233})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima, só serão retornados os registros em que o mês é menor que 3, pois quando a função anônima retorna false, são retornados todos os valores testados até aquele ponto.&lt;/p&gt;

&lt;p&gt;A diferença entre o filter e o take-while é que o filter processa toda a sequência enquanto o take-while processa a sequência até uma determinada parte de acordo com regra implementada pela função passada como parâmetro.&lt;/p&gt;

&lt;h1&gt;
  
  
  Drop-while
&lt;/h1&gt;

&lt;p&gt;A função drop-while segue um raciocínio parecido com a take-while, sendo a única diferença que os registros da sequência serão excluidos até que a função passada como parâmetro retorne false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(drop-while #(&amp;lt; (:mes %) 3) pacientes-hospital)
; ({:mes 3, :pacientes-atendidos 298} {:mes 4, :pacientes-atendidos 144} {:mes 5, :pacientes-atendidos 128})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Some
&lt;/h1&gt;

&lt;p&gt;A função some também recebe uma função e uma sequência como parâmetro e retorna true quando encontra um elemento que segue a regra da função ou false quando não encontra. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(some #(&amp;gt; (:pacientes-atendidos %) 250) pacientes-hospital)
; true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Sort-By
&lt;/h1&gt;

&lt;p&gt;A função sort-by também recebe uma função e uma sequência como parâmetros. A função sort-by ordena a sequência de acordo com a regra implementada pela função passada como parâmetro. No exemplo abaixo, a sequência é ordenada pelo tamanho do nome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(sort-by count ["Ronaldo" "Rivaldo" "Ronaldinho" "Kaká"])
; ("Kaká" "Ronaldo" "Rivaldo" "Ronaldinho")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bem, por enquanto é isso. Espero que tenha aproveitado o conteúdo e nos vemos num post futuro. Até lá! :)&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>sequence</category>
      <category>functions</category>
      <category>functional</category>
    </item>
    <item>
      <title>Funções em Clojure</title>
      <dc:creator>Guilherme Rodrigues de Melo</dc:creator>
      <pubDate>Fri, 08 Jan 2021 18:04:47 +0000</pubDate>
      <link>https://dev.to/guilhermelo/funcoes-em-clojure-2568</link>
      <guid>https://dev.to/guilhermelo/funcoes-em-clojure-2568</guid>
      <description>&lt;p&gt;Vimos no &lt;a href="https://dev.to/guilhermelo/comecando-com-clojure-4939"&gt;post anterior&lt;/a&gt; como são as estruturas básicas de dados em Clojure. Nesse post, veremos como declarar e trabalhar com funções na linguagem Clojure.&lt;/p&gt;

&lt;h1&gt;
  
  
  Definindo funções
&lt;/h1&gt;

&lt;p&gt;A criação de uma função é dividida em cinco partes, sendo elas:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;defn&lt;/li&gt;
&lt;li&gt;Nome da função&lt;/li&gt;
&lt;li&gt;A documentação da função, sendo opcional&lt;/li&gt;
&lt;li&gt;Parâmetros que são passados entre colchetes&lt;/li&gt;
&lt;li&gt;Corpo da função&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Criando nossa primeira função em Clojure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn ola
"Função que retorna um texto de boas vindas!"
[nome]
(println "Olá, " nome))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Acima definimos o nome da nossa função como "ola", escrevemos uma documentação simples, passamos "nome" como parâmetro e criamos um corpo da função que imprime a frase retornada.&lt;/p&gt;

&lt;p&gt;Invocando a função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ola "Guilherme")
; Olá Guilherme
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Parâmetros e Aridade
&lt;/h1&gt;

&lt;p&gt;Em linguagens orientadas a objetos podemos ter métodos com o mesmo nome, porém com quantidade de parâmetros diferentes na mesma classe. Em Clojure, temos algo parecido. Podemos definir que uma função pode ter diferentes formas de implementação com diferentes aridades (número de parâmetros passados para a função), o que chamamos de sobrecarga de aridade (arity overloading). Abaixo nossa função "ola" ganha novas aridades e para isso, devemos modificar um pouco a forma como escrevemos a função, envolvendo cada forma de implementar com parênteses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn ola
"Função que retorna um texto de boas vindas!"
([nome]
(println "Olá," nome))

([nome sobrenome]
(println "Olá," nome sobrenome))

([nome sobrenome idade]
(println "Olá," nome sobrenome ". Idade:" idade "anos")))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Invocando a função utilizando as três formas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ola "Guilherme")
; Olá, Guilherme

(ola "Guilherme" "Rodrigues")
; Olá, Guilherme Rodrigues

(ola "Guilherme" "Rodrigues" 23)
; Olá, Guilherme Rodrigues . Idade: 23 anos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clojure também nos permite definir uma função com aridade variável através do parâmetro rest (rest parameter). Para indicar que estamos utilizando rest parameter, devemos utilizar o simbolo &amp;amp; como no exemplo abaixo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn imprime-nome [nome]
    (println "Olá" nome))

(defn ola [&amp;amp; nomes]
    (map imprime-nome nomes))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No exemplo acima definimos uma função chamada &lt;strong&gt;imprime-nome&lt;/strong&gt; passando como parâmetro o nome. Utilizamos a função &lt;strong&gt;imprime-nome&lt;/strong&gt; para mapear a lista de argumentos e imprimi-los. Invocando a função com os parâmetros:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(ola "Guilherme" "João" "José")

; Olá Guilherme
; Olá João
; Olá José
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para utilizar rest parameter juntamente com outro parâmetro, devemos passa-los como último parâmetro da função. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn mostra-time [time &amp;amp; nomes]
    (println "Os jogadores do" time "são: " 
        (clojure.string/join ", " nomes)))
Invocando a função:

(mostra-time "Real Madrid" "Benzema" "Casemiro" "Rodrigo")
; Os jogadores do Real Madrid são: Benzema, Casemiro, Rodrigo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Desestruturação
&lt;/h1&gt;

&lt;p&gt;Clojure nos permite extrair valores dos parâmetros que são passados para a função utilizando um conceito chamado destructuring. No exemplo abaixo recuperamos apenas o primeiro elemento da coleção passada como parâmetro e retornamos o mesmo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn primeiro-elemento [[primeiro-elemento]]
    primeiro-elemento)

(primeiro-elemento ["Carro" "Bicicleta" "Caminhão"])
; "Carro"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clojure nos permite utilizar a desestruturação com rest parameters como no exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn dois-primeiros-elementos-e-resto [[primeiro segundo &amp;amp; resto]]
    (println "Primeiro:" primeiro)
    (println "Segundo:" segundo)
    (println "Outros:")
    (println (clojure.string/join ", " resto)))

(dois-primeiros-elementos-e-resto ["Carro" "Bicicleta" "Caminhão" "Metrô" "Ônibus"])

; Primeiro: Carro
; Segundo: Bicicleta
; Outros:
; Caminhão, Metrô, Ônibus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também é possível utilizar desestruturação com mapas. No exemplo abaixo os valores das chaves :nome e :sobrenome informadas são passados para os parâmetros nome e sobrenome:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn ola [{nome :nome sobrenome :sobrenome}]
(println "Nome:" nome)
(println "Sobrenome:" sobrenome))

(ola {:nome "Guilherme" :sobrenome "Rodrigues"})

; Nome: Guilherme
; Sobrenome: Rodrigues
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Corpo de função
&lt;/h1&gt;

&lt;p&gt;O corpo da função pode conter inúmeras formas dentro dele. Porém, Clojure retorna apenas a última expressão avaliada pela função. No exemplo abaixo temos diversas formas, porém apenas a última é retornada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn corpo-funcao []
    (+ 10 15)
    "Corpo da função"
    (* 100 12))

(corpo-funcao)
; 1200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Funções anônimas
&lt;/h1&gt;

&lt;p&gt;Acima fizemos um exemplo utilizando a função &lt;strong&gt;map&lt;/strong&gt; e passamos a função &lt;strong&gt;imprime-nome&lt;/strong&gt; como parâmetro. Relembrando a função:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn imprime-nome [nome]
    (println "Olá" nome))

(defn ola [&amp;amp; nomes]
    (map imprime-nome nomes))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Porém, em Clojure não é necessário que todas as funções tenham nomes, pois a linguagem nos possibilita utilizar funções anônimas. Vejamos abaixo como podemos utilizar funções anônimas nesse caso:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn ola [&amp;amp; nomes]
    (map (fn [nome] 
           (println "Olá" nome)) nomes))

(ola "Guilherme" "João")         

; Olá Guilherme
; Olá João
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como visto, para definir uma função anônima, trocamos o &lt;strong&gt;defn&lt;/strong&gt; por &lt;strong&gt;fn&lt;/strong&gt;, retiramos o nome da função e passamos como parâmetro de outra função. Porém, podemos diminuir mais um pouco a definição da função anônima. Para isso, deixamos de utilizar o &lt;strong&gt;fn&lt;/strong&gt;, não definimos o nome do parâmetro e substituimos o parâmetro apenas por %. Exemplo acima com função encurtada:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(defn ola [&amp;amp; nomes]
    (map #(println "Olá" %) nomes))

(ola "Guilherme" "João")    

; Olá Guilherme
; Olá João
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Caso a função anônima receba mais de um parâmetro, é possível utiliza-los como no exemplo abaixo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(#(+ %1 %2) 10 15)
;25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Espero que tenha gostado das funções em Clojure. Por enquanto é só e nos vemos em um futuro post. Abraços :)&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>functional</category>
    </item>
    <item>
      <title>Começando com Clojure</title>
      <dc:creator>Guilherme Rodrigues de Melo</dc:creator>
      <pubDate>Fri, 08 Jan 2021 17:55:30 +0000</pubDate>
      <link>https://dev.to/guilhermelo/comecando-com-clojure-4939</link>
      <guid>https://dev.to/guilhermelo/comecando-com-clojure-4939</guid>
      <description>&lt;h1&gt;
  
  
  O que é Clojure?
&lt;/h1&gt;

&lt;p&gt;Clojure é um dialeto de Lisp, que é uma linguagem de programação funcional. Clojure roda na JVM (Java Virtual Machine), possui uma sintaxe um tanto quanto peculiar e simples. Por poder ser executada na JVM, programas escritos em Clojure pode fazer uso de bibliotecas Java.&lt;/p&gt;

&lt;h1&gt;
  
  
  Mas o que é uma programação funcional?
&lt;/h1&gt;

&lt;p&gt;Programação funcional é um paradigma de programação, ou seja, é uma forma de se programar. Este paradigma é baseado em um modelo computacional chamado Cálculo Lambda, criado por Alonzo Church em 1930. Em programação funcional tudo é função, ou seja, um código funcional é uma sequência de funções que resolvem um problema.&lt;/p&gt;

&lt;h1&gt;
  
  
  O início
&lt;/h1&gt;

&lt;p&gt;Como dito anteriormente, Clojure possui uma sintaxe muito simples, porém que pode confundir muito (me confundiu muito) quem está começando no mundo de linguagens baseadas em Lisp. Abaixo como é escrito o código Clojure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(operador operando1 operando2... operando)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Não entendeu? Então vamos ao exemplo. Suponhamos que você deseja realizar uma soma entre 5 números.&lt;/p&gt;

&lt;p&gt;O que em Javascript poderíamos fazer assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let resultado = 3 + 7 + 8;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Em Clojure fazemos assim:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(+ 3 7 8)
=&amp;gt; 18
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No código acima o operador "+" soma os parâmetros 3, 7 e 8.&lt;/p&gt;

&lt;p&gt;Um outro exemplo utilizando o famoso Hello World, onde a string "Hello World" é passada como parâmetro para a função println:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(println "Hello World")
=&amp;gt; "Hello World"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Nomeando valores
&lt;/h1&gt;

&lt;p&gt;Usa-se a instrução &lt;strong&gt;def&lt;/strong&gt; para vincular o nome do símbolo a um valor. Exemplos:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def texto "Iniciando com Clojure")
(def contas-pagas 100)
Imprimindo os valores definidos:

(println texto)
=&amp;gt; "Iniciando com Clojure"

(println "Quantidade de contas pagas:"  contas-pagas)
=&amp;gt; "Quantidade de contas pagas: 100"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Estruturas de dados
&lt;/h1&gt;

&lt;p&gt;Em Clojure todas as estruturas de dados são imutáveis, ou seja, seus valores não podem ser alterados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Números básicos
&lt;/h2&gt;

&lt;p&gt;Em Clojure podemos definir três tipos básicos de números, sendo eles Integer, Float ou fracionados. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def numero-inteiro 10)
(def numero-ponto-flutuante 3.5)
(def numero-fracionado 10/3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Strings
&lt;/h2&gt;

&lt;p&gt;Strings representam textos, assim como em outras linguagens de programação. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def hobbit "Bilbo")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Mapas
&lt;/h2&gt;

&lt;p&gt;Mapas, assim como em outras linguagens de programação, são estruturas que armazenam chaves e valores. Abaixo algus exemplos de mapas em Clojure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def usuario {:nome "Guilherme" :idade 30})

(def funcao {"funcao-soma" +})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também é possível encadear mapas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def mapa {:nome "Guilherme" :endereco {:cidade "São Paulo" :rua "Rua Sete de Abril"}})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Outra forma de criar mapas é através da função &lt;strong&gt;hash-map&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def usuario (hash-map :nome "Guilherme" :cidade "São Paulo"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Para recuperar alguma informação do mapa, utilizamos a função &lt;strong&gt;get&lt;/strong&gt;. Nela nós passamos o mapa e a keyword utilizada como chave para recuperar a informação desejada. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(get mapa :nome)
=&amp;gt; "Guilherme"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Keywors são geralmente utilizadas como chaves em mapas no Clojure. No exemplo anterior, :nome é uma keyword.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vetores
&lt;/h2&gt;

&lt;p&gt;Um vetor é como um array em linguagens mais comuns, onde o index começa no 0. Definindo um símbolo como vetor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def numeros [3 2 1])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recuperando item do vetor de acordo com o índice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(get numeros 2)
=&amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Também é possível criar vetores utilizando a função &lt;strong&gt;vector&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def empresas (vector "Apple" "Microsoft" "Samsung"))

(get empresas 1)
=&amp;gt; "Microsoft"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Listas
&lt;/h2&gt;

&lt;p&gt;Listas são parecidas com vetores em Clojure, porém com algumas diferenças. Por exemplo, para recuperar algum item de acordo com a posição da lista, usa-se a função &lt;strong&gt;nth&lt;/strong&gt; e não a função &lt;strong&gt;get&lt;/strong&gt;. Para declarar uma lista, basta definir os itens da lista entre parênteres e colocar um apóstrofo no início. Exemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def numeros '(1 2 3 4))
(def estados '("SP" "RJ" "RS" "PR"))

(nth estados 2)
=&amp;gt; "RS"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Levando em consideração a performance, a função &lt;strong&gt;get&lt;/strong&gt; é mais rápida que a &lt;strong&gt;nth&lt;/strong&gt;, pois a nth passa por todos os elementos da lista para encontrar o item buscado.&lt;/p&gt;

&lt;p&gt;Também é possível criar listas utilizando a função &lt;strong&gt;list&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def numeros (list 1 2 3 4))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sets
&lt;/h2&gt;

&lt;p&gt;Sets são coleções em que os itens são únicos, ou seja, não podem se repetir. Em Clojure temos duas formas de criar um Set:&lt;/p&gt;

&lt;p&gt;Forma literal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def produtos #{"Refrigerante" "Carne" "Arroz"})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Utilizando a função &lt;strong&gt;hash-set&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(def produtos (hash-set "Refrigerante" "Carne" "Arroz"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Podemos inclusive transformar um vetor em um set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(set [2 2 5 6 5 1 1])
=&amp;gt; #{1 6 2 5}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Por enquanto é isso. Quem sabe nos vemos em um próximo post. :)&lt;/p&gt;

</description>
      <category>clojure</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
