map
e reduce
let
Você já viu algumas funções, como
count
,conj
,first
erest
. Toda a aritimética que fizemos usou funções também:+
,-
,*
, e/
. O que significa ser uma função então?
Uma função é um trecho distinto e independente de código que recebe alguns valores como entrada (chamados de argumentos ou parâmetros) e devolve um valor na saída.
Referência: Básicos de funções
count
, conj
, first
+
, -
, *
, /
Funções também podem receber mais de um argumento. Vamos fazer uma função
forward-right-with-len
que recebe uma distância para frente, além da tartaruga.
(defn forward-right-with-len
"Dado uma tartaruga e uma distância, ande para frente com a tartaruga e vire a sua cabeça"
[turtle len]
(forward turtle len)
(right turtle 135))
(forward-right-with-len :trinity 90) ;=> {:trinity {:angle 135}}
(forward-right-with-len :neo 80) ;=> {:neo {:angle 135}}
Nomes de função são símbolos, do mesmo jeito que os símbolos usados com o
def
quando atribuímos nomes a valores.
Símbolos devem começar com um caractere não numérico e podem conter caracteres alfanuméricos, além de
*
,+
,!
,-
,_
, e?
. Essa flexibilidade é importante para funções, pois existem alguns estilos de escrita que usamos.
Clojure tem dois tipos de função:
- função que retorna um valor,
- função que retorna
true
oufalse
. O segundo tipo é chamado de predicado.
Em Clojure,
=
é uma função predicado, o que pode ser algo surpreendente. Além disso, como em muitas outras linguagens de programação, Clojure tem funções predicado para testar maior que, menor que, etc. A maioria dos predicados termina com?
, se começam com palavras.
=
,not=
>
,<
,>=
,<=
true?
,false?
,empty?
,nil?
,vector?
,map?
Algumas das funções mais poderosas que você pode usar com coleções recebem outras funções como argumento. Essa é uma das coisas mais mágicas sobre Clojure – e muitas outras linguagens de programação. É uma ideia complicada, e pode não fazer muito sentido à primeira vista. Vamos ver um exemplo e aprender mais sobre isso.
Referência: Funções de alta ordem
map
map
é uma função que recebe outra função junto com uma coleção. Ela chama a função passada em cada um dos elementos da coleção, e devolve uma nova coleção com os resultados destas chamadas de função. É um conceito estranho, mas é a essência de Clojure e de programação funcional em geral.
(map inc [1 2 3]) ;=> (2 3 4)
(map (partial + 90) [0 30 60 90]) ;=> (90 120 150 180)
Referência: partial
reduce
Vamos ver outra função que recebe uma função. Essa é a
reduce
, e é usada para transformar coleções em um único valor.
reduce
recebe os dois primeiros elementos da coleção passada e chama a função passada nesses dois elementos. Em seguida, chama a função novamente – dessa vez usando o resultado da chamada anterior da função como primeiro argumento e o próximo elemento da coleção como segundo.reduce
vai fazer isso repetidas vezes até percorrer todos os elementos e chegar no fim da coleção.
(reduce + [30 60 90]) ;=> 180
Até agora todas as funções que vimos tinham nomes, como
+
estr
ereduce
. No entanto, funções não precisam ter nome, assim como valores não precisam ter nomes. Chamamos funções sem nome de funções anônimas. Uma função anônima é criada comfn
, assim:
Referência: Função anônima
(fn [s1 s2] (str s1 " " s2))
Antes de prosseguir, você deve entender que você sempre está livre para dar um nome às suas funções. Não há nada de errado em fazer isso. No entanto, você vai ver código Clojure com funções anônimas, então deveria entender como elas funcionam.
(defn junta-com-espaco
[s1 s2]
(str s1 " " s2))
let
Quando você cria funções, você pode quere dar nomes a valores para poder reutilizá-los ou deixar o seu código mais legível. Dentro de uma função, no entanto, você não deveria usar
def
, como você fez fora de uma função. Ao invés disso, você deveria usar uma expressão especial chamadalet
.
let
Podemos atribuir um nome a um valor usando
let
da mesma forma que fizemos nodef
. Quando um nome está atribuído a um valor, esse nome é chamado de símbolo.
Referência: Atribuição let
(let [mangas 3
laranjas 5]
(+ mangas laranjas))
;=> 8
Voltar ao primeiro slide, ou ir para o índice do currículo.