Clojure é uma linguagem LISP-style para a JVM. Um dos focos de Clojure é concorrência, que é suportado através de suas estruturas de dados imutáveis (Clojure vem com estruturas de dados persistentes). Outra funcionalidade é Software Transactional Memory (STM), que permite usar transações, ao invés de Locks ou Mutexes, para compartilhar memória. Enquanto STM é uma tecnologia controversa que ainda precisa se provar, ter acesso a uma implementação na JVM oferece uma forma fácil de experimentá-la.
Espera-se que Clojure alcance o release 1.0 num futuro próximo e muito das bibliotecas Clojure já estão disponíveis. Algumas delas tiraram inspiração de bibliotecas Ruby, apenas para listar algumas:
- Compojure é um framework web escrito em Clojure que, de acordo com seu arquivo README, foi inspirado no framework web Sinatra escrito em Ruby.
- Ring é uma forma de oferecer serviços HTTP, similar ao WSGI do Python e o Rack do Ruby.
- clj-record é uma implementação do ActiveRecord ORM mapper.
- Lancet ferramenta criada por Stuart Halloway, para build automatizados em Clojure, como o Rake.
- clj-haml é um port da biblioteca HALM do Ruby.
Biblioteca Clojure inspiradas pelo Ruby são uma forma das duas linguagens interagirem. Outra forma é o JRuby - as duas linguagens compartilham o mesmo ambiente de execução, a JVM.
Daniel Kwiecinski explora a idéia de combinar JRuby e Clojure em um post e experimenta tornando estruturas de dados Clojure disponíveis para o JRuby como objetos Ruby.
Particularmente interssante são as estruturas de dados persistentes da Clojure, por exemplo seus vetores persistentes. Nota: Neste contexto, a palavra "persistente" não se refere a dados sendo persistidos no disco. Estruturas de dados persistidos são imutáveis; modificações, como inserções, são possível mas eles sempre geram uma nova 'cópia' de toda a estrutura de dados. A implementação de Clojure e a restrição de imutabilidade permite escapar de fazer uma cópia profunda (deep copy) completa; ao invés disso, somente um delta relativamente pequeno precisa ser copiado. Karl Krukow mostra a implementação do Vetor Persistente de Clojure e explica como seu comportamento de performance é alcançado.
Outra oportunidade para desenvolvedores Jruby é o suporte de Clojure ao STM, que oferece uma forma para os desenvolvedores Ruby exeprimentar este conceito. Mesmo que o código Ruby não use explicitamente qualquer funcionalidade em particular do Clojure STM, ainda é possível escrever o modelo base da aplicação em Clojure e usar o JRuby como parte de front-end, seja com Rails ou qualquer outro framework Ruby.
Outra opção ẃ usar Clojure para gargalos de performance. Apesar de a performance do JRuby estar rapidamente melhorando, ainda á situações onde pode ser interessante trocar a flexibilidade e polimorfismo do (J)Ruby por performance. No MRI, os gargalos de performance em uma aplicação Ruby podem ser corrigidos escrevendo uma extensão nativa. Em JRuby, uma solução é escrever código em Java, seja através de código fonte Java ou uma forma de gerar bytecode JVM (tanto bytecode generation com uma DSL de bytecode em Ruby ou uma linguagem como Duby de Charles Nutters).
Escolher uma linguagem de baixo nível, linguagem de sistema, seja em C (para MRI) ou Java (para JRuby) tem um lado ruim óbvio: descer ao nível do Java e perder características como Blocos, muitos tipos de metaprogramação, etc.
Clojure é uma solução possível para este problema: a linguagem tem vários níveis de flexibilidade. Por exemplo, funções normais Clojure tem pouco overhead de chamadas porque elas são em sua maior parte reduzidas a chamadas estáticas de métodos. Clojure oferece estilos diferentes de polymorfismo em runtime, por exemplo na forma de multi-métodos.
Clojure é uma LISP e vem com um sistema poderoso de macro. Maros permitem metaprogramação em tempo de compilação, que traz ainda mais oportunidades para diminuir a geração de código para o computador (invés de escrever código chato e repetitivo em Java manualmente). O código Clojure é sempre compilado para bytecode da JVM, compilação Ahead Of Time (AOT) também é suportada. Cliff Click da Azul olhou de perto a performance de algumas linguagens da JVM, incluindo Clojure e JRuby e informou sobre a performance de Clojure. Enfim, Clojure oferece muitas poportunidades para escrever código rápido em um estilo elegante.
O outro lado da medalha é claro, uma questão de dependências: usar Clojure significa uma outra dependência para o projeto. Se é uma boa idéia adicionar outra linguagem, ainda pouco conhecida, como Clojure a um projeto, é uma questão que cada time deve responder.
A solução STM para concorrência e dados compartilhados foi massivametne debatida. O criador de Clojure Rich Hickey teve uma longa discussão com Cliff Click sobre o STM. Outra fonte de informação sobre STM é a edição de Setembro da ACMQueue, sobre concorrência.
O que você acha: JRuby e Clojure - uma boa combinação?