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
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:
Executar
4 * 3
; (= 12)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?
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
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:
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ávelmore
.
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
:
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:
Top comments (0)