Lisp é uma família de linguagens de programação criada no fim dos anos 1950 por John McCarthy.
O nome vem de LISt Processing, ou seja, processamento de listas.
Lisp é uma das linguagens mais antigas ainda em uso e teve enorme influência em áreas como:
Quando alguém fala “Lisp”, pode estar se referindo a várias linguagens parecidas, como:
Lisp não é apenas uma linguagem específica. É uma ideia de linguagem.
A característica mais importante de Lisp é que código e dados têm praticamente a mesma estrutura.
Em muitas linguagens, código e dados são coisas bem separadas.
Em Lisp, o próprio código é escrito como listas.
Exemplo:
(+ 2 3)
Isso significa:
some 2 e 3
O resultado é:
5
Em Python, você escreveria:
2 + 3
Em Lisp, o operador vem primeiro:
(+ 2 3)
Esse estilo se chama notação prefixada.
A sintaxe de Lisp é baseada em parênteses.
Uma expressão Lisp geralmente tem esta forma:
(função argumento1 argumento2 argumento3)
Exemplos:
(+ 1 2)
Resultado:
3
(* 4 5)
Resultado:
20
(- 10 3)
Resultado:
7
(/ 20 4)
Resultado:
5
Uma expressão pode conter outras expressões:
(* (+ 2 3) 4)
Primeiro:
(+ 2 3)
Resultado:
5
Depois:
(* 5 4)
Resultado final:
20
Listas são fundamentais em Lisp.
Exemplo de lista:
'(1 2 3 4)
O apóstrofo ' impede que Lisp tente executar a lista como código.
Sem o apóstrofo, Lisp pensaria que 1 é uma função:
(1 2 3 4)
Isso normalmente causaria erro.
Com o apóstrofo:
'(1 2 3 4)
Lisp entende que isso é dado, não código.
Outro exemplo:
'(maçã banana laranja)
Isso é uma lista de símbolos.
Aqui está a parte mais poderosa — e mais esquisita — de Lisp.
Este código:
(+ 2 3)
É também uma lista:
(+ 2 3)
Ou seja, o programa tem a mesma forma que os dados.
Isso permite que programas Lisp manipulem outros programas Lisp com muita facilidade.
Essa ideia é chamada de homoiconicidade.
Nome feio, ideia forte:
Em Lisp, código e dados usam a mesma representação básica.
Essa característica torna Lisp excelente para criar:
Em Common Lisp, uma função pode ser definida com defun.
Exemplo:
(defun quadrado (x)
(* x x))
Isso cria uma função chamada quadrado.
Uso:
(quadrado 5)
Resultado:
25
Outro exemplo:
(defun soma (a b)
(+ a b))
Uso:
(soma 10 20)
Resultado:
30
Lisp possui condicionais, como if.
Exemplo:
(if (> 10 5)
"maior"
"menor ou igual")
Resultado:
"maior"
A estrutura é:
(if condição
valor-se-verdadeiro
valor-se-falso)
Exemplo com função:
(defun positivo? (x)
(if (> x 0)
"positivo"
"não positivo"))
Uso:
(positivo? 7)
Resultado:
"positivo"
Lisp é muito associada à programação funcional e à recursão.
Recursão acontece quando uma função chama a si mesma.
Exemplo clássico: fatorial.
Matematicamente:
5! = 5 × 4 × 3 × 2 × 1
Em Lisp:
(defun fatorial (n)
(if (= n 0)
1
(* n (fatorial (- n 1)))))
Uso:
(fatorial 5)
Resultado:
120
Como funciona:
(fatorial 5)
= 5 × (fatorial 4)
= 5 × 4 × (fatorial 3)
= 5 × 4 × 3 × (fatorial 2)
= 5 × 4 × 3 × 2 × (fatorial 1)
= 5 × 4 × 3 × 2 × 1 × (fatorial 0)
= 5 × 4 × 3 × 2 × 1 × 1
= 120
car, cdr e cons¶Três operações clássicas de Lisp:
car¶Pega o primeiro elemento de uma lista.
(car '(10 20 30))
Resultado:
10
cdr¶Pega o restante da lista, sem o primeiro elemento.
(cdr '(10 20 30))
Resultado:
(20 30)
cons¶Constrói uma nova lista colocando um elemento no começo.
(cons 5 '(10 20 30))
Resultado:
(5 10 20 30)
Essas funções são antigas, mas importantes para entender a mentalidade Lisp.
Macros são uma das armas mais fortes de Lisp.
Uma função comum recebe valores.
Uma macro recebe código, transforma esse código e devolve outro código.
Isso permite criar novas formas de expressão dentro da linguagem.
Exemplo conceitual:
(defmacro quando (condição &body corpo)
`(if ,condição
(progn ,@corpo)))
Uso:
(quando (> x 10)
(print "x é maior que 10"))
Isso poderia ser transformado em algo como:
(if (> x 10)
(progn
(print "x é maior que 10")))
A ideia importante:
Macros permitem estender a linguagem usando a própria linguagem.
Isso é muito mais poderoso do que apenas criar funções.
Lisp é famosa pelo uso do REPL.
REPL significa:
Read
Eval
Print
Loop
Ou seja:
Isso permite programar de forma interativa.
Você escreve:
(+ 2 2)
O ambiente responde:
4
Esse modo de trabalho influenciou ambientes modernos de Python, JavaScript, Clojure, Racket e várias outras linguagens.
É um Lisp grande, poderoso e cheio de recursos.
Pontos fortes:
Pontos fracos:
É um Lisp minimalista e elegante.
Pontos fortes:
Pontos fracos:
É um Lisp moderno que roda principalmente na JVM.
Pontos fortes:
Pontos fracos:
É descendente de Scheme e muito usado para ensino, pesquisa e criação de linguagens.
Pontos fortes:
Pontos fracos:
É o Lisp usado para configurar e estender o editor Emacs.
Pontos fortes:
Pontos fracos:
Você provavelmente não deve estudar Lisp achando que vai virar a linguagem principal do seu trabalho amanhã.
Essa expectativa é ruim.
O melhor motivo para estudar Lisp é outro:
Lisp melhora sua cabeça como programador.
Ela força você a entender:
Aprender Lisp pode melhorar sua forma de programar em Python, JavaScript, Ruby, Elixir, Rust ou qualquer outra linguagem.
A verdade brutal:
Lisp é intelectualmente poderosa, mas não é a escolha pragmática padrão para a maioria dos projetos comerciais modernos.
Isso não torna Lisp inútil. Só significa que você deve estudar com o objetivo certo.
Python:
def quadrado(x):
return x * x
Lisp:
(defun quadrado (x)
(* x x))
Python:
if x > 10:
print("maior")
else:
print("menor ou igual")
Lisp:
(if (> x 10)
(print "maior")
(print "menor ou igual"))
Python usa sintaxe mais familiar.
Lisp usa uma sintaxe mais uniforme.
Essa uniformidade é o que torna macros e manipulação de código tão naturais em Lisp.
Escreva uma expressão Lisp que some 10, 20 e 30.
Resposta:
(+ 10 20 30)
Escreva uma expressão que calcule:
(2 + 3) × 4
Resposta:
(* (+ 2 3) 4)
Crie uma função que calcule o dobro de um número.
Resposta:
(defun dobro (x)
(* x 2))
Uso:
(dobro 8)
Resultado:
16
Crie uma função que diga se um número é maior que 100.
Resposta:
(defun maior-que-100? (x)
(if (> x 100)
"sim"
"não"))
Use car para pegar o primeiro item da lista:
'(a b c d)
Resposta:
(car '(a b c d))
Resultado:
a
Estude:
'.Objetivo:
Conseguir ler código Lisp simples sem travar nos parênteses.
Estude:
defun;Objetivo:
Escrever pequenas funções matemáticas e utilitárias.
Estude:
car;cdr;cons;Objetivo:
Entender por que listas são tão centrais em Lisp.
Estude:
Objetivo:
Parar de depender apenas de loops tradicionais.
Estude macros só depois de entender bem funções e listas.
Objetivo:
Entender como Lisp consegue modificar a própria linguagem.
Não tente aprender macros no primeiro dia. É pedir para sofrer à toa.
Algumas opções:
Para começar, a escolha mais amigável costuma ser:
Racket, se o objetivo é aprender.
Common Lisp, se o objetivo é entender Lisp clássico.
Clojure, se o objetivo é usar ideias Lisp em sistemas modernos.
Lisp é uma linguagem de programação, mas também é uma forma diferente de pensar programação.
Ela não venceu o mercado de massa, mas influenciou quase tudo.
Estudar Lisp vale a pena porque ensina ideias profundas:
Resumo final:
Lisp não é a linguagem mais popular.
Lisp não é a mais fácil para arrumar emprego.
Lisp não é a escolha óbvia para projetos comuns.
Mas Lisp é uma das melhores linguagens para expandir sua cabeça como programador.
| Termo | Significado |
|---|---|
| Lisp | Família de linguagens baseada em listas |
| Lista | Estrutura central de dados em Lisp |
| S-expression | Expressão simbólica escrita com parênteses |
| REPL | Ambiente interativo de leitura, execução e resposta |
| Macro | Código que transforma código |
| Homoiconicidade | Código e dados compartilham representação parecida |
car |
Primeiro elemento de uma lista |
cdr |
Resto da lista |
cons |
Cria uma nova lista adicionando um item no começo |
| Common Lisp | Dialeto robusto e clássico |
| Scheme | Dialeto minimalista |
| Clojure | Lisp moderno sobre a JVM |
| Racket | Dialeto educacional e experimental |
Não pule direto para macros.
Esse é o erro clássico de quem quer parecer avançado antes de entender o básico.