ATENÇÃO: ESTE LIVRO ESTÁ ALTAMENTE INCOMPLETO! O objetivo é prover uma tradução apropriada para o Common Lisp Cookbook original, em concordância com o licenciamento e com o texto do mesmo. Visite o repositório no GitHub e nos ajude a traduzi-lo.

ATENÇÃO: CAPÍTULOS AINDA ESTÃO FALTANDO. Caso queira consultar informações faltantes, você pode achar o Cookbook original neste link.

The Common Lisp Cookbook (PT-BR)

Cookbook, subst.
um livro contendo receitas e outras informações sobre a preparo e cozimento de comida.

agora com Lisp extra (e com cobertura de Português do Brasil!)

Informações

Este é um projeto colaborativo focado em prover, para Common Lisp, algo similar ao Perl Cookbook, publicado pela O'Reilly. Mais detalhes sobre o que este livro é e o que ele não é podem ser encontrados neste tópico encontrado em comp.lang.lisp.

Se você quer contribuir com o CL Cookbook, por favor, envie um pull request ou preencha uma issue no GitHub!

Sim, estamos falando com você! Precisamos de mais contribuidores - escreva um capítulo que está faltando e adicione-o, encontre uma pergunta em aberto e dê uma resposta, encontre bugs e reporte-os (se você não tem ideia do que falta mas gostaria de ajudar, dê uma olhada no índice do Perl Cookbook). Não se preocupe com a formatação, apenas envie texto simples se você quiser - cuidaremos disso depois.

Desde já, obrigado pela sua ajuda!

Notas dos tradutores

Este livro é uma tradução direta, para o Português brasileiro, do Common Lisp Cookbook, pela comunidade Common Lisp Brasil.

Caso haja erros de tradução ou de Português nestas páginas, você está livre para contribuir no mesmo formato provido acima, ou poderá abrir uma issue no repositório desta tradução.

Nosso foco primário é na pura tradução do Cookbook original, portanto, se você está interessado em contribuir com conteúdo novo, por favor, dirija-se ao repositório original.

Contribuidores

Finalmente, o crédito por finalmente dar a luz ao projeto provavelmente vai para "dj_special_ed", que postou esta mensagem em comp.lang.lisp.

Tradutores

Outros recursos

Licença

Redistribution and use of the "Common Lisp Cookbook" in its orginal form (HTML) or in 'derived' forms (PDF, Postscript, RTF and so forth) with or without modification, are permitted provided that the following condition is met:

  • Redistributions must reproduce the above copyright notice, this and the following disclaimer in the document itself and/or other materials provided with the distribution.

IMPORTANT: This document is provided by the Common Lisp Cookbook Project "as is" and any expressed or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the Common Lisp Cookbook Project be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this documentation, even if advised of the possibility of such damage.

LispCookbook GithubGroup addendum: this document is now managed in a modified format.

Copyright:
2015-2017 LispCookbook Github Group
2002-2007 The Common Lisp Cookbook Project.

Começando

Passos simples para instalar um ambiente de desenvolvimento e iniciar um projeto.

Quer uma instalação em dois-cliques? Então veja o Portacle, um ambiente portátil e multiplataforma de Common Lisp. Ele inclui Emacs25, SBCL (a implementação), Quicklisp (gerenciador de pacotes), Slime (a IDE) e Git. É a forma mais rápida de começar!

Instalando uma implementação

com seu gerenciador de pacotes

TL;DR:

apt-get install sbcl

Common Lisp foi padronizado através de um documento ANSI, então ele pode ser implementado de diversas formas; veja a lista de implementações da Wikipédia.

As implementações a seguir são empacotadas para o Debian e provavelmente também para a sua distro:

Em dúvida, apenas use o SBCL.

Veja também:

e este pacote Debian para Clozure CL.

com Roswell

Roswell é:

  • um gerenciador de implementações: torna mais fácil instalar uma implementação de Common Lisp (ros install ecl), uma exata versão de uma implementação (ros install sbcl/1.2.0), e mudar para uma implementação padrão (ros use ecl);
  • um ambiente de scripting (ajuda a executar Lisp através do shell, obter argumentos de linha de comando, ...);
  • um instalador de scripts;
  • um ambiente para testes (para executar testes, incluindo em plataformas populares de Integração Contínua);
  • uma ferramenta de compilação (para compilar imagens e executáveis de forma portátil).

Você encontrará diversas formas de instalação na Wiki do Roswell (pacote Debian, instalador Windows, Brew/Linux Brew, etc).

com Docker

Se você já conhece o Docker, você pode começar a usar Common Lisp rapidamente. A imagem daewok/lisp-devel-docker inclui as versões recentes de SBCL, CCL, ECL e ABCL, além de Quicklisp instalado na pasta home (/home/lisp) para que possamos executar ql:quickload logo de cara.

Funciona em GNU/Linux, Mac e Windows.

O comando a seguir baixará a imagem requerida (mais ou menos 400MB), colocará seus arquivos de código locais dentro da imagem Docker, onde indicado, e mostrará o REPL do SBCL:

docker run --rm -it -v /path/to/local/code:/usr/local/share/common-lisp/source daewok/lisp-devel:base sbcl`

Mas nos ainda queremos desenvolver usando Emacs e Slime, então precisamos conectar o Slime ao Lisp dentro do Docker. Veja slime-docker para uma biblioteca que o ajudará a configurar isto.

Iniciando um REPL

Apenas abra o executável da implementação na linha de comando para entrar no REPL (Read Eval Print Loop, ou Laço de Leitura-Interpretação-Escrita).

Saia com (quit) ou ctrl-d (em algumas implementações).

Eis um exemplo de uma sessão:

[email protected]:~$ sbcl
This is SBCL 1.3.14.debian, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses.  See the CREDITS and COPYING files in the
distribution for more information.
* (+ 1 2)

3
* (quit)
[email protected]:~$

Você pode melhorar um pouco o REPL (as teclas de setas não funcionam, ele não tem um histórico de comandos, ....) com o programa rlwrap:

apt-get install rlwrap

E então:

rlwrap sbcl

Mas nós configuraremos nosso editor para oferecer uma melhor experiência, ao invés de trabalhar diretamente neste REPL. Veja Suporte de Editores de Texto.

TODO: subsituir o link acima.

Libraries (Bibliotecas)

Common Lisp tem centenas de libraries disponíveis sob uma licença livre de software. Veja:

  • Quickdocs - a biblioteca de documentação para CL.
  • A lista Awesome-cl, uma lista curada de librariess.
  • Cliki, a wiki de Common Lisp.

Terminologia

  • No mundo de Common Lisp, um package (pacote) é uma forma de agrupar símbolos e prover encapsulamento. É similar a um namespace de C++, um module (módulo) de Python ou a um package de Java.

  • Um system (sistema) é uma coleção de códigos-fonte de CL, agrupados com um arquivo .asd que informa como compilá-los e carregá-los. Às vezes, há um relacionamento próximo entre systems e packages, mas isto não é algo obrigatório. Um system pode declarar uma dependência por outro system. Systems são gerenciados pelo ASDF (Another System Definition Facility), que oferece funcionalidades similares ao make e ao ld.so, e se tornou um padrão.

  • Uma library (biblioteca) ou um project (projeto) de Common Lisp normalmente consiste de um ou vários systems ASDF (e é distribuído como um project Quicklisp).

Instalando o Quicklisp

Quicklisp é mais que um gerenciador de pacotes, ele também é um repositório central (um dist) que assegura que todas as bibliotecas compilem juntas.

Ele providencia seu próprio dist, mas também é possível criar o seu próprio.

Para instalá-lo, nós podemos:

1 - Executar o seguinte comando, em qualquer lugar:

curl -O https://beta.quicklisp.org/quicklisp.lisp

e entrar em um REPL Lisp e carregar o arquivo baixado:

sbcl --load quicklisp.lisp

Ou:

2 - Instalar o pacote Debian:

apt-get install cl-quicklisp

e carregá-lo, de um REPL:

(load "/usr/share/cl-quicklisp/quicklisp.lisp")

E então, em ambos os casos, ainda através do REPL:

(quicklisp-quickstart:install)

Isto criará o diretório ~/quicklisp/, onde Quicklisp manterá seu estado e seus projetos baixados.

Se você quer que o Quicklisp seja sempre carregado em suas sessões Lisp, execute (ql:add-to-init-file): isto adicionará os comandos certos ao arquivo de inicialização da sua implementação de CL. Do contrário, você deverá executar (load "~/quicklisp/setup.lisp") em cada sessão, se você quiser utilizar o Quicklisp ou uma das bibliotecas instaladas através do mesmo.

Este comando adiciona o seguinte em (por exemplo) seu arquivo ~/.sbclrc:

#-quicklisp
  (let ((quicklisp-init (merge-pathnames "quicklisp/setup.lisp"
                                         (user-homedir-pathname))))
    (when (probe-file quicklisp-init)
      (load quicklisp-init)))

Instalando libraries

No REPL:

(ql:quickload "nome-do-package")

e voilà. Veja a documentação do Quicklisp para mais comandos.

Note, também, que dezenas de libraries Common Lisp estão empacotadas como pacotes Debian. O nome dos pacotes normalmente começam com o prefixo cl- (use apt-cache search --names-only "^cl-.*" para listar todos eles).

Por exemplo, para utilizar a library CL-PPCRE (para expressões regulares), deve-se, primeiramente, instalar o pacote cl-ppcre.

Então, no SBCL ou no ECL, este pode ser utilizado com:

(require "asdf")
(require "cl-ppcre")
(cl-ppcre:regex-replace "fo+" "foo bar" "frob")

Veja mais: https://wiki.debian.org/CommonLisp

Gerenciamento avançado de dependências

Perceba que estas informações não são necessárias para começar.

Quicklisp instala as libraries no diretório ~/quicklisp/local-projects/. Uma library ali instalada estará automaticamente disponível para qualquer projeto.

Fornecendo sua própria versão de uma biblioteca: Clonando projects

Dada a propriedade acima, podemos clonar qualquer library para o diretório local-projects e ele será encontrado pelo Quicklisp e disponível logo em seguida:

(ql:quickload "package")

Como trabalhar com versões locais de libraries

Se precisarmos de que bibliotecas sejam instaladas localmente, para apenas um projeto, ou para facilmente embarcar uma lista de dependências com uma aplicação, podemos utilizar o Qlot.

Quicklisp também fornece bundles Quicklisp. São conjuntos independentes de systems que são exportados do Quicklisp e carregáveis sem envolvê-lo.

Por fim, há também o Quicklisp controller, para nos ajudar a construir dists.

Trabalhando com Projects

Agora que temos Quicklisp e nosso editor prontos, podemos começar a escrever código Lisp em um arquivo e interagir com o REPL.

Mas, e se quisermos trabalhar com um projeto existente, ou criar um novo? Como procedemos, qual a sequência correta de defpackages, o que colocar em um arquivo .asd, e como carregar um projeto no REPL?

Criando um novo project

Alguns criadores de projects ajudam a criar a estrutura do projeto. Gostamos de cl-project, que também configura um esqueleto para testes.

Em resumo:

(ql:quickload "cl-project")
(cl-project:make-project #P"./caminho/para/raiz/do/projeto/")

Isto criará uma estrutura de diretório como essa:

|-- my-project.asd
|-- my-project-test.asd
|-- README.markdown
|-- README.org
|-- src
|   `-- my-project.lisp
`-- tests
    `-- my-project.lisp

Onde my-project.asd lembra o seguinte:

(defsystem "my-project"
  :version "0.1.0"
  :author ""
  :license ""
  :depends-on ()  ;; <== list of Quicklisp dependencies
  :components ((:module "src"
                :components
                ((:file "my-project"))))
  :description ""
  :long-description
  #.(read-file-string
     (subpathname *load-pathname* "README.markdown"))
  :in-order-to ((test-op (test-op "my-project-test"))))

E src/my-project.lisp lembra isto:

(defpackage footest
  (:use :cl))
(in-package :footest)

Como carregar um project existente

Você criou seu novo project, ou tem um project existente, e você gostaria de trabalhar com ele no REPL, mas o Quicklisp não o conhece. O que fazer?

Primeiramente, se você criá-lo ou cloná-lo em ~/quicklisp/local-projects, você poderá (ql:quickload ...) seu project, sem mais ressalvas.

Usualmente, você vai querer "entrar" no system, através do REPL, neste estágio:

(use-package :my-project)

Por fim, você poderá compilar ou interpretar os códigos-fonte (my-project.lisp) com C-c C-k ou C-c C-c1 (slime-compile-defun) em um form, e ver seu resultado no REPL.

Outra solução é usar a lista de projects conhecidos do ASDF:

(pushnew "~/caminho/para/raiz/do/projeto/" asdf:*central-registry* :test #'equal)

E, já que o ASDF é integrado ao Quicklisp, nós podemos dar quickload no project.

Feliz hacking!

1 N. do T.: Estes atalhos dizem respeito ao Emacs ou ao Portacle. Não se preocupe por ainda não compreendê-los.

Mais configurações

Você pode querer definir o formato padrão de codificação do SBCL para UTF-8:

(setf sb-impl::*default-external-format* :utf-8)

Você pode adicionar isso ao seu ~/sbclrc.

Leia Mais

Créditos