A linguagem Lisp foi criada por John McCarthy em 1956, para o processamento de dados simbólicos, no contexto de desenvolvimento de programas para inteligência artificial e resolução de problemas complexos. Seu nome deriva da forma de operação em sua principal estrutura de dados, a lista: LISt Processing. A linguagel parece um tanto quanto “estranha” para quem a vê pela primeira vez:
Mesmo sendo a segunda linguagem de programação mais antiga em uso atualmente (Fortran é mais antiga por um ano), ainda é considerada a linguagem de programação mais poderosa existente (leia Revenge of the Nerds e Beating the Averages, ambos de Paul Graham, e também The Perils of JavaSchools, de Joel Spolsky, para saber que tipo de “poder” é esse).
De seu início acadêmico na década de 50, a linguagem Lisp evoluiu muito durante as décadas de 60 a 90 e deu origem a diversos dialetos e implementações diferentes. Os quatro dialetos (e suas implementações) mais importantes e comuns hoje em dia são a Common Lisp, a Scheme, a Elisp e a Autolisp:
- Common Lisp: foi criada como uma padronização das melhores características de diversos outros dialetos Lisp, e é o dialeto mais utilizado hoje em dia. O trabalho de padronização dos dialetos existentes está descrito no livro Common Lisp: the language, de Guy Steele, publicado em 1984. A Common Lisp tornou-se um padrão ANSI em 1996. As principais implementações da Common Lisp são:
- SBCL (Steel Bank Common Lisp): é uma implementação open-source da Common Lisp para Linux, Unix, MacOS e Windows. Talvez seja a mais utilizada.
- CCL (Clozure Common Lisp): também é uma implementação open-source muito utilizada.
- CLISP: é uma implementação open-source mantida na Alemanha.
- CLASP: é uma implementação open-source com integração com bibliotecas C++.
- CMUCL (Carnegie Mellon University Common Lisp): é uma implementação open-source para sistemas Unix.
- AllegroCL: é uma implementação comercial com muitas bibliotecas e adições ao padrão original.
- LispWorks: também é uma implementação comecial com muitas bibliotecas e adições ao padrão original.
- Outras: existem diversas outras implementações da Common Lisp, cada uma com suas vantagens e desvantagens.
- Scheme: é um dialeto Lisp criado por Guy Lewis Steele Jr. e Gerald Jay Sussman, no Massachussets Institute of Techonology (MIT), criado para ter uma semântica excepcionalmente clara e simples. É um dialeto bem menor do que o Common Lisp (para comparação, considere que a especificação da Scheme tem cerca de 70 páginas e a especificação da Common Lisp tem mais de 1.000 páginas). É um dialeto utilizado em universidades por todo o mundo por suas características de simplicidade e poder de expressão (a referência básica e obrigatória é o Structure and Interpretation of Computer Programs, de Harold Abelson e Gerald Jay Sussman), e se tornou um padrão IEEE em 1990. As principais implementações da Scheme são:
- MIT/GNU Scheme: é a implementação open-source mais famosa e a mais utilizada. Foi utilizada durante décadas como a linguagem de programação “oficial” da graduação em ciência da computação no MIT.
- Racket: talvez seja a implementação open-source Scheme mais adequada para os iniciantes, trazendo junto da linguagem um ecossistema e interface gráfica para desenvolvimento. Na verdade a Racket evoluiu bastante e já se tornou uma linguagem própria.
- Guile: é uma implementação open-source interessante, com diversas funcionalidades embutidas, como um servidor web.
- Scheme 48: é uma implementação open-source pequena e portável.
- SCM: também é uma implementação open-source portável.
- Outras: existem mais de 20 implementações da Scheme, cada uma com suas vantagens e desvantagens.
- Elisp: é o dialeto Lisp utilizado como a linguagem de programação e extensão do Emacs.
- Autolisp: é o dialeto Lisp utilizado como linguagem de extensão do AutoCAD.
Dialeto x Implementação
Uma diferença importante da Lisp com outras linguagens de programação como, por exemplo, Python, Java e C#, é que a Lisp não é um “produto”, uma “linguagem pronta” única, controlada e distribuída de forma centralizada por uma empresa, pessoa, associação ou organização.
Considerando apenas os dialetos Common Lisp e Scheme (já que Elisp e Autolisp têm fins específicos e estão ligados, respectivamente, ao Emacs e ao AutoCAD), cada dialeto é definido apenas por seu padrão, um documento escrito com a especificação detalhada do dialeto:
- Common Lisp Standard: o padrão oficial é vendido no site do ANSI, apenas em formato PDF (com formatação não tão agradável de leitura). Como a versão oficial em PDF não é distribuída gratuita e livremente, existe uma versão HTML que é considerado “o” padrão atual (principalmente por ser online): o Common Lisp HyperSpec.
- Scheme Standard: o padrão oficial é vendido no site do IEEE, também em formato PDF, mas existem diversas atualizações e novos padrões disponíveis na internet.
Não existe um “dono” ou um “produto” Lisp… o que existem são dialetos definidos por seus padrões e, assim, qualquer pessoa, instituição ou empresa pode ler os padrões e implementar a sua própria versão da linguagem (o dialeto). Eu poderia estudar os padrões e criar o “Abrantes Common Lisp” ou o “Abrantes Scheme”, implementações para os dois dialetos mais importantes.
A importância disso é que os padrões definem um contrato entre a pessoa que implementou a linguagem e os programadores que utilizarão a implementação Lisp criada. Esse contrato é o seguinte: se você escrever um programa que utiliza apenas as características definidas no padrão, você pode ter certeza de que seu programa funcionará da mesma maneira em qualquer implementação que seja conforme ao padrão.
As implementações da Common Lisp e da Scheme geralmente implementam tudo o que está definido em seus respectivos padrões e, além disso, acrescentam várias outras funcionalidades. Você pode então decidir usar somente as características padronizadas do dialeto, para maximizar a portabilidade entre diferentes implementações, ou decidir por utilizar funcionalidades específicas de uma determinada implementação (facilitando o desenvolvimento ao custo de uma menor portabilidade).
Que dialeto/implementação utilizar?
Essa pergunta tem o potencial destrutivo semelhante a perguntas sobre o melhor time de futebol (claro que é o Vasco) ou sobre a distribuição Linux (Ubuntu, SuSE ou Debian, por favor). Cada pessoa gosta de um dialeto e de uma implementação, então o melhor a fazer é experimentar várias. Minhas preferências em cada dialeto são:
- Para Common Lisp: eu utilizo a implementação SBCL com duas versões de ambiente de desenvolvimento:
- “Softcore”: para iniciantes no Common Lisp, o melhor ambiente integrado de desenvolvimento é o Portacle, que é um pacote portável que inclui a implementação SBCL, uma IDE baseada no Emacs (incluindo o SLIME, o Magit! e o Company) e o Quicklisp. O Portacle tem distribuições para Linux, Unix, Windows e MacOS. O Portacle é um ambiente de desenvolvimento pronto para uso e completo, basta fazer o download, descompactar e começar a usar!
- “Hardcore”: depois de adquirir uma certa desenvoltura você pode achar que os padrões do Portacle não servem exatamente para o que você quer ou o seu estilo de programação. Você pode configurar o Portacle (até certo limite) ou então instalar um ambiente de desenvolvimento próprio do zero, com o SBCL, o Emacs, o SLIME, e Company e o Quicklisp, instalando e configurando tudo manualmente.
- Para Scheme: eu utilizo a implementação MIT/GNU Scheme, também com duas versões de ambiente de desenvolvimento:
- “Hardcore”: eu faço a instalação da MIT/GNU Scheme manualmente e utilizo o Emcas como IDE de programação (esse é o ambiente que eu mais utilizo) ou a interface própria da MIT/Scheme, o Edwin;
- “Softcore”: para coisas mais simples e “visuais”, eu utilizo o Racket e sua IDE integrada.