Hands On
Hands On
Seção intitulada “Hands On”A função map em Clojure aplica uma função a cada elemento de uma coleção, retornando uma nova coleção com os resultados.
No arquivo map.clj é implementado uma função chamada meu-mapa para exemplificar a funcionalidade da função map do clojure:
(defn meu-mapa [fun seq] (let [primeiro-elemento (first seq)] (if (not (nil? primeiro-elemento)) (do (fun primeiro-elemento) (meu-mapa fun (rest seq))))))Nessa função é processada uma sequência aplicando fun ao primeiro elemento e, em seguida, chamando-se recursivamente com o restante da sequência até que a sequência esteja vazia.
O problema dessa função é que ela utiliza recursividade sem otimização de cauda (tail call optimization). Em Clojure, a recursividade sem otimização de cauda pode levar a um estouro de pilha (stack overflow) quando aplicada a sequências muito longas, pois cada chamada recursiva adiciona um novo frame à pilha de chamadas.
No mesmo arquivo temos a função meu-mapa-otimizado utilizando a função recur do clojure para otimizar a execução:
(defn meu-mapa-otimizado [fun seq] (let [primeiro-elemento (first seq)] (if (not (nil? primeiro-elemento)) (do (fun primeiro-elemento) (recur fun (rest seq))))))A recursão em cauda é uma técnica onde a chamada recursiva é a última operação em uma função, permitindo que a linguagem reutilize o mesmo frame de pilha para cada chamada recursiva, ou seja, a pilha de chamadas não cresce. Isso evita o estouro de pilha (stack overflow) em sequências muito longas, que é um problema comum quando a recursão não é otimizada. Sem recur, cada chamada recursiva adiciona um novo frame à pilha de chamadas, o que pode levar ao estouro de pilha se a sequência for muito longa.