Loading...

O QUE TORNOU LISP DIFERENTE

Original

Dezembro de 2001 (rev. Maio de 2002)

(Este artigo surgiu em resposta a algumas perguntas na lista de discussão LL1. Agora está incorporado em Revenge of the Nerds.)

Quando McCarthy projetou Lisp no final da década de 1950, foi uma ruptura radical em relação às linguagens existentes, a mais importante das quais era Fortran.

Lisp incorporou nove novas ideias:

1. Condicionais. Um condicional é uma construção if-then-else. Nós consideramos isso como algo natural agora. Eles foram inventados por McCarthy no curso do desenvolvimento do Lisp. (Fortran naquela época tinha apenas um goto condicional, baseado de perto na instrução de ramificação no hardware subjacente.) McCarthy, que estava no comitê do Algol, conseguiu inserir condicionais no Algol, de onde se espalharam para a maioria das outras linguagens.

2. Um tipo de função. Em Lisp, funções são objetos de primeira classe

  • são um tipo de dado assim como inteiros, strings, etc, e têm uma representação literal, podem ser armazenadas em variáveis, podem ser passadas como argumentos, e assim por diante.

3. Recursão. A recursão existia como um conceito matemático antes do Lisp, é claro, mas Lisp foi a primeira linguagem de programação a suportá-la. (É discutivelmente implícita ao tornar funções objetos de primeira classe.)

4. Um novo conceito de variáveis. Em Lisp, todas as variáveis são efetivamente ponteiros. Valores são o que têm tipos, não variáveis, e atribuir ou vincular variáveis significa copiar ponteiros, não o que eles apontam.

5. Coleta de lixo.

6. Programas compostos de expressões. Programas Lisp são árvores de expressões, cada uma das quais retorna um valor. (Em alguns Lisps, expressões podem retornar múltiplos valores.) Isso contrasta com Fortran e a maioria das linguagens subsequentes, que distinguem entre expressões e instruções.

Era natural ter essa distinção no Fortran porque (não surpreendentemente em uma linguagem onde o formato de entrada era cartões perfurados) a linguagem era orientada a linhas. Você não podia aninhar instruções. E assim, enquanto você precisava de expressões para que a matemática funcionasse, não havia razão para fazer qualquer outra coisa retornar um valor, porque não poderia haver nada esperando por isso.

Essa limitação desapareceu com a chegada das linguagens estruturadas em blocos, mas por então já era tarde demais. A distinção entre expressões e instruções estava entrincheirada. Ela se espalhou de Fortran para Algol e daí para ambos os seus descendentes.

Quando uma linguagem é composta inteiramente de expressões, você pode compor expressões como quiser. Você pode dizer tanto (usando a sintaxe do Arc)

(if foo (= x 1) (= x 2))

ou

(= x (if foo 1 2))

7. Um tipo de símbolo. Símbolos diferem de strings em que você pode testar a igualdade comparando um ponteiro.

8. Uma notação para código usando árvores de símbolos.

9. A linguagem inteira sempre disponível. Não há real distinção entre tempo de leitura, tempo de compilação e tempo de execução. Você pode compilar ou executar código enquanto lê, ler ou executar código enquanto compila, e ler ou compilar código em tempo de execução.

Executar código em tempo de leitura permite que os usuários reprogramem a sintaxe do Lisp; executar código em tempo de compilação é a base das macros; compilar em tempo de execução é a base do uso do Lisp como uma linguagem de extensão em programas como Emacs; e ler em tempo de execução permite que programas se comuniquem usando s-expressions, uma ideia recentemente reinventada como XML.

Quando o Lisp foi inventado pela primeira vez, todas essas ideias estavam longe da prática de programação comum, que era ditada em grande parte pelo hardware disponível no final da década de 1950.

Com o tempo, a linguagem padrão, incorporada em uma sucessão de linguagens populares, tem evoluído gradualmente em direção ao Lisp. 1-5 agora são amplamente utilizados. 6 está começando a aparecer no mainstream. Python tem uma forma de 7, embora não pareça haver qualquer sintaxe para isso. 8, que (com 9) é o que torna as macros do Lisp possíveis, até agora ainda é exclusivo do Lisp, talvez porque (a) requer esses parênteses, ou algo tão ruim quanto, e (b) se você adicionar aquele último incremento de poder, não poderá mais afirmar que inventou uma nova linguagem, mas apenas que projetou um novo dialeto do Lisp ; -)

Embora útil para programadores atuais, é estranho descrever o Lisp em termos de sua variação em relação aos expedientes aleatórios que outras linguagens adotaram. Isso não foi, provavelmente, como McCarthy pensou sobre isso. Lisp não foi projetado para corrigir os erros do Fortran; surgiu mais como um subproduto de uma tentativa de axiomatizar a computação.