Começando com Clojure
Tags: clojure, functional
Published: 2021-01-08 17:55:30

# O que é Clojure?

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.

# Mas o que é uma programação funcional?

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.

# O início
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:
```
(operador operando1 operando2... operando)
```
Não entendeu? Então vamos ao exemplo. Suponhamos que você deseja realizar uma soma entre 5 números.

O que em Javascript poderíamos fazer assim:
```
let resultado = 3 + 7 + 8;
```

Em Clojure fazemos assim:
```
(+ 3 7 8)
=> 18
```
No código acima o operador "+" soma os parâmetros 3, 7 e 8.

Um outro exemplo utilizando o famoso Hello World, onde a string "Hello World" é passada como parâmetro para a função println:
```
(println "Hello World")
=> "Hello World"
```

#Nomeando valores
Usa-se a instrução **def** para vincular o nome do símbolo a um valor. Exemplos:
```
(def texto "Iniciando com Clojure")
(def contas-pagas 100)
Imprimindo os valores definidos:

(println texto)
=> "Iniciando com Clojure"

(println "Quantidade de contas pagas:"  contas-pagas)
=> "Quantidade de contas pagas: 100"
```

# Estruturas de dados
Em Clojure todas as estruturas de dados são imutáveis, ou seja, seus valores não podem ser alterados.

## Números básicos
Em Clojure podemos definir três tipos básicos de números, sendo eles Integer, Float ou fracionados. Exemplo:
```
(def numero-inteiro 10)
(def numero-ponto-flutuante 3.5)
(def numero-fracionado 10/3)
```

## Strings
Strings representam textos, assim como em outras linguagens de programação. Exemplo:
```
(def hobbit "Bilbo")
```

## Mapas
Mapas, assim como em outras linguagens de programação, são estruturas que armazenam chaves e valores. Abaixo algus exemplos de mapas em Clojure:
```
(def usuario {:nome "Guilherme" :idade 30})

(def funcao {"funcao-soma" +})
```

Também é possível encadear mapas:
```
(def mapa {:nome "Guilherme" :endereco {:cidade "São Paulo" :rua "Rua Sete de Abril"}})
```

Outra forma de criar mapas é através da função **hash-map**:

```
(def usuario (hash-map :nome "Guilherme" :cidade "São Paulo"))
```

Para recuperar alguma informação do mapa, utilizamos a função **get**. Nela nós passamos o mapa e a keyword utilizada como chave para recuperar a informação desejada. Exemplo:

```
(get mapa :nome)
=> "Guilherme"
```

Keywors são geralmente utilizadas como chaves em mapas no Clojure. No exemplo anterior, :nome é uma keyword.

## Vetores
Um vetor é como um array em linguagens mais comuns, onde o index começa no 0. Definindo um símbolo como vetor: 
```
(def numeros [3 2 1])
```

Recuperando item do vetor de acordo com o índice:
```
(get numeros 2)
=> 1
```

Também é possível criar vetores utilizando a função **vector**
```
(def empresas (vector "Apple" "Microsoft" "Samsung"))

(get empresas 1)
=> "Microsoft"
```
## Listas
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 **nth** e não a função **get**. Para declarar uma lista, basta definir os itens da lista entre parênteres e colocar um apóstrofo no início. Exemplo:
```
(def numeros '(1 2 3 4))
(def estados '("SP" "RJ" "RS" "PR"))

(nth estados 2)
=> "RS"
```
Levando em consideração a performance, a função **get** é mais rápida que a **nth**, pois a nth passa por todos os elementos da lista para encontrar o item buscado.

Também é possível criar listas utilizando a função **list**:

```
(def numeros (list 1 2 3 4))
```

## Sets
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:

Forma literal:
```
(def produtos #{"Refrigerante" "Carne" "Arroz"})
```

Utilizando a função **hash-set**:
```
(def produtos (hash-set "Refrigerante" "Carne" "Arroz"))
```
Podemos inclusive transformar um vetor em um set:
```
(set [2 2 5 6 5 1 1])
=> #{1 6 2 5}
```
Por enquanto é isso. Quem sabe nos vemos em um próximo post. :)