Lisp, abreviação de "LISt Processing" (Processamento de Listas), é uma família de linguagens de programação que compartilham uma sintaxe distinta baseada em parênteses, centrada principalmente na manipulação de símbolos e listas. É uma das linguagens de programação de alto nível mais antigas, originalmente inventada no final da década de 1950, e evoluiu significativamente ao longo das décadas. Lisp é particularmente conhecido por seus recursos poderosos, como tipagem dinâmica, coleta de lixo e funções de primeira classe, tornando-o adequado para pesquisa em IA, computação simbólica e prototipagem rápida.
Lisp foi criado por John McCarthy em 1958 como uma notação matemática para programas de computador e como um meio prático de implementar IA. A linguagem foi derivada do cálculo lambda, um sistema formal em lógica matemática e ciência da computação. A primeira implementação foi realizada no IBM 704, e logo depois, numerosos dialetos surgiram, cada um adicionando suas próprias características e complexidades.
Vários dialetos notáveis de Lisp surgiram ao longo do tempo, incluindo Common Lisp e Scheme. Common Lisp foi padronizado na década de 1980 para unificar vários dialetos, enquanto Scheme, que enfatiza a programação funcional e o minimalismo, ganhou popularidade na academia. Influências de Lisp podem ser vistas em muitas linguagens de programação modernas, especialmente aquelas que suportam paradigmas de programação funcional, como Clojure, Racket e até mesmo linguagens como Python e Ruby.
Hoje, Lisp não está entre as linguagens de programação mais populares, mas continua a ser influente, particularmente em pesquisa, IA e educação. A comunidade desenvolve ativamente novos dialetos como Clojure, que roda na Java Virtual Machine (JVM) e foca na programação concorrente.
Lisp emprega uma sintaxe única usando parênteses para denotar expressões, com o código representado em expressões simbólicas (S-expressions). Por exemplo:
(+ 1 2)
Essa expressão representa a adição de 1 e 2.
Funções em Lisp podem ser passadas como argumentos, retornadas de outras funções e atribuídas a variáveis:
(defun square (x) (* x x))
(mapcar #'square '(1 2 3 4)) ; retorna (1 4 9 16)
Lisp é dinamicamente tipado, permitindo que variáveis mantenham valores de qualquer tipo de dado sem declaração prévia:
(setq x 10) ; x agora é um número
(setq x "hello") ; x agora é uma string
Lisp possui poderosos sistemas de macros que permitem aos desenvolvedores criar construções sintáticas personalizadas:
(defmacro when (condition &body body)
`(if ,condition
(progn ,@body))
)
As formas if
e cond
facilitam o controle de fluxo em Lisp:
(if (> x 0)
(print "Positivo")
(print "Não positivo"))
Lisp trata listas como estruturas de dados fundamentais:
(setq my-list '(1 2 3 4))
(car my-list) ; retorna 1
(cdr my-list) ; retorna (2 3 4)
Funções são definidas usando a construção defun
:
(defun factorial (n)
(if (= n 0)
1
(* n (factorial (- n 1)))))
Common Lisp inclui um sistema orientado a objetos conhecido como Common Lisp Object System (CLOS):
(defclass person ()
((name :initarg :name :accessor person-name)
(age :initarg :age :accessor person-age)))
(defmethod say-hello ((p person))
(format t "Olá, meu nome é ~A e eu tenho ~A anos."
(person-name p) (person-age p)))
Lisp fornece um sofisticado mecanismo de tratamento de erros usando handler-case
:
(handler-case
(/ 1 0)
(division-by-zero () (print "Capturado divisão por zero!")))
Continuações são suportadas em alguns dialetos, permitindo que o programa salve e restaure estados de execução:
(call-with-current-continuation
(lambda (k)
(k 10)))
Vários Ambientes de Desenvolvimento Integrados (IDEs) e compiladores atendem à programação em Lisp. As escolhas populares incluem:
Para construir um projeto Lisp, você geralmente cria um arquivo com a extensão ".lisp" ou ".lsp". Usando SBCL, um fluxo de trabalho típico pode envolver carregar seu projeto a partir do REPL:
(load "my-project.lisp")
Para projetos que utilizam Quicklisp, um gerenciador de bibliotecas, as dependências podem ser facilmente gerenciadas e carregadas.
Lisp é particularmente conhecido por suas aplicações em inteligência artificial, computação simbólica e academia, mas também encontra usos em:
Lisp é frequentemente comparado a:
A tradução de Lisp para outras linguagens é frequentemente feita usando ferramentas de tradução de código fonte para código fonte. Por exemplo, as seguintes ferramentas existem:
Cada uma dessas ferramentas fornece mapeamentos específicos que garantem que as funcionalidades principais de Lisp possam ser efetivamente representadas nas linguagens de destino. Para traduções mais complexas, pode ser necessário refatoração manual, especialmente para código fortemente otimizado por macros.