1.1. Os Elementos da Programação
Uma linguagem de programação poderosa é mais do que apenas um meio de instruir um computador a realizar tarefas. A linguagem também serve como uma estrutura dentro da qual organizamos nossas idéias sobre processos. Assim, quando descrevemos uma linguagem, devemos prestar atenção especial aos meios que a linguagem oferece para combinar ideias simples para formar ideias mais complexas. Cada linguagem poderosa tem três mecanismos para fazer isso:
expressões primitivas, que representam as entidades mais simples com as quais a linguagem se preocupa,
meios de combinação, pelos quais os elementos compostos são construídos a partir de outros mais simples, e
meios de abstração, pelos quais elementos compostos podem ser nomeados e manipulados como unidades.
Em programação, lidamos com dois tipos de elementos: procedimentos e dados. (Mais tarde, descobriremos que eles realmente não são tão distintos.) Informalmente, dados são "coisas" que queremos manipular e procedimentos são descrições das regras para manipular os dados. Assim, qualquer linguagem de programação poderosa deve ser capaz de descrever dados primitivos e procedimentos primitivos e deve ter métodos para combinar e abstrair procedimentos e dados.
Neste capítulo, lidaremos apenas com dados numéricos simples para que possamos nos concentrar nas regras para a construção de procedimentos.*4 Nos capítulos posteriores, veremos que essas mesmas regras nos permitem construir procedimentos para manipular dados compostos também.
1.1.1. Expressões
Uma maneira fácil de começar a programar é examinar algumas interações típicas com um interpretador para o dialeto Scheme do Lisp. Imagine que você está sentado em um terminal de computador. Você digita uma expressão e o interpretador responde exibindo o resultado de sua avaliação dessa expressão.
Um tipo de expressão primitiva que você pode digitar é um número. (Mais precisamente, a expressão que você digita consiste nos numerais que representam o número na base 10.) Se você apresentar a Lisp um número:
O interpretador responderá imprimindo: *5
486
As expressões que representam números podem ser combinadas com uma expressão que representa um procedimento primitivo (como + ou *) para formar uma expressão composta que representa a aplicação do procedimento a esses números. Por exemplo:
486 666 495 2 12.7
Expressões como essas, formadas pela delimitação de uma lista de expressões entre parênteses para denotar a aplicação do procedimento, são chamadas de combinações. O elemento mais à esquerda na lista é chamado de operador e os outros elementos são chamados de operandos. O valor de uma combinação é obtido aplicando o procedimento especificado pelo operador aos argumentos que são os valores dos operandos.
A convenção de colocar o operador à esquerda dos operandos é conhecida como notação de prefixo e pode ser um pouco confusa no início porque se afasta significativamente da convenção matemática usual. A notação de prefixo tem várias vantagens, entretanto. Uma delas é que pode acomodar procedimentos que podem receber um número arbitrário de argumentos, como nos exemplos a seguir:
75
ou
1200
Nenhuma ambiguidade pode surgir, porque o operador é sempre o elemento mais à esquerda e toda a combinação é delimitada por parênteses.
Uma segunda vantagem da notação de prefixo é que ela se estende de maneira direta para permitir que as combinações sejam aninhadas, ou seja, ter combinações cujos elementos são eles próprios combinações:
19
Não há limite (em princípio) para a profundidade de tal aninhamento e para a complexidade geral das expressões que o interpretador Lisp pode avaliar. Somos nós, humanos, que ficamos confusos com expressões ainda relativamente simples, como:
57
Podemos nos ajudar escrevendo tal expressão na forma:
57
Mesmo com expressões complexas, o interpretador sempre opera no mesmo ciclo básico: ele lê uma expressão do terminal, avalia a expressão e imprime o resultado. Este modo de operação é frequentemente expresso dizendo-se que o interpretador é executado em um ciclo de leitura-avaliação-impressão. Observe em particular que não é necessário instruir explicitamente o interpretador a imprimir o valor da expressão.*7
1.1.2. Nomenclatura e Ambiente
Last updated
Was this helpful?