(Executando funções no Clojure)
Tags: clojure, beginners, braziliandevs, functional
Published: 2023-05-08 12:30:00

Agora que já tem o ambiente instalado e já sabemos o que é REPL, que tal entender um pouco mais como executar funções no Clojure?
Se ainda não tem o ambiente funcionando, não se preocupe! Basta seguir os outros posts que fiz da série [Clojure 101](https://dev.to/afucher/series/21480)

## Características das funções
Clojure é uma linguagem da família LISP, e por isso tem algumas características diferentes de quem não teve contato com nenhum dialeto LISP.
No texto sobre REPL executamos algumas funções de exemplo para entender o laço contido dentro do REPL, se lembra?

- `(pprint "Hello world!")`

- `(+ 1 1)`

Analisando elas, a primeira coisa que podemos notar é o uso de `()` parênteses envolvendo a chamada da função. Em outras linguagens escrevemos a função a ser executada, e depois os parênteses para executá-la e passar os parâmetros. Por exemplo, no JavaScript seria `console.log("Hello world!")`

Outra ponto é o uso da notação polonesa, onde você declara primeiro a operação e depois os operandos. Quando olhamos para a soma, ao invés de declarar `1 + 1`, usamos `+ 1 1`. Essa notação vem da matemática e tem suas vantagens. No caso da soma, vamos pensar que queremos somar 3 números: `1 + 2 + 3`, em clojure escrevemos `+ 1 2 3`

## Chamadas de funções encadeadas
Continuando a pensar em operações matemáticas, digamos que queremos executar a seguinte conta: `2 + 4 * 3`.

> Aqui já começa o primeiro desafio ~~pessoal~~, saber em qual ordem isso deveria ser resolvido 😂

Depois de pesquisar na internet a ordem correta é * depois + 👍, então precisamos:

1. Executar `4 * 3`; (= 12)

1. Executar `2 + _multiplicação_`; (= 14)

Vamos montar a expressão Clojure que representa isso. A multiplicação fica `(* 4 3)`, agora precisamos fazer a soma que seria `(+ 2 _multiplicação_ )`. Substituindo ficamos com `(+ 2 (* 4 3))`, vamos validar no REPL?

```clojure
user=>  (+ 2 (* 4 3))
14
```
Você pode estar se perguntando:
> Mas com diversas chamadas isso deve ficar horrível de entender. Não fica confuso?

E a minha reposta é: Fica sim! 🤷 Existem maneiras de melhorar o código, mas isso é um assunto mais pra frente.

## doc e source: funções pra te ajudar
Quando estou vendo uma linguagem ou função nova, tendo a ir fuçando, lendo documentações e código fonte. Me ajuda a entender melhor e conhecer novas coisas.
> Se quiser ver onde eu costumo me atualizar e aprender sobre clojure, fiz um [post sobre isso](https://dev.to/afucher/clojure-onde-aprender-28c5)

E quando estamos no REPL tem uma maneira muito legal de poder entender melhor as funções que estamos usando. No REPL vamos chamar a função `doc` passando `+` como parâmetro:
```clojure
user=> (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
```
Ele traz o nome completo da função `clojure.core/+`, nesse caso indicando que a função `+` fica dentro da _namespace_ `clojure.core`.
Depois traz todas as opções de chamada que a função tem:

- `[]`: sem nenhum parâmetro

- `[x]`: recebendo um parâmetro

- `[x y]`: recebendo dois parâmetros

-  `[x y & more]`: recebendo N parâmetros. O `&` indica que todos os demais parâmetros irão vir dentro de um _array_ na variável `more`.

E por último temos a _docstring_ da função, explicando o que a função faz, e algumas outras informações. Veja também o `See also: +'` indicando para olhar a função `+'`. ⚠️ Isso pode ser um caminho sem volta

E se isso não for o bastante para minha curiosidade? Vamos então chamar a função `source`:

```clojure
user=> (source +)
(defn +
  "Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'"
  {:inline (nary-inline 'add 'unchecked_add)
   :inline-arities >1?
   :added "1.2"}
  ([] 0)
  ([x] (cast Number x))
  ([x y] (. clojure.lang.Numbers (add x y)))
  ([x y & more]
     (reduce1 + (+ x y) more)))
```
🤯 Com esse comando podemos ver a implementação da função, entender como fazem determinada coisa. 

---

Espero que tenha gostado do conteúdo! Se sim, compartilhe, comente e/ou deixe uma reação. Isso ajuda a trazer visibilidade e saber que estão curtindo!
E se não gostou, comenta aí o que poderia melhorar! Quem sabe o próximo post você goste? 

Abraços e até breve

---
Links interessantes:

- [lisp.com.br](https://lisp.com.br/)

- [Notação polonesa](https://pt.wikipedia.org/wiki/Nota%C3%A7%C3%A3o_polonesa)