Loading...

PROGRAMAÇÃO DE BAIXO PARA CIMA

Original

Janeiro de 1993

(Este ensaio é da introdução aOn Lisp.)

É um princípio de longa data do estilo de programação que os elementos funcionais de um programa não devem ser muito grandes. Se algum componente de um programa crescer além do estágio em que é facilmente compreensível, ele se torna uma massa de complexidade que oculta erros tão facilmente quanto uma grande cidade oculta fugitivos. Tal software será difícil de ler, difícil de testar e difícil de depurar.

De acordo com este princípio, um programa grande deve ser dividido em partes, e quanto maior o programa, mais ele deve ser dividido. Como você divide um programa? A abordagem tradicional é chamada de design de cima para baixo: você diz "o propósito do programa é fazer essas sete coisas, então eu o divido em sete sub-rotinas principais. A primeira sub-rotina tem que fazer essas quatro coisas, então ela por sua vez terá quatro de suas próprias sub-rotinas", e assim por diante. Este processo continua até que todo o programa tenha o nível certo de granularidade - cada parte grande o suficiente para fazer algo substancial, mas pequena o suficiente para ser entendida como uma única unidade.

Programadores Lisp experientes dividem seus programas de forma diferente. Além do design de cima para baixo, eles seguem um princípio que poderia ser chamado de design de baixo para cima - mudando a linguagem para se adequar ao problema. Em Lisp, você não apenas escreve seu programa para baixo em direção à linguagem, mas também constrói a linguagem para cima em direção ao seu programa. Ao escrever um programa, você pode pensar "Eu gostaria que Lisp tivesse tal e tal operador". Então você vai e escreve. Depois, você percebe que usar o novo operador simplificaria o design de outra parte do programa, e assim por diante. Linguagem e programa evoluem juntos. Como a fronteira entre dois estados em guerra, o limite entre linguagem e programa é traçado e retraçado, até que finalmente se estabeleça ao longo das montanhas e rios, as fronteiras naturais do seu problema. No final, seu programa parecerá que a linguagem foi projetada para ele. E quando linguagem e programa se encaixam bem, você acaba com código que é claro, pequeno e eficiente.

Vale a pena enfatizar que o design de baixo para cima não significa apenas escrever o mesmo programa em uma ordem diferente. Quando você trabalha de baixo para cima, você geralmente termina com um programa diferente. Em vez de um único programa monolítico, você obterá uma linguagem maior com operadores mais abstratos, e um programa menor escrito nela. Em vez de uma viga, você terá um arco.

No código típico, uma vez que você abstrai as partes que são apenas escrituração, o que resta é muito mais curto; quanto mais alto você constrói a linguagem, menos distância você terá que percorrer de cima para baixo até ela. Isso traz várias vantagens:

Ao fazer a linguagem fazer mais do trabalho, o design de baixo para cima gera programas que são menores e mais ágeis. Um programa mais curto não precisa ser dividido em tantos componentes, e menos componentes significa programas que são mais fáceis de ler ou modificar. Menos componentes também significa menos conexões entre componentes, e portanto menos chance de erros lá. Como os designers industriais se esforçam para reduzir o número de peças móveis em uma máquina, programadores Lisp experientes usam o design de baixo para cima para reduzir o tamanho e a complexidade de seus programas.

O design de baixo para cima promove a reutilização de código. Quando você escreve dois ou mais programas, muitos dos utilitários que você escreveu para o primeiro programa também serão úteis nos seguintes. Uma vez que você tenha adquirido um grande substrato de utilitários, escrever um novo programa pode levar apenas uma fração do esforço que seria necessário se você tivesse que começar com Lisp bruto.

O design de baixo para cima torna os programas mais fáceis de ler.

Um exemplo deste tipo de abstração pede ao leitor que compreenda um operador de uso geral; um exemplo de abstração funcional pede ao leitor que compreenda uma sub-rotina de uso especial. [1]

Porque faz com que você esteja sempre atento a padrões em seu código, trabalhar de baixo para cima ajuda a esclarecer suas ideias sobre o design do seu programa. Se dois componentes distantes de um programa forem semelhantes na forma, você será levado a notar a semelhança e talvez a redesenhar o programa de uma forma mais simples.

O design de baixo para cima é possível em certa medida em linguagens diferentes de Lisp. Sempre que você vê funções de biblioteca, o design de baixo para cima está acontecendo. No entanto, Lisp lhe dá muito mais amplos poderes neste departamento, e aumentar a linguagem desempenha um papel proporcionalmente maior no estilo Lisp - tanto que Lisp não é apenas uma linguagem diferente, mas uma maneira totalmente diferente de programar.

É verdade que este estilo de desenvolvimento é mais adequado para programas que podem ser escritos por pequenos grupos. No entanto, ao mesmo tempo, ele estende os limites do que pode ser feito por um pequeno grupo. Em The Mythical Man-Month, Frederick Brooks propôs que a produtividade de um grupo de programadores não cresce linearmente com seu tamanho. À medida que o tamanho do grupo aumenta, a produtividade de programadores individuais diminui. A experiência da programação Lisp sugere uma maneira mais alegre de expressar esta lei: à medida que o tamanho do grupo diminui, o produtividade de programadores individuais aumenta. Um pequeno grupo vence, relativamente falando, simplesmente porque é menor. Quando um pequeno grupo também tira vantagem do técnicas que Lisp torna possíveis, ele pode vencer completamente.

Novo: Baixe On Lisp gratuitamente.

[1] "Mas ninguém pode ler o programa sem entender todos os seus novos utilitários." Para ver por que tais afirmações são geralmente erradas, veja a Seção 4.8.