Clojure - Funções, vetores e def
Tags: clojure, functional, beginners, braziliandevs
Published: 2022-02-07 12:28:47

Nessa postagem escreveremos nossas primeiras linhas de código com o Clojure, aqui tentaremos trazer alguns conceitos para mais perto de quem já programa com os paradigmas mais tradicionais (orientação a objetos por exemplo), de modo que fique mais simples entender as intenções e começarmos a correlacionar alguns pontos, mesmo que alguns deles não sejam necessariamente a mesma coisa.

## Funções

Como já é de conhecimento, funções são pequenas partes de um programa que executam um trabalho e devolvem um resultado, e para que esse trabalho seja realizado muitas vezes é necessário informar argumentos ou informações para que algo seja feito.

Em Clojure toda invocação de uma função ocorre dentro de parênteses, logo podemos interpretar o conteúdo que esta dentro dos parênteses da seguinte forma:

- O primeiro valor é a função a ser executada;
- O segundo valor é o primeiro argumento que a função receberá;
- Vamos agora ao nosso primeiro exemplo, iremos chamar uma função que escreve no console, passando como "argumento" o famoso "Olá Mundo!":

```
(println "Olá Mundo!")
```

![Nosso primeiro comando!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zoybd0a23qqi37z2r7ob.png)

Vamos falar sobre a imagem agora, linha por linha:

- Na primeira linha estamos iniciando o Clojure com o comando "clj";
- Na segunda linha nos é apresentada a versão atual (1.10.3);
- Na terceira linha começamos a escrever nosso primeiro código, chamando a função "println";
- Na quarta linha temos o resultado da execução interna da função "println", que é a escrita no console da frase que informamos como "argumento";
- Na quinta linha temos o retorno da função "println", como ela não retorna nada recebemos nulo (nil);
- Na sexta e última linha temos o controle a disposição novamente para informar os próximos comandos;

Ainda sobre funções vale destacar que os operadores matemáticos também são considerados como funções, logo se quisermos somar dois números, por exemplo, precisaríamos iniciar a expressão com o operador de soma, seguido dos "argumentos" (números) que desejamos somar:

```
(+ 1 2)
```

Iniciar a a expressão com um número, utilizando um padrão de operação comum nas linguagens  de programação mais tradicionais resultaria em erro, uma vez que o Clojure tentaria interpretar um número como uma função:

```
(1 + 2)
```

![Somando dois números](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/czx95bmspq1oeyau1pfq.png)

Na imagem acima vemos os dois exemplos, o primeiro com o resultado correto, onde a soma é o primeiro parâmetro e o segundo com o resultado incorreto, onde o Clojure nos diz que o número informado não é uma função.

## def

Quando estamos programando é trivial mantermos determinados valores (independente do tipo) armazenados em memória, para podermos acessá-los durante a execução de uma aplicação ou função e comumente realizamos isso por meio de "variáveis", sendo justamente esse o conceito que utilizaremos agora para tentar entender o "def".

Com o "def" criamos (ou definimos) símbolos que nos permitem salvar e recuperar determinados valores, funcionando de forma semelhante a uma variável, sua sintaxe é simples, e funciona como uma função, onde temos a função propriamente dita, o símbolo a ser criado/atualizado e o valor que pretendemos associar ao símbolo:

```
(def total-de-alunos 25)
```

Para poder ver o valor armazenado em nosso símbolo podemos usar o "println" ou podemos ver seu conteúdo simplesmente digitando o nome do símbolo (fora de parentes é claro):

```
(println total-de-alunos)

total-de-alunos
```

![Definindo um símbolo e vendo seu conteúdo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kuvox0l2zeuj1gmj3v4t.png)

Na imagem acima vemos o seguinte:

- Na linha três a definição do símbolo "total-de-alunos" com o valor "25";
- Na linha quatro o retorno que nos indica o espaço onde nosso símbolo esta gravado (user);
- Na linha cinco executamos a função "println" para ver o conteúdo;
- Na linha oito verificamos o valor do símbolo diretamente, sem o uso de uma função;
- Nas linhas seis e nove podemos ver o valor armazenado no símbolo;

Para alterar o valor de um símbolo basta utilizarmos o "def" novamente, informando o identificador e o novo valor, esse novo valor pode ser um número fixo (como vimos anteriormente) ou pode ser a execução de uma outra função:

```
(def total-de-alunos 30)

(def total-de-alunos (+ total-de-alunos 5))

```

![Alterando o valor do símbolo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7jjna7mxcr2770r0c0d.png)

Podemos observar na imagem acima:

- Na linha um definimos um novo valor para o símbolo;
- Na linha três pedimos para ver o novo valor e na linha quatro o vemos (30);
- Na linha cinco alteramos o valor novamente, fazendo com que o novo valor seja o valor já existente "30" somado a "5";
- Na linha sete pedimos para ver o novo valor e na linha oito o vemos (35);

## Vetores

Quando começamos a aprender uma nova linguagem de programação umas das primeiras estruturas que aprendemos para armazenar uma série de elementos é o vetor, em Clojure não é diferente, a exemplo do que vimos anteriormente, iremos usar o "def" para definir um símbolo ficando por conta do valor atribuído a definição desse vetor, em nosso caso iremos atribuir uma série de nomes entre colchetes:

```
(def alunos ["Maria", "Flávia", "Teresa"])
```

Perceba que no comando acima utilizamos "virgulas" para separar os elementos, mas o que conta mesmo para essa separação são os espaços, a virgula esta ali apenas como uma boa prática que nos permite identificar melhor os itens (inclusive as virgulas são consideradas como espaços no Clojure).

Para ver os itens de nosso vetor podemos usar tanto as formas já vistas até aqui, com o "println" ou digitando o nome do símbolo diretamente, o que resulta na apresentação de todos os valores ou podemos acessá-los por meio de suas posições, nesse último caso o vetor acaba funcionando como uma função que recebe como parâmetro a posição desejada:

```
(println alunos)

alunos

(alunos 2)

```
![Criando o vetor e vendo seu conteúdo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/22c8jzvj67uhnwlwoukw.png)

Quando trabalhamos com vetor temos a disposição a função "count" para contar o total de elementos:

```
(count alunos)
```

Agora se nossa intenção for adicionar um novo item ao vetor devemos usar a função "conj", aqui é muito importante entendermos que essa função não altera o vetor original, o que ela faz é retornar um novo vetor que possui os valores anteriores e também o novo, isso devido a imutabilidade do Clojure:

```
(conj alunos "Eduardo")
```

Mas qual a vantagem da imutabilidade então? Bom ela nos garante que nossa informação (no caso os valores de nosso vetor) não serão alterados sem o nosso conhecimento ao utilizarmos outras funções, desse modo temos uma confiabilidade maior sobre a informação uma vez que ela só será alterada se realmente desejarmos, ou seja, não corremos o risco de termos os dados alterados por uma função que se quer conhecemos a implementação.

![Adicionando valor ao vetor sem alterá-lo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zzh6xf6ra2aenquubi6c.png)

Na imagem acima temos:

- Na linha sete usamos a função "conj" para adicionar um elemento ao vetor;
- Na linha oito a função "conj" nos retorna o novo vetor contendo a alteração que realizamos;
- Na linha nove e dez podemos perceber que o vetor original "alunos" não foi alterado;

Certo, como já é possível imaginar, se nossa intenção for alterar o vetor original precisaremos então redefinir o valor do nosso símbolo "vetor", sendo que seu novo valor será o resultado da execução da função "conj":

```
(def alunos (conj alunos "Eduardo"))
```

![Novo valor no vetor original](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y1a4oayui1byvbaf11vh.png)

Como podemos ver na imagem acima agora o vetor original "alunos" possui o novo valor.

## Conclusão

Nessa postagem sentimos o gostinho inicial do Clojure, escrevemos nosso primeiro "Olá Mundo!", definimos nossa primeira "variável" e criamos nosso primeiro vetor. Também nos deparamos com a imutabilidade, entendendo como ela funciona e uma de suas principais vantagens.

## Saiba mais

- [Clojure](https://clojure.org/)
- [Learn Clojure - Syntax](https://clojure.org/guides/learn/syntax)
- [Escrito originalmente aqui](https://programero.blogspot.com/2022/02/clojure-funcoes-vetores-e-def.html)