A intenção da minha pergunta não é iniciar uma guerra de insultos, mas sim determinar em que circunstâncias cada idioma é "a melhor ferramenta para o trabalho".
Eu li vários livros sobre Clojure ( Programming Clojure , Practical Clojure , The Joy of Clojure e a edição Manning Early Access de Clojure in Action ) e acho que é uma linguagem fantástica. No momento, estou lendo Let Over Lambda, que lida principalmente com macros Common Lisp e, também, é uma linguagem muito interessante.
Estou não um especialista em Lisp (mais de um novato), mas esta família de línguas me fascina, assim como a programação funcional, em geral.
Vantagens do Clojure (e desvantagens de "outros"):
É executado no JVM.
A JVM é um ambiente de linguagem muito estável e de alto desempenho que atende muito bem ao sonho da Sun de "Escreva uma vez, execute [quase] em qualquer lugar". Posso escrever código no meu Macbook Pro, compilá-lo em um arquivo JAR executável e executá-lo no Linux e no Microsoft Windows com poucos testes adicionais.
O (Hotspot e outros) JVM suporta coleta de lixo de alta qualidade e compilação e otimização just-in-time de muito desempenho. Onde, há poucos anos, escrevi tudo o que precisava ser executado rapidamente em C, agora não hesito em fazê-lo em Java.
Modelo padrão, simples, multithreading. O Common Lisp tem um pacote multithreading padrão?
Rompe a monotonia de todos aqueles parênteses com
[]
,{}
e#{}
, embora os especialistas em Common Lisp provavelmente me digam que com macros de leitor, você pode adicioná-los ao CL.
Desvantagens do Clojure :
- É executado no JVM.
- Sem recursão de cauda ou continuações. O Common Lisp suporta continuações? O esquema requer suporte para ambos, eu acredito.
Vantagens dos outros (Lisp comum, em particular) (e desvantagens do Clojure):
Macros de leitor definidas pelo usuário.
Outras vantagens?
Pensamentos? Outras diferenças?
fonte
Respostas:
Minha lista pessoal de razões para preferir Clojure a outros Lisps (ps, ainda acho que todos os Lisps são ótimos!):
É executado na JVM - portanto, obtém acesso automático à fantástica engenharia na própria JVM (algoritmos de coleta de lixo avançados, otimização HotSpot JIT etc.)
Muito boa interoperabilidade Java - fornece compatibilidade com a grande variedade de bibliotecas no ecossistema de linguagem Java / JVM. Usei Clojure como uma linguagem de "cola" para conectar diferentes bibliotecas Java com bons resultados. Como eu também desenvolvo muitos códigos Java, é útil para mim que o Clojure se integre bem com as ferramentas Java (por exemplo, eu uso Maven, Eclipse com o plugin no sentido anti-horário para meu desenvolvimento Clojure)
Boa sintaxe para vetores
[1 2 3]
, mapas{:bob 10, :jane 15}
e conjuntos#{"a" "b" "c"}
- considero essas ferramentas essenciais para a programação moderna (além das listas, é claro!)Eu pessoalmente gosto do uso de colchetes para formulários de vinculação: por exemplo
(defn foo [a b] (+ a b))
- acho que torna o código um pouco mais claro de ler.Ênfase na programação funcional preguiçosa com estruturas de dados persistentes e imutáveis - em particular toda a biblioteca Clojure principal é projetada para suportar isso por padrão
Excelente implementação de STM para simultaneidade multi-core. Eu acredito que Clojure tem a melhor história de simultaneidade de qualquer idioma no momento (veja este vídeo para mais detalhes do próprio Rich Hickey )
É um Lisp-1 (como Scheme), que pessoalmente prefiro (acho que em uma linguagem funcional faz sentido manter funções e dados no mesmo namespace)
fonte
Lembre-se de que Clojure é uma linguagem e uma implementação (geralmente na JVM). Common Lisp é uma linguagem com mais de dez implementações diferentes. Portanto, temos uma incompatibilidade de categoria aqui. Você pode, por exemplo, comparar Clojure com SBCL.
Geralmente:
uma versão do Common Lisp é executada na JVM: ABCL
a maioria das outras implementações Common Lisp não
a maioria das implementações CL tem recursos multitarefa, uma biblioteca fornece uma interface comum
Lisp comum tem sintaxe para matrizes. A sintaxe para outros tipos de dados pode ser escrita pelo usuário e é fornecida por várias bibliotecas.
Common Lisp não suporta otimização de chamada final nem continuações. As implementações fornecem TCO e as bibliotecas fornecem alguma forma de continuação.
fonte
Uma diferença importante entre Clojure e Common Lisp é que Clojure é mais prescritivo sobre programação funcional. A filosofia, expressões idiomáticas e, até certo ponto, linguagem / bibliotecas de Clojure encorajam fortemente e às vezes insistem que você programe de maneira funcional (sem efeitos colaterais, sem estado mutável).
O Common Lisp definitivamente suporta programação funcional, mas também permite estado mutável e programação imperativa.
Claro, há uma série de benefícios para a programação funcional, na área de simultaneidade e outras. Mas sendo tudo o mais igual, também é bom ter a escolha de qual abordagem você deseja usar para cada situação. Clojure não proíbe completamente a programação imperativa, mas é menos compatível com esse estilo do que o Common Lisp.
fonte
Aqui está um bom vídeo com uma comparação de Scheme (Racket principalmente) e Clojure .
Para ser justo, Racket tem sintaxe de açúcar (material de leitor adicional) para tipos de dados também (#hash, #, colchetes, etc.)
Além disso, a única maneira de Clojure fazer uma chamada final adequada é usar
recur
, essa é a desvantagem de compilar para JVM.fonte
trampoline
para chamadas de cauda.