Pular para o conteúdo principal

Prefácios de Estrutura e Interpretação de Programas de Computador

Um computador é como um violino. Você pode imaginar um novato experimentando primeiro um fonógrafo e depois um violino. O último, diz ele, parece terrível. Esse é o argumento que ouvimos de nossos humanistas e da maioria de nossos cientistas da computação. Os programas de computador são bons, dizem eles, para fins específicos, mas não são flexíveis. Nem o é um violino, nem uma máquina de escrever, até que você aprenda a usá-lo.

- Marvin Minsky

"A Estrutura e Interpretação de Programas de Computador" é o assunto básico em ciência da computação no Instituto de Tecnologia de Massachusetts. É exigido de todos os alunos do MIT que se especializam em engenharia elétrica ou ciência da computação como um quarto do "currículo básico comum", que também inclui duas disciplinas sobre circuitos e sistemas lineares e uma disciplina sobre design de sistemas digitais. Estamos envolvidos no desenvolvimento deste assunto desde 1978, e temos ensinado este material em sua forma atual desde o outono de 1980 para entre 600 e 700 alunos a cada ano. A maioria desses alunos teve pouco ou nenhum treinamento formal anterior em computação, embora muitos tenham brincado um pouco com computadores e alguns tenham vasta experiência em programação ou design de hardware.

Nosso projeto deste assunto introdutório à ciência da computação reflete duas preocupações principais. Primeiro, queremos estabelecer a ideia de que uma linguagem de computador não é apenas uma maneira de fazer com que um computador execute operações, mas sim um novo meio formal para expressar ideias sobre metodologia. Assim, os programas devem ser escritos para que as pessoas leiam e apenas incidentalmente para que as máquinas os executem. Em segundo lugar, acreditamos que o material essencial a ser abordado por um assunto neste nível não é a sintaxe de construções de linguagem de programação particular, nem algoritmos inteligentes para computar funções particulares de forma eficiente, nem mesmo a análise matemática de algoritmos e os fundamentos da computação, mas sim as técnicas usadas para controlar a complexidade intelectual de grandes sistemas de software.

Nosso objetivo é que os alunos que concluem esta disciplina tenham uma boa noção dos elementos de estilo e estética da programação. Eles devem ter o comando das principais técnicas para controlar a complexidade em um grande sistema. Eles devem ser capazes de ler um programa de 50 páginas, se for escrito em um estilo exemplar. Eles devem saber o que não ler e o que não precisam entender a qualquer momento. Eles devem se sentir seguros para modificar um programa, mantendo o espírito e o estilo do autor original.

Essas habilidades não são exclusivas da programação de computadores. As técnicas que ensinamos e utilizamos são comuns a todos os projetos de engenharia. Controlamos a complexidade construindo abstrações que ocultam detalhes quando apropriado. Nós controlamos a complexidade estabelecendo interfaces convencionais que nos permitem construir sistemas combinando peças padronizadas e bem compreendidas de uma forma de "misturar e combinar". Nós controlamos a complexidade estabelecendo novas linguagens para descrever um design, cada uma das quais enfatiza aspectos particulares do design e não enfatiza outros.

Subjacente à nossa abordagem a este assunto está a nossa convicção de que "ciência da computação" não é uma ciência e que seu significado tem pouco a ver com computadores. A revolução do computador é uma revolução na maneira como pensamos e expressamos o que pensamos. A essência dessa mudança é o surgimento do que poderia ser mais bem chamado de epistemologia procedimental – o estudo da estrutura do conhecimento de um ponto de vista imperativo, em oposição ao ponto de vista mais declarativo adotado por disciplinas matemáticas clássicas. A matemática fornece uma estrutura para lidar precisamente com noções de "o que é". A computação fornece uma estrutura para lidar precisamente com noções de "como fazer".

Ao ensinar nosso material, usamos um dialeto da linguagem de programação Lisp. Nunca ensinamos formalmente o idioma, porque não precisamos. Nós apenas o usamos e os alunos pegam em alguns dias. Esta é uma grande vantagem das linguagens semelhantes ao Lisp: elas têm muito poucas maneiras de formar expressões compostas e quase nenhuma estrutura sintática. Todas as propriedades formais podem ser abordadas em uma hora, como as regras do xadrez. Depois de um curto tempo, esquecemos os detalhes sintáticos da linguagem (porque não há nenhum) e continuamos com os problemas reais – descobrindo o que queremos calcular, como vamos decompor os problemas em partes gerenciáveis ​​e como vamos trabalhar nas partes. Outra vantagem do Lisp é que ele suporta (mas não impõe) mais estratégias em grande escala para decomposição modular de programas do que qualquer outra linguagem que conhecemos. Podemos fazer abstrações procedurais e de dados, podemos usar funções de ordem superior para capturar padrões comuns de uso, podemos modelar o estado local usando atribuição e mutação de dados, podemos vincular partes de um programa a fluxos e avaliação atrasada, e podemos facilmente implementar linguagens incorporadas. Tudo isso está incorporado em um ambiente interativo com excelente suporte para design, construção, teste e depuração de programas incrementais. Agradecemos a todas as gerações de magos Lisp, começando por John McCarthy, que criaram uma ferramenta excelente com poder e elegância sem precedentes.

Scheme, o dialeto de Lisp que usamos, é uma tentativa de reunir o poder e a elegância de Lisp e Algol. Do Lisp, tiramos o poder metalinguístico que deriva da sintaxe simples, a representação uniforme de programas como objetos de dados e os dados alocados em heap coletados pelo lixo. De Algol, pegamos o escopo léxico e a estrutura de blocos, presentes dos pioneiros do projeto de linguagem de programação que estavam no comitê de Algol. Queremos citar John Reynolds e Peter Landin por seus insights sobre a relação do cálculo lambda de Church com a estrutura das linguagens de programação. Também reconhecemos nossa dívida para com os matemáticos que exploraram esse território décadas antes dos computadores aparecerem. Esses pioneiros incluem Alonzo Church, Barkley Rosser, Stephen Kleene e Haskell Curry.

- Harold Abelson e Gerald Jay Sussman