Como estou apenas iniciando meus estudos em Lisp seria muita pretensão de minha parte dar uma resposta pessoal autência à pergunta “Por que Lisp?”
Para piorar a situação, hoje (2019-11-01), eu não estou 100% confiante de que todo o esforço que investirei será recompensado ou utilizado de forma prática em curto prazo (ou em prazo algum, na verdade).
Valerá a pena? Bem… quanto mais eu leio as opiniões de grandes “hackers” e programadores respeitados, mais confortável e seguro eu fico. Em resumo, todos dizem que Lisp é a melhor e mais poderosa linguagem de programação existentente hoje em dia (apesar da academia e mercado a considerarem uma linguagem morta). Se é a melhor, então por que não estudá-la?
Resolvi criar este texto que funciona como uma espécie de “guia de auto-ajuda motivacional” para me manter firme na tarefa de aprender, de fato, Lisp. Não só o “hello, world” mas, sim, as entranhas obscuras que os grandes programadores utilizam: se os grandes aprenderam com Lisp (entre outras linguagens), vou seguir o caminho já trilhado. Simples assim.
Atualizarei periodicamente este texo com base em meus estudos. Aprendi uma coisa nova? Algo ficou mais claro? Isso será refletido aqui. Os objetivos finais deste “guia de auto-ajuda motivacional” são:
- Ter bem claro o que é Lisp;
- Achar a resposta à pergunta “Por que usar Lisp?”; e
- Manter uma lista de referências que me permitam alcançar os objetivos anteriores e aprender Lisp.
1. O que é Lisp?
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 de sua forma principal de execução, o processamento de listas: LISt Processing.
A linguagem Lisp original evoluiu durante as décadas de 60 a 80 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:
- 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 criado para ter uma semântica excepcionalmente clara e simples. É um dialeto bem menor do que o Common Lisp (a especificação da Scheme tem cerca de 50-70 páginas, enquanto 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.
- 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.
1.1. 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”.
Considerando apenas os dialetos Common Lisp e Scheme (já que Elisp e Autolisp tem 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. Mas 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 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 definido em seus respectivos padrões, e 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).
1.2. Que dialeto/implementação utilizar?
Essa pergunta tem o potencial destrutivo semelhante à pergunta sobre o time de futebol preferido, ou sobre a distribuição Linux preferida. 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 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. Na dúvida, o Portacle é sua porta de entrada para o dialeto Common Lisp!
- Para Scheme: eu utilizo duas implementações, dependendo do meu humor e da fase da lua:
- “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.
2. Por que usar Lisp?
Porque…
- Joel Spolsky, um dos criadores do StackOverflow, recomenda enfaticamente aprender Lisp, em seu fenomenal artigo The Perils of JavaSchools;
- Eric Raymond, que dispensa apresentações, recomenda em seu artigo How to Become a Hacker;
- Paul Graham, o desenvolvedor da primeira ferramenta para desenvolvimento online de lojas virtuais (em Lisp, claro) e o autor dos livros ANSI Common Lisp e On Lisp, explica que Lisp é absolutamente fundamental para coisas complexas. Seu artigo Beating the Averages é leitura fundamental para entender como Lisp pode fazer a diferença em diversas situações. Aliás, Paul Graham tem uma série muito interessante de artigos sobre Lisp:
- Peter Norvig, que também dispensa apresentações, autor de Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp, tem uma série de artigos importantes sobre a utilidade de aprender e desenvolver em Lisp:
- Lisp: Where do we come from? What are we? Where are we going?
- Lisp as an alternative to Java
- A Retrospective on Paradigms of AI Programming (dados, um pouco antigos na verdade, mostram que Lisp é mais rápido que Java e Python e tem performance próxima de C)
- Python for Lisp Programmers (uma boa comparação entre Lisp e Python)
- Teach Yourself Programming in Ten Years (recomenda Python ou Scheme como a primeira linguagem a ser aprendida)
- Ron Garret tem alguns ótimos artigos sobre Lisp:
- Uma história interessante sobre o uso de Lisp no Jet Propulsion Lab da NASA em seu texto Lisping at JPL
- O motivo de Lisp ter muitos parênteses (e de porque é tão poderosa) é explicado em Why Lisp?
- O que faz Lisp tão boa é detalhado em Yes, code is data, but that’s not what makes Lisp cool
- Alguns pensamentos interessantes em Is it Lisp or is it me?
- Rudolf Winestock escreveu um ótimo ensaio intitulado The Lisp Curse, onde descreve “A Maldição da Lisp”: a incapacidade de Lisp ser mais difundida e utilizada é causada justamente por seu poder: “Lisp is so powerful that problems which are technical issues in other programming languages are social issues in Lisp.”
- Mark Tarver escreveu um ótimo ensaio, The Bipolar Lisp Programmer, e defende que Lisp tende a atrair as melhores mentes e também os maiores fracassos.
- Richard P. Gabriel publicou, em 1991, o texto Lisp: Good News, Bad News, How to Win Big, onde faz um balanço das vantagens e desvantagens da Lisp. Também tem vários outros ensaios interessantes sobre o tema.
3. Como aprender?
De forma geral, além dos links citados nas seções acima, existem duas categorias globais de livros sobre Lisp:
- Livros sobre a linguagem Lisp em si, tanto para a Common Lisp quanto para a Scheme; e
- Livros que usam Lisp para ensinar conceitos de ciência da computação.
Minha abordagem é a seguinte:
- Começar com livros sobre a linguagem Lisp em si:
- Estudar o Practical Common Lisp, de Peter Seibel
- Depois, ou de forma simultânea, estudar algum entre:
- Simple Scheme, de Brian Harvey e Matthew Wright
- The Scheme Program Language, de R. Kent Dybvig
- The Little Schemer, de Daniel Friedman e Matthias Felleisen
- The Seasoned Schemer, de Daniel Friedman e Matthias Felleisen
- The Reasoned Schemer, de Daniel Friedoman, William Byrd e Oled Kiselyov
- Continuar com livros mais avançados e/ou sobre ciência da computação:
- Structure and Interpretation of Computer Programs, de Hal Abelson, Jerry Sussman e Julie Sussman.
- How to Design Programs, de Matthias Felleisen, Robert Findler, Matther Flatt e Shriram Krishnamurthi.
- Common Lisp Recipes: a problem-solution approach, de Edmund Weitz
- On Lisp, de Paul Graham
- Let Over Lambda, de Doug Hoyte
Incrível o conteúdo. Obrigado pelo ensino! S2
19/09/2022 estou estudando lisp para ter uma base sobre os fundamentos.
Estou fazendo esse curso aqui.
https://ocw.mit.edu/courses/6-001-structure-and-interpretation-of-computer-programs-spring-2005/pages/lecture-notes/
Muito bom, o MIT 6.001 foi um dos cursos que iniciou uma revolução no ensino da ciência da computação. Mas note que ele é em Scheme (um dialeto Lisp) e muito, mas MUITO difícil mesmo. Eu estou gravando uma série de vídeos para preparar os interessados para o estudo futuro do SICP, a “Série Pré-SICP”, no canal do Computação Raiz no YouTube. Se tiver interesse, visite: https://www.youtube.com/playlist?list=PLk3bkShxC-bADG9hi7TJhP3cCI-hpfedO