Olá Solange, tudo bem?
A diferença é que o def
é executado apenas uma vez e o defn
é executado todas as vezes que é invocado. É recomendado usar o def
quando fizer uso em vários pontos do código, a execução dele é ligeiramente mais rápida. Já o defn
deve ser usado quando sua função precisar fazer algum processamento e normalmente trará resultados variados.
Quanto a parte das funções anônimas, elas são usadas apenas para encurtar seu código e para uso local. Se a intensão do código é ser executado em vários pontos, é mais interessante que ele seja bem explícito.
Encontrei dois códigos com defn
que fazem a mesma coisa, recebem dois vetores, concatenam os valores e depois aplica filtro retornando apenas os números pares. Mas um usa funções anônimas e o outro não e sinceramente, fiquei um pouco confuso com o uso da função anônima, definindo a função e um símbolo para usar nesta função me pareceu mais limpo:
(defn evens-with-def
[vec1 vec2]
(def combined (concat vec1 vec2))
(filter even? combined))
(evens-with-def [1 2 3] [4 5 6])
(defn evens-with-fn
[vec1 vec2]
((fn [x] (filter even? x))
(concat vec1 vec2)))
(evens-with-fn [1 2 3] [4 5 6])
Espero que tenha ajudado, mas caso precise, tentaremos ajudar novamente.
Bons estudos!