Loading...

PROGRAMAÇÃO DE BAIXO PARA CIMA

Original

Janeiro de 1993

(Este ensaio é da introdução deOn 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. Esse software será difícil de ler, difícil de testar e difícil de depurar.

De acordo com esse princípio, um programa grande deve ser dividido em pedaços, e quanto maior o programa, mais ele deve ser dividido. Como você divide um programa? A abordagem tradicional é chamada de projeto de cima para baixo: você diz "o objetivo do programa é fazer essas sete coisas, então eu o divido em sete subrotinas principais. A primeira subrotina tem que fazer essas quatro coisas, então ela terá quatro subrotinas próprias", e assim por diante. Esse 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 experientes de Lisp dividem seus programas de maneira diferente. Além do projeto de cima para baixo, eles seguem um princípio que poderia ser chamado de projeto de baixo para cima - mudando a linguagem para se adequar ao problema. Em Lisp, você não apenas escreve seu programa em direção à linguagem, você também constrói a linguagem em direção ao seu programa. Enquanto você está escrevendo um programa, você pode pensar "Eu gostaria que o Lisp tivesse tal e tal operador". Então você vai e o escreve. Depois você percebe que usar o novo operador simplificaria o projeto 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 é desenhado e redesenhado, até que eventualmente se estabeleça nas montanhas e rios, as fronteiras naturais de seu problema. No final, seu programa parecerá que a linguagem tivesse sido projetada para ele. E quando a linguagem e o programa se encaixam bem, você acaba com um código que é claro, pequeno e eficiente.

Vale a pena enfatizar que o projeto de baixo para cima não significa apenas escrever o mesmo programa em uma ordem diferente. Quando você trabalha de baixo para cima, geralmente acaba com um programa diferente. Em vez de um único programa monolítico, você terá 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 contabilidade, o que sobra é muito mais curto; quanto mais você construir 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 projeto 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. Assim como os designers industriais se esforçam para reduzir o número de peças móveis em uma máquina, os programadores experientes de Lisp usam o projeto de baixo para cima para reduzir o tamanho e a complexidade de seus programas.

O projeto 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 subsequentes. Uma vez que você adquiriu 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 o Lisp bruto.

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

Uma instância desse tipo de abstração pede ao leitor que entenda um operador de uso geral; uma instância de abstração funcional pede ao leitor que entenda uma subrotina de uso específico. [1]

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

Design bottom-up é possível em certo grau em linguagens diferentes do Lisp. Sempre que você vê funções de biblioteca, design bottom-up está acontecendo. No entanto, o Lisp lhe dá muito mais poderes neste departamento, e aumentar a linguagem desempenha um papel proporcionalmente maior no estilo Lisp - tanto que o Lisp não é apenas uma linguagem diferente, mas uma maneira completamente 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 dos programadores individuais diminui. A experiência da programação em Lisp sugere uma maneira mais animadora de formular essa lei: à medida que o tamanho do grupo diminui, a produtividade dos programadores individuais aumenta. Um pequeno grupo ganha, relativamente falando, simplesmente porque é menor. Quando um pequeno grupo também aproveita as técnicas que o Lisp torna possíveis, ele pode vencer de fato.

Novidade: Baixe On Lisp de Graça.

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