clojure_
Linguagem
Introdução à
Clojure
Um guia rápido e prático sobre a linguagem,
suas ferramentas e frameworks
Leandro Ribeiro Moreira | [Link]@[Link]
Diverte-se com desenvolvimento de sistemas, atualmente na ThoughtWorks Brasil. Quando sobra
tempo, escreve em seu blog ([Link]) sobre T.I.
A ideia básica do artigo é explorar a linguagem de modo
a demonstrar seus conceitos chave, construções bási-
cas, tipos, alguns exemplos e ferramentas bem aceitas
na comunidade. Tudo isso de um jeito prático e rápido.
A finalidade não é servir como um guia completo para
linguagem, mas sim como uma apresentação curta da
mesma. Logo, se o leitor se interessar e quiser se apro-
fundar, há referências de livros e links que podem aju-
dar esse aperfeiçoamento de conhecimento. Note que,
por questões de simplicidade, adotei o termo função
genericamente, sendo que às vezes pode se referir na
verdade a uma macro, uma forma especial ou outra es-
trutura da linguagem.
Clojure é uma linguagem dinâmica, de propósito linguagens funcionais como Haskell,
geral, escrita em Java, de código-fonte aberto e que Clojure é impura e permite a mutabi-
roda sobre a Java Virtual Machine (JVM). Atualmen- lidade (side-effects).
te, há versões da linguagem para .NET (CLR) e Ja- A escolha do nome da linguagem
vaScript. Seu criador, Rich Hickey, a concebeu como foi fortemente influenciada pelo ter-
um dialeto Lisp (uma das mais antigas linguagens de mo da computação científica conhe-
programação), mas com muitas melhorias e facili- cido como closure juntamente com a
dades na sintaxe (syntactic sugar). Clojure também plataforma Java. uma closure pode ser exemplifica-
se inspirou nas boas ideias das linguagens Python e da como a capacidade que uma função f1, retornada
Haskell. Apesar de conseguir criar eou reusar progra- dentro do corpo de outra f2, tem de referenciar va-
mas no paradigma orientado a objetos, Clojure tem riáveis locais da função f2 mesmo estando fora do
como paradigma a programação funcional (veja o contexto de definição das variáveis. Veja o exemplo
quadro sobre o assunto). Diferentemente de outras implementado em JavaScript.
19 \
instalado e disponível no seu sistema operacional o
var f2 = function(){ Java 5 ou outra versão mais atual. A instalação con-
var contadorExterno = 0; siste apenas em baixar o .zip do endereço [Link]
var f1 = function(){ [Link]/downloads o qual contém a última versão
contadorExterno = contadorExterno + 1 ; estável. No momento da escrita do artigo, essa ver-
return contadorExterno; são é a 1.3.0. Depois de baixado, extraia o arquivo zip
}; e observe que há um jar com nome [Link].
return f1; Para seguir os exemplos do artigo, você deve en-
};
trar pelo seu prompt/terminal na pasta onde baixou
var f1 = f2(); //retorna a função f1
o descompactou o jar e executar o comando java -cp
alert(f1()); //mostra 1 [Link] [Link] ou java -jar clojure-
alert(f1()); //mostra 2 -[Link]. Esse comando faz com que o seu terminal
se transforme em um ambiente interativo onde você
insere código e o mesmo é avaliado e executado. Tal
ambiente é muito bom para testar códigos rapida-
Além da vantagem de ter um enorme alcance mente. Para quem conhece Ruby é bem similar ao
oferecido pela JVM, Clojure também se integra fa- IRB. A esse ambiente é dado o nome REPL (read–
cilmente com código Java. No entanto, ultimamente eval–print loop) e nesse local você poderá executar
a linguagem está tendo mais foco devido às facilida- os exemplos do artigo.
des que Clojure proporciona para se escrever siste-
mas distribuídos sem se preocupar com locks e ou Outros REPLs
sincronização. Um dos ideais de Clojure para resol- Caso não queira instalar na sua máquina ou ape-
ver o problema da concorrência é ter como premissa nas por curiosidade quiser testar os códigos, pode
básica o fato de que quase tudo é imutável, e o que utilizar também outros REPL. Um deles é on-line e
não é deve ser tratado dentro de um contexto transa- pode ser acessado através do endereço [Link]
cional, usando um modelo STM (softtware transac- com/. Você também pode usar seu smartphone ou
tional memory). É importante observar que Clojure tablet, com android embutido, pra testar códigos
não resolverá os problemas de concorrência que um pelo REPL que pode ser obtido no endereço https://
código legado Java já possui. [Link]/details?id=[Link]-
Clojure é uma linguagem homoiconic, um nome re_repl (figura 1, QRCODE).
bem diferente para demonstrar que os programas
escritos na linguagem são representados por estru- Alô mundo
turas de dados. A linguagem é definida em termos Antes de demonstrar o exemplo ‘alô mundo’ em
da análise das estruturas de dados e não da sintaxe clojure, é necessário ressaltar novamente que todos
da mesma. Essa diferença dá o poder de construção os exemplos podem ser executados diretamente no
sobre a linguagem, ou seja, caso haja algo que não REPL; logo, você pode deixar o mesmo aberto en-
existe ainda na linguagem, você pode simplesmente quanto lê o artigo.
criar essa “sintaxe” nova. Programas escritos em Clojure são estruturas
Mesmo tirando todas as vantagens citadas an- de dados conhecidas como listas. Para o exemplo,
teriormente, penso que a linguagem é interessante iremos criar uma lista com dois itens, a função e o
e vale a pena ser estudada por ser limpa, objetiva, argumento.
propor reusabilidade ao máximo e também porque
faz o desenvolvedor pensar de um modo totalmen- Listagem 1. Exemplo alô mundo.
te diferente da forma imperativa de criar programas
computacionais. (println “Alô mundo”)
Outro fator importante a ser citado é a quantida-
de e qualidade de suporte da comunidade. Ao contrá- Para executar o programa, basta pressionar a te-
rio de outros dialetos Lisp, Clojure está sendo bem cla Enter, e verá a execução do famoso exemplo de
mais difundida, entendida e explorada. Basta ver o introdução a linguagens de computador. Como dito
“ecossistema” em volta da linguagem, que tem desde anteriormente, programas em Clojure são listas, e
ferramentas para automação de projetos e resolução tais listas são criadas utilizando-se parênteses e com
de dependências a muitos frameworks de propósitos itens dentro dos parênteses, opcionalmente separa-
gerais. dos por vírgula.
Simplificando um pouco todas as nuances pos-
Instalação síveis, quando essa instrução for lida pelo REPL, ele
Para instalar e utilizar Clojure, você deve ter irá tentar executar o primeiro item da lista como
/ 20
uma função, que por sua vez recebe o restante da lis- Listagem 2. Exceção de overflow.
ta como parâmetro. Apesar de parecer uma sintaxe
da linguagem, uma palavra reservada ou ainda uma (* 1000 1000 1000 1000 1000 1000 1000 1000)
função especial, a função println não é. É uma fun-
ção ordinária da linguagem como qualquer outra, e Para representar os boleanos basta utilizar os
ela está definida dentro de um namespace, conceito literais true e false. Para Clojure, exceto nil e false,
similar ao pacote [Link] em Java, que é disponibi- tudo é true, inclusive o 0. O literal nil é equivalente
lizado automaticamente para você utilizar. ao null da linguagem Java.
O mesmo exemplo poderia ser escrito usando O tipo literal é exatamente o tipo String do Java,
uma variável interna para guardar a cadeia de carac- com sua imutabilidade e métodos. A diferença fica no
teres “Alô mundo”. Para criar essa variável, basta usar tipo caractere, que é representado por barra e o ca-
a função def, que espera como argumento um nome racter \x, onde x é o próprio caractere. Observe que \n
e, opcionalmente, um valor. Veja na Listagem 1.1 o não tem o mesmo valor que tem Java, sendo apenas o
mesmo exemplo, mas utilizando uma variável inter- caractere n. Exemplos de caracteres: \a, \n, \newline,
na. Observe também que para se criar comentários no \tab etc.
código utiliza-se o caractere ponto-e-vírgula. Um tipo similar a cadeia de caracteres, porém
com outro propósito são as palavras-chave (keywor-
Listagem 1.1. Exemplo alô mundo com variável. ds). Para criá-las, basta adicionar ao início do literal
dois pontos. São principalmente usadas como cha-
; Alô mundo por variável
ves de um mapa. Exemplos de palavra-chave: :chave,
(def alo-mundo “Alô mundo”) :campo-nome etc.
(println alo-mundo)
Coleções
Coleções são tipos abstratos que representam
Principais tipos diversos tipos repositórios de itens. Em Clojure, as
Assim como outras linguagens dinâmicas, Cloju- coleções têm algumas propriedades compartilhadas.
re é tipada. Conhecer seus tipos básicos é essencial Todas são heterogêneas, ou seja, você pode ter diver-
para a criação de programas. Alguns tipos em Clojure sos tipos dentro de uma mesma coleção. A linguagem
são exatamente os mesmos da linguagem Java, como, trata todas as coleções como sequences, uma abstra-
por exemplo, o tipo String. ção de Clojure na qual você consegue aplicar funções
O tipo responsável por dar nomes a coisas em comuns sobre essas estruturas de dados.
Clojure é o símbolo. No exemplo alô mundo, note que Clojure utiliza um conceito conhecido como es-
o nome da função println é um símbolo, mas o mes- trutura de dados persistentes para implementar to-
mo não se restringe apenas à nomeação de funções das suas coleções. Nesse modelo, não há mudanças
e também é utilizado na definição de namespaces e quando você adiciona, remove ou atualiza um item
outros. Exemplos de símbolos: nome-da-funcao, +, da coleção, o que ocorre são apenas ligações entre es-
[Link]/funcao etc. sas mudanças, que preserva versões anteriores de sua
Os números são bem simples de serem entendi- coleção, e isso torna as coleções efetivamente imutá-
dos. Assim como em Java e outras linguagens, os li- veis. Na prática, quando você adiciona um item a uma
terais numéricos irão representar os números. Há um coleção, na verdade você está recebendo uma nova
tipo numérico novo, a fração (ratio), não muito co- coleção. Tal fato pode assustar alguns desenvolvedo-
nhecido para alguns desenvolvedores. Esse tipo man- res por medo de baixa performance ou alto consumo
tém os valores de uma divisão na forma dividendo por de memória, mas a linguagem foi projetada para não
divisor sem perder a precisão. Ao usar esse novo tipo, fazer apenas cópias e ser inteligente o bastante para
você pode fazer operações aritméticas normalmente ligar tais coleções.
sem se preocupar. É como se estivesse trabalhando Um das estruturas de dados mais simples, o vetor,
com tipos numéricos simples. Exemplos de números: pode ser criada usando colchetes ou a função vector,
1, 30M, 3.14, 1 ⁄ 3 etc. como, por exemplo.
É importante dizer que não há promoção auto- [ “item1”, :item2, [ ] ]
mática dos tipos numéricos. O código da Listagem 2
(vector “1” 2 :tres)
executa sucessivas multiplicações por mil que resulta
não em um gigantesco número, mas sim em uma ex- A estrutura de dados que têm seus valores orde-
ceção de overflow. Uma maneira de corrigir o código nados e tais podem ocorrer mais de uma vez, conhe-
seria colocar um M no final do literal numérico, que cida como lista, também é suportada por Clojure. Tais
o força a ser um BigDecimal. Versões mais antigas da listas podem ser criadas usando apóstrofo seguido de
linguagem faziam essa promoção automática. parênteses ou com a função list, como, por exemplo.
21 \
Quando se deseja criar uma função para um pro-
(def pilha ‘(“jpa” “jsf”))
pósito menor, seja para fazer uma simples seleção
(def hobbies (list “música”“boxe” “baralho”)
ou algo mais trivial, pode-se criar funções anônimas.
Por diversas razões, às vezes precisamos de listas Tais funções não são nomeadas e nem precisam ser
que não pode permitir repetições de itens. Esse tipo definidas por meio da função defn. Na Listagem 4 é
de estrutura é conhecido como conjunto. Para criar apresentada uma função chamada operação, que re-
conjuntos em Clojure, podemos utilizar a notação cebe uma função mais dois argumentos e imprime o
sustenido seguido de chaves ou a função hash-set, resultado da aplicação dos parâmetros sobre a função
como pode ser visto nos exemplos. passada.
A ideia é criar quatro funções anônimas, que re-
#{“f1” “rally” “fórmula truck” “f1” “indy”} presentem soma, subtração, multiplicação e divisão,
; a repetição do item “f1” será ignorada. e passá-las para a função operação. Para criar funções
anônimas, pode-se utilizar a função fn, a qual é simi-
(def centro-oeste (hash-set :go :df :ms :mt)
lar a defn, omitindo apenas o seu nome. As funções
anônimas possibilitam várias técnicas úteis, e uma
Por último, temos a coleção do tipo mapa, a qual é um delas é expor o contexto interno de uma função a
tipo abstrato onde se faz associações de chaves a va- funções externas, ou carregá-los além de sua defini-
lores, por várias vezes visto como sinônimo de dicio- ção, o que pode ser visto como um closure.
nário ou vetor associativo. Para criá-las em Clojure,
você pode usar chaves ou uma função como a hash- Listagem 4. Funções anônimas.
-map, e mesmo a vírgula sendo opcional nos mapas,
seu uso é encorajado devido a melhor legibilidade do
(defn operacao [funcao x y]
código.
(println (funcao x y)))
(def nosql-bd
{:server “[Link]”, :port 8584, :cloud false})
(def cidade (operacao (fn [a b] (+ a b)) 2 2)
(hash-map :nome “são paulo”, :sigla “sp”, (operacao (fn [a b] (- a b)) 4 6)
:per-capita 32493))
(operacao (fn [a b] (* a b)) 1 0)
(operacao (fn [a b] (/ a b)) 2 4)
Função a unidade central
Depois de conhecer um pouco sobre os tipos da Controle de fluxo por funções e não
linguagem, o próximo passo natural é estudar sua es- sintaxe
trutura central. Nas linguagens orientadas a objetos, Em uma linguagem funcional, normalmente, to-
essa estrutura central seria a classe: já em Clojure, é das suas estruturas de controle de fluxo, sejam elas
a função. Seus programas poderão ser expressos por condicionais e ou de iterações, são construídas sobre
meio de funções, e sua composição guiará ao propó- funções, e Clojure também segue essa mesma regra.
sito de sua ideia para um sistema. Essa pequena diferença é, talvez, a que causa maior
Para se criar uma função, basta utilizar outra estranheza aos novos adeptos de uma linguagem
função de uso bem simples, chamada defn. É mos- funcional. Por exemplo, suponhamos que você queira
trado na Listagem 3 a criação de duas funções, onde imprimir todos os valores de um dado vetor. Compare
a primeira simplesmente imprime “alô mundo” no na Listagem 5 como esse código poderia ser escrito
console/prompt enquanto a segunda recebe dois nú- em Java e Clojure.
meros e devolve a soma dos mesmos, usando a função
+ que realiza a soma dos parâmetros passados. Note Listagem 5. Iteração : Java & Clojure.
que a função defn recebe um símbolo, que define o
nome da função, seus parâmetros, ou ausência deles,
através dos colchetes e o corpo da função envolto em //Java
parênteses. Abaixo da definição das duas funções, se- final String[] valores = new String[] { “um”, “dois”, “três”};
guem exemplos de como executar ambas. for (String valor : valores) {
[Link](valor);
Listagem 3. Criar funções. }
(defn alo-mundo [] (println “alô mundo”))
(defn soma [x y] (+ x y)) ;Clojure
(alo-mundo) (map println [1 “dois” :tres])
(println (soma 2 3))
/ 22
A intenção da comparação do código da Listagem 5 a função dotdot. Alguns métodos requerem parâme-
não é pelo tamanho ou complexidade, mas apenas tros para sua execução, e segue-se a mesma regra de
para demonstrar que, enquanto nas linguagens im- passagem de parâmetros a funções, bastando usar o
perativas o que é esperado é uma sintaxe nova, em espaço e informar tais parâmetros. Há também uma
Clojure você utiliza uma função ou outra pra iterar. função bastante útil chamada bean. Tal função re-
Outra forma de se controlar o fluxo de programas cebe uma instância de objeto e retorna um mapa do
é por meio de instruções condicionais: os famosos padrão JavaBean, e de posse desse mapa, pode-se fa-
if’s. Em Clojure tem-se a função if para esse fim. O zer consultas a esse mapa utilizando a chave como
seu uso é muito simples: ela espera dois parâmetros acessor para o valor. Todos os conceitos explanados
obrigatórios, a condição e uma instrução, caso a con- anteriormente estão exemplificados e comentados na
dição seja verdadeira, e um opcional, que seria exe- Listagem 8.
cutado caso a condição fosse falsa. Na Listagem 6 é
mostrado um exemplo bem simples de uma função
que recebe um número, checa se o mesmo é maior do
que dez e retorna um texto dizendo se é maior ou não
do que dez. Programação funcional
Listagem 6. Função determina maior do que dez. Definir o que significa programação funcio-
nal é uma tarefa árdua, apesar de ser um conceito
(defn maior-do-que-dez [numero] que pode apresentar várias concepções há algu-
(if (> numero 10) mas definições que são bem aceitas pela grande
(str “Sim”) maioria dos desenvolvedores. Pode-se dizer que
(str “Não”)))
programação funcional é um paradigma de de-
senvolvimento que enfatiza a aplicação de fun-
;Exemplo de uso ções, em contraste com o estilo de programação
(println (maior-do-que-dez 100))
imperativo, onde o que é realçado são as mudan-
ças no estado dos programas. A programação fun-
cional tem suas raízes no cálculo lambda. Segue
Interoperabilidade com Java abaixo uma descrição de alguns conceitos sobre
Clojure fornece muitas funções e facilidades para esse paradigma.
essa interoperabilidade, o que faz a tarefa de usar Java Funções sem side-effect: a princípio uma
dentro da linguagem muito simples. Pode-se invocar função não deveria causar um efeito fora de seu
um método utilizando as notações apresentadas na escopo, ou seja, ela deveria ser uma unidade atô-
Listagem 7. Vale lembrar que Clojure já importa auto- mica que não causa mudança de estado no pro-
maticamente o namespace [Link]. grama. Claro que, na prática é quase impossível
escrever um programa onde não há uma função
Listagem 7. Invocando um método Java em Clojure. que cause mudanças externas.
; Métodos de instância Dados imutáveis: nesse paradigma deve se
evitar a mutabilidade, que é uma das dicas bási-
(.toUpperCase “gaucho”)
cas para o bom desenvolvedor Java. Sabendo que
(. “pessoense” toUpperCase) programas de computador vão causar e persistir
; Métodos de classe efeitos externos, as linguagens implementam jei-
(Math/PI) tos para que os programas possam ser mutáveis
quando necessário.
(.Math PI)
Funções como cidadãos de primeira classe:
Para criar instâncias de objetos há pelo menos duas você consegue usar funções como se fossem obje-
formas: a primeira utilizando a função new, e outra tos num sistema OO, você pode passar uma fun-
na qual você coloca o nome da classe seguido de um ção para outra e ou receber, da execução de uma
ponto. Lembrando que Java optou por organizar as função, outra função.
classes em pacotes, e assim, para utilizar uma classe Construções básicas como funções: ao invés
nos referimos ao caminho completo ou importamos de uma sintaxe específica para iterações e estru-
o pacote ou classe. Em Clojure existe a função im- turas condicionais, construções básicas de uma
port, que faz justamente a importação dos pacotes e linguagem de programação, a solução é utilizar
ou classes. funções, seja pra iterar sobre uma coleção ou con-
O encadeamento de chamadas a métodos pode trolar o fluxo dos programas.
ser feito utilizando a função dot, ou mais facilmente
23 \
/eu uso
Phil Calçado
Desenvolvedor na SoundCloud, a plataforma que lidera a distribuição e socialização de música e áudio na Internet. Ele
bloga em [Link] e pode ser encontrado no twitter como @pcalcado.
Por volta de 2006, eu estava em um projeto Ruby e comecei a me deparar com as limitações desta lin-
guagem em termos de metaprogramação. Ao procurar uma melhor maneira de enfrentar estes problemas
eu acabei aprendendo Common Lisp e Scheme. Eu fiquei imediatamente excitado com as possibilidades
que Lisp traz, mas estas duas linguagens estavam muito distantes da minha realidade, que era basica-
mente projetos em Ruby, Java e C++.
Quando Clojure foi anunciada eu vi a oportunidade que faltava. A linguagem não traz algumas das
principais vantagens de Lisp, como reader macros, mas ainda assim provê um conjunto de ferramentas
fundamentais para a criação de Domain-Specific Languages; além do suporte bem maduro à Programa-
ção Funcional.
Hoje em dia eu uso Clojure para sistemas de análise de dados e também aplicações web. A produtivi-
dade que se atinge ao dominar o desenvolvimento em Lisp com emacs e seu REPL não possui equivalente
em nenhum outro ambiente que eu conheça.
Listagem 8. Interoperabilidade. muitas dessas suportam algumas técnicas para oti-
mização de performance. A linguagem Clojure su-
porta a ideia de dar dicas (hints) sobre os tipos para
; Criar objetos ajudar o compilador a compilar um código bem mais
(new [Link]) rápido, mas ao mesmo tempo seu código fica menos
([Link].) flexível. Para dar essas dicas ao compilador, você uti-
liza os metadados da linguagem, ou seja, dados sobre
; Importar pacotes/namespace os dados.
(import [Link]) Para criar metadados, basta utilizar o caractere
; Multiplas classes importadas; acento circunflexo. Esse metadado pode ser aplicado
(import ‘([Link] Date Calendar)
para informar os tipos, sejam eles primitivos, não-
‘([Link]))
-primitivos e arrays. Em tipos primitivos, basta utili-
zar o acento circunflexo antes do nome: ^int, e para
; Encadear chamadas a métodos.
os tipos complexos a regra é a mesma (ex: ^String). Já
(. (. “dkcr” toUpperCase) toLowerCase)
; ou simplifcando, tendo menos parênteses do que Java.
os arrays seguem uma regra um pouco diferente: os
mesmos são declarados como plurais dos tipos pri-
mitivos; logo, o metadado ^floats está informando ao
(.. “dkcr” toUpperCase toLowerCase)
compilador que espere um array de float.
Para exemplificar e quantificar o uso das dicas
; Passagem de parâmetros aos métodos de tipos, vamos construir um exemplo simples que
(System/getProperty “[Link]”)
se baseia em uma função que conta o número de ca-
racteres de uma String. Iremos escrever duas funções,
; JavaBean em forma de mapa uma com e outra sem hint. Para testar, vamos utilizar
(def date-map (bean ([Link].)))
cada uma das funções em uma lista de 5.000.000 de
; Obtendo os segundos e o tempo do mapa
(:seconds date-map) itens, somar todas essas contagens e ao mesmo tem-
(date-map :time) po marcar o tempo gasto. Depois de executar o código
da Listagem 9, observe que a versão sem hint levou
em média 4.000 milissegundos, enquanto a versão
com os hints levou em média apenas 365 milissegun-
Dicas de performance dos, uma diferença de mais de 100%. Lembre-se, fuja
Geralmente, as linguagens dinâmicas são mais de ajustes de performance prematuros, deixe existir
lentas do que as estaticamente tipadas. No entanto, a real necessidade para só então realizar os ajustes
necessários.
/ 24
Listagem 9. Funções e Benchmark. Vale citar que o provedor de plataforma nas nu-
vens (PaaS) Heroku já tem suporte à implantação de
projetos Clojure, o que faz seu alcance ainda mais
; Funções amplo, indo de um simples entusiasta que deseja tes-
(defn contar [valor] (.length valor)) tar a linguagem a um start-up que deseja apostar nes-
(defn contar-com-hint [^String valor] (.length valor)) sa nova linguagem. O padrão de integração escolhido
; Benchmark pelo Heroku foi os projetos gerenciados pelo lein.
(time (reduce + (map contar (repeat 1000000 “aeiou”))))
(time (reduce + (map contar-com-hint (repeat 1000000
“aeiou”)))) Considerações finais
O intuito do artigo não é ser um guia completo,
mas sim os primeiros passos e uma visão geral para
que você se liberte um pouco do medo e comece a
Ferramentas, Frameworks e afins estudar e se aprofundar. Assuntos como sequences,
Um dos fatores que pode mostrar o quanto uma namespace, macros, metadata, protocols, multiméto-
linguagem está sendo usada, testada e difundida são dos, agents, refs, atoms e outros ficaram de fora por
as ferramentas e frameworks existentes para a mes- questões de escopo e complexidade. Aqueles que de-
ma. A linguagem, apesar de bem nova e em evolução, sejam ser mais eficientes e usar a linguagem de fato,
já tem suporte em diversos IDEs bem como uma am- devem dominar tais assuntos, bem como o estudo e
pla gama de frameworks escritos em Clojure. uso mais apropriado e aprofundado das ferramentas
Sempre que se fala em uma nova linguagem, a e frameworks.
comunidade procura por IDEs para suportar a mes- Clojure oferece, entre outras coisas, alta reusabi-
ma, e para aqueles que desejam utilizar Clojure já há lidade, o alcance da JVM, acesso a todas as bibliotecas
suporte em alguns ambientes. Para os que gostam do Java já existentes, despreocupação de locks e sincro-
Netbeans, há um projeto paralelo chamado EnCloju- nização na criação de aplicativos multithread, uma
re ([Link] Para os amantes do Eclipse, comunidade forte e ferramentas e frameworks bem
há um plugin chamando Counter ClockWise (http:// testados. Tudo isso faz de Clojure, no mínimo, uma
[Link]/p/counterclockwise/). E para aque- linguagem a ser investigada.
les que não deixam de utilizar o IntelliJ, este também
já suporta a linguagem via plugin ([Link]
[Link]/plugin/?id=4050). Por fim, mesmo não /referências
sendo classificado como IDE por alguns, já há suporte Links
amplo para Clojure nos editores de texto Emacs e vi.
Para automação, resolução de dependências e > [Link]
outros, a linguagem conta com uma ótima ferramen- > [Link]
ta chamada Leiningen, ou apens lein ([Link]
com/technomancy/leiningen). Com essa ferramen- > [Link]
ta você consegue criar um projeto esqueleto, rodar > [Link]
testes, empacotar, implantar seus jars, inclusive para
um repositório on-line como o Clojars ([Link] > [Link]
org/), dentre outras tarefas. É bem comum ver proje-
> [Link]
tos no github que utilizam o padrão de pastas e orga-
nização proposto pela ferramenta. > [Link]
Como não deveria faltar, há frameworks para tes-
> [Link]
tes também para Clojure. Um deles é o Midje, e a es-
colha do mesmo como exemplo principal se deu ao Livros
fato de seu amadurecimento, quantidade de ajuda
> The Joy of Clojure, FOGUS, Michael e HOUSER, Chris;
disponível e constantes atualizações. De uma forma
bem simples, o criador do framework resolveu tratar, Ed. Manning
dado a natureza da linguagem, os testes como fatos, > Programming Clojure, HALLOWAY, Stuart; Ed.
logo, para testar se um mais um é dois, você pode es- Pragmatic Bookshelf
crever um fato.
> Clojure in Action, RATHORE, Amit; Ed. Manning
(fact (+ 1 1) => 2)
25 \