Glossário de EDA Flashcards
Consolidar a terminologia básica da programação e dos algoritmos
abstracção
abstraction
Processo mental que consiste em escolher ou isolar um aspecto determinado de um estado de coisas relativamente complexo, a fim de simplificar a sua avaliação ou classificação, ou para permitir a comunicação do mesmo. [Antônio Houaiss et al., Dicionário Houaiss da Língua Portuguesa, 1.ª reimpressão com alterações, Objetiva, Rio de Janeiro, 2004.] A abstracção é um conceito fundamental em informática. Muitos dos artefactos das linguagens de programação têm como objectivo possibilitar a modularização e o encapsulamento, que são ferramentas essenciais para facilitar a abstracção.
algoritmo
algorithm
- Uma sequência pormenorizada de acções a executar para realizar alguma tarefa [Foldoc]. 2. Uma sequência finita de instruções bem definidas e não ambíguas, cada uma das quais pode ser executada mecanicamente num período de tempo finito e com uma quantidade de esforço finita [Wikipédia]. 3. Um conjunto finito de regras que fornece uma sequência de operações para resolver um tipo específico de problema e que tem as seguintes características: finitude, definitude, entradas, saídas e eficácia [Donald Knuth, The Art of Computer Programming, Volume 1: Fundamental Algorithms, 2.ª edição, Addison-Wesley, Reading, Massachusetts, E.U.A., 1973]. (Nota: Donald Knuth é uma das maiores figuras da ciência da computação.)
ciclo
* controlado por contador
* controlado por guarda
ciclo infinito
* controlado por colecção
loop
count-controlled loop
condition-controlled loop
infinite loop
collection-controlled loop
Um ciclo é uma sequência de instruções que é especificada uma única vez para ser executada várias vezes sucessivamente. O código dentro do ciclo (o seu passo ou a sua acção) é executado um determinado número de vezes (ciclos controlados por contador), uma vez para cada membro de uma colecção de itens (ciclos controlados por colecção), até que uma dada condição (a sua guarda) se verifique (ciclos controlados por guarda) ou indefinidamente (ciclos infinitos). [Wikipédia] Cada ciclo consiste usualmente num conjunto de instruções que o precede, a inicialização, numa guarda implícita ou explícita, que controla a duração do ciclo, sendo avaliada a cada passo do ciclo, e num passo, que é executado repetidamente e que pode normalmente ser decomposto numa acção e num progresso. Em ciclos controlados por contador e em ciclos controlados por colecção é típico que a guarda e o progresso sejam implícitos e que a inicialização se relacione apenas com a acção a realizar, e não com o progresso do ciclo. Usualmente os ciclos têm uma variável de controlo. Esta variável está envolvida no progresso do ciclo.
As instruções iterativas do C (o while
, o do-while
e o for
) suportam directamente apenas ciclos controlados por guarda. No entanto, qualquer tipo de ciclo pode ser escrito à custa dessas instruções (aliás, bastaria apenas uma delas para se poder escrever qualquer tipo de ciclo).
Exemplo de ciclo controlado por guarda em C:
exemplo de ciclo controlado por guarda para calcular numero de dígitos
Exemplo de ciclo controlado por contador em C:
exemplo de ciclo controlado por contador para calcular factorial
Exemplo de ciclo infinito em C:
exemplo de ciclo controlado infinito para obter do utilizador valor cumprindo condição
Exemplo de ciclo controlado por colecção em C:
exemplo de ciclo controlado por colecção para somar os itens de uma lista
código
código fonte
code
source code
O nome genérico código (ou código fonte) aplica-se a qualquer troço de programa escrito numa qualquer linguagem de programação legível por humanos.
expressão
expression
Uma expressão numa linguagem de programação é uma combinação explícita de valores, constantes, operadores e funções que é interpretada de acordo com as regras de precedência e associatividade particulares dessa linguagem, resultando num valor calculado. A este processo, tal como no caso das expressões matemáticas, chama-se cálculo. O valor pode ser de vários tipos, por exemplo, um valor numérico, uma cadeia de caracteres ou um valor booleano. Por exemplo, 2 + 3 é uma expressão cujo valor calculado é 5. Uma variável é também uma expressão, uma vez que denota um valor em memória. Assim, se x for uma variável, então x será também uma expressão, tal como x + 2. Um exemplo de uma expressão relacional é 4 ≠ 4, cujo valor é falso. Uma função, embora isso se considere uma má prática, pode ter efeitos laterais, coisa que também pode acontecer com alguns operadores (e.g., =, += ou ++, no C e nas linguagens dele derivadas). O cálculo do valor de uma expressão pode, por isso, em alguns casos, alterar o estado do programa. [Wikipédia] (Nota: Em Snap!, uma expressão consiste sempre na invocação de um repórter, passando-lhe os respectivos argumentos, que são também eles expressões.)
Exemplo de uma expressão em C:
> factorial(3 + 2) //
uma expressão
fluxo de controlo
control flow
O fluxo de controlo consiste na sequência exacta das instruções que são executadas por um programa. Imagine uma linha a unir as instruções que vão sendo executadas num programa. Quando passar por uma instrução de selecção, a linha seguirá apenas por um dos seus ramos. Quando atinguir um ciclo, a linha dará um determinado número de voltas. Quando uma rotina for invocada, a linha ligar-se-á à primeira instrução dessa rotina. Quando a rotina retornar, a linha retornará ao percurso que estava a percorrer antes da invocação da rotina. Essa linha representa um dado fluxo de controlo. O fluxo de controlo ao longo de um programa é tipicamente diferente consoante as circunstâncias que influenciam a sua execução (respostas do utilizador, conteúdos de ficheiros lidos pelo programa, etc.).
função
function
Um dos tipos de rotina. As funções têm como objectivo calcular e devolver um ou vários valores. As funções não têm, ou não devem ter, efeitos laterais, i.e., não devem agir sobre o mundo que as circunda. Quando as funções não têm efeitos laterais, também se dizem funções puras. Quando as funções devolvem valores booleanos recebem o nome de predicados. Quando as funções devolvem valores booleanos, chamam-se também predicados.
Em C, a palavra «função» é usada no sentido de rotina. Para evitar ambiguidades, sempre que pretendermos referir-nos ao mecanismo do C que suporta a noção de rotina usaremos a expressão «função C».
Exemplo de uma função em C:
int factorial(int n) { if (n == 0) return 1; return n * factorial_of(n - 1); }
Exemplo de um predicado (e por isso também uma função) em C:
int is_odd(int n) { return n % 2 != 0; }
instrução de controlo de fluxo
control flow statement
Uma instrução de controlo de fluxo é um tipo específico de instrução que permite controlar o fluxo de controlo de um programa. As instruções de condicionais, as instruções de selecção e os vários tipos de instruções iterativas são instruções de controlo de fluxo.
Em C existem diversas instruções de controlo de fluxo:
- A instrução condicional:
> if (guarda) instrução
- A instrução de selecção:
> if (guarda) instrução1 else instrução2
- A instrução de comutação:
> switch (expressão) { case valor1: instruções1 break; case valor2: instruções2 break; ... case valorn: instruçõesn break; default: instruções break; }
- O ciclo
while
:
> while (guarda) passo
- O ciclo
do-while
:
> do passo while (guarda);
- O ciclo
for
:
> for (inicialização; guarda; progresso) acção
- As instruções de retorno (
return
), quebra (break
), continuação (continue
) e salto incondicional (goto
, não usar!).
instrução iterativa
instrução de iteração
iteration statement
Uma instrução iterativa é um tipo específico de instrução de controlo de fluxo que permite construir ciclos de uma forma estruturada. Há vários tipos possíveis de instruções iterativas. Por exemplo:
- repete [o passo] [n] vezes
- até que 〈a guarda〉, repete [o passo]
- enquanto 〈a guarda〉, repete [o passo]
- repete [o passo] até que 〈a guarda〉
- repete [o passo] enquanto 〈a guarda〉
- repete [o passo] para sempre
- para (i) de (o início] a (o fim), repete [a acção]
- para cada (o item) em [a lista], repete [a acção]
linguagem
* de programação
language
programming *
Uma linguagem de programação é uma linguagem artificial concebida para comunicar instruções a uma máquina, em particular a um computador. As linguagens de programação podem ser usadas para criar programas que controlam o comportamento de uma máquina e/ou para exprimir algoritmos com precisão. [Wikipédia]
Ver:
parâmetro
parameter
formal argument
passagem de argumentos
argument passing
Acto ou efeito de usar os valores dos argumentos para inicializar os correspondentes parâmetros quando ocorre uma invocação de uma rotina e a sua subsequente execução. A forma mais comum de passar argumentos a uma rotina é a passagem de argumentos por valor.
O Snap! usa passagem de argumentos por valor:
procedimento
procedure
Um dos tipos de rotina. Os procedimentos agem sobre o estado do mundo os rodeia, podendo alterá-lo. O objectivo de um procedimento é tipicamente que essas alterações ocorram. A essas alterações é usual chamar-se efeitos laterais, mesmo quando a sua ocorrência é a razão de ser do procedimento. [c2.com]
Em C, a palavra «função» é usada no sentido de rotina. Para evitar ambiguidades, sempre que pretendermos referir-nos ao mecanismo do C que suporta a noção de rotina usaremos a expressão «função C».
Exemplo de um procedimento em C:
void swap(int a[], int i, int j) { const int original_a_i = a[i]; a[i] = a[j]; a[j] = original_a_i;
}
programa
* de computador
program
computer *
Um programa de computador (ou simplesmente programa ou aplicação) é uma sequência de instruções concebida para desempenhar uma dada tarefa com um computador. Um computador requer um programa para funcionar, executando tipicamente as instruções do programa num processador central. Um programa pode ter uma forma executável, que o computador usa directamente para executar as instruções, e uma forma legível por humanos, a partir da qual a forma executável pode ser obtida por tradução (conhecida por compilação). A forma legível por humanos está tipicamente escrita numa linguagem de programação de alto nível. A forma executável directamente pelo computador está expressa em linguagem máquina. Há linguagens de programação de alto nível concebidas para serem interpretadas. Ou seja, os programas expressos nessas linguagens não se destinam a serem compilados, mas sim a serem interpretados por um outro programa, que os executa. O código fonte de um programa é muitas vezes escrito por programadores. As linguagens de programação podem classificar-se como suportando um ou mais paradigmas de programação, sendo que três dos principais paradigmas são a programação imperativa, a programação funcional e a programação declarativa. [Wikipédia] (Nota: Ao contrário do que é feito na Wikipédia, consideramos que programação declarativa e programação lógica expressam o mesmo conceito e que a programação funcional não é uma forma de programação declarativa. Estas definições não são consensuais. Ver, por exemplo, [Allen B. Tucker e Robert E. Noonan, Programming Languages: Principles and Paradigms, segunda edição, McGraw-Hill, Boston, 2007].)
programação
* de computadores
programming
computer *
A programação de computadores ou simplesmente programação é o processo de concepção, escrita, teste, depuração e manutenção do código fonte de programas de computador. O código fonte é escrito usando uma ou mais linguagens de programação (tais como o Java, o C++, o C#, o Ruby ou o Python). O objectivo da programação é a criação de um conjunto de instruções que são usadas pelos computadores para desempenhar operações específicas ou para apresentarem comportamentos desejados. O processo de escrita de código fonte requer muitas vezes perícia em muitos diferentes assuntos, incluindo conhecimento do domínio de aplicação, de algoritmos especializados e de lógica formal. Até que ponto a escrita de programas é uma forma de arte, um ofício ou uma disciplina da engenharia continua a ser debatido. Em geral, considera-se boa programação uma aplicação equilibrada dessas três práticas com o objectivo de produzir um solução de software eficiente e passível de evolução. [Wikipédia]
programação imperativa
imperative programming
A programação imperativa é o mais antigo dos paradigmas de programação, fundando-se no modelo clássico de computação de «von Neumann-Eckert». Neste modelo, o programa e as suas variáveis são armazenados em conjunto, e o programa contém uma sequência de instruções que efectuam cálculos, atribuem valores a variáveis, lêem entradas, produzem saídas ou direccionam o fluxo do controlo para outro local na sequência de instruções. A abstracção procedimental (na forma de procedimentos, ou melhor, de rotinas) é um elemento essencial da programação procedimental, um dos paradigmas de programação incluído na programação imperativa. As sequências de instruções, as instruções iterativas e as instruções condicionais e de selecção são elementos essenciais da programação estruturada, outro dos paradigmas de programação incluído na programação imperativa. [Allen B. Tucker e Robert E. Noonan, Programming Languages: Principles and Paradigms, segunda edição, McGraw-Hill, Boston, 2007] A programação orientada por objectos também pode ser considerada com um dos paradigmas de programação incluído na programação imperativa, embora o seu modelo assente na visão do programa como uma colecção de objectos que interagem entre si, enviando mensagens (i.e., invocando operações) uns aos outros e agindo de acordo com as mensagens recebidas (executando os métodos correspondentes às operações invocadas), assim alterando possivelmente o seu estado [idem].
Abaixo ilustram-se os três principais paradigmas de programação através de implementações do algoritmo de Euclides para o obtenção do máximo divisor comum de dois números em Prolog, Scheme e Java («gcd» é a abreviatura de «greatest common divisor»).
Prolog (programação lógica):
> gcd(X, 0, X):- !. gcd(0, X, X):- !. gcd(X, Y, D):- X > Y, !, Z is X mod Y, gcd(Y, Z, D). gcd(X, Y, D):- Z is Y mod X, gcd(X, Z, D).
Scheme (programação funcional):
> (define (gcd a b) (if (= b 0) a (gcd b (modulo a b))))
Java (programação imperativa):
> public static int gcd(int a,
` int b) { while (b > 0) { int c = a % b; a = b; b = c; } return a; }`
programação procedimental
procedural programming
A programação procedimental é um paradigma de programação que deriva da programação estruturada, incluindo-a, e assenta no conceito da invocação de procedimentos, ou melhor, de rotinas. As rotinas, também conhecidas por subrotinas (e a que, quando associadas a uma classe ou objecto na programação orientada por objectos, também se chama métodos), contêm simplesmente uma sequência de instruções (incluindo possivelmente instruções de controlo de fluxo) a executar para atingir um objectivo definido, dado um conjunto de parâmetros de entrada. As rotinas podem ser invocadas em qualquer ponto da execução de um programa, inclusivamente dentro de outras rotinas ou mesmo dentro da própria rotina invocada. Algumas linguagens de programação seguindo o paradigma da programação procedimental são o Fortran, o Basic, o C ou o Pascal. [Wikipédia] A programação procedimental enfatiza a abstracção procedimental, que permite ao programador, enquanto cliente de uma rotina, preocupar-se apenas com a interface entre a rotina e o seu resultado computacional, ignorando os pormenores da sua implementação. [Allen B. Tucker e Robert E. Noonan, Programming Languages: Principles and Paradigms, segunda edição, McGraw-Hill, Boston, 2007] Ou seja, a programação procedimental encoraja simultaneamente o encapsulamento, e por isso uma forma simples do princípio da ocultação de informação, e a modularização, no sentido em que as rotinas podem ser consideradas como módulos reutilizáveis a partir dos quais se constrói o programa. (Nota 1: Considera-se uma boa prática da programação procedimental que uma rotina tenha um único objectivo bem definido. Nota 2: A programação orientada por objectos inclui a programação procedimental. Nota 3: A programação por contrato pode em parte ser vista como uma formalização da programação procedimental em que as interfaces das rotinas passam a ter associados contratos estabelecidos entre os seus produtores e os seus clientes.)
rotina
subrotina
routine
subroutine
O nome genérico dado às funções (incluindo os predicados) e aos procedimentos é rotina (ou subrotina). As rotinas são uma das unidades de modularização em programação. Uma rotina abstrai uma acção ou uma computação. Uma rotina expõe uma interface e encapsula uma implementação. A interface consiste no nome da rotina, bem como no número e tipo dos seus argumentos e dos valores que devolve. A sua implementação consiste na declaração dos seus parâmetros, que recebem em cada invocação o valor dos argumentos que são passados à rotina, e no seu corpo, ou seja, na sequência de instruções que realizam a acção pretendida ou que calculam o valor a devolver. As rotinas têm associados contratos, que por vezes não são tornados explícitos. (Nota: A distinção feita aqui entre rotina, procedimento e função não é consensual.)
Em C, a palavra «função» é usada no sentido de rotina. Para evitar ambiguidades, sempre que pretendermos referir-nos ao mecanismo do C que suporta a noção de rotina usaremos a expressão «função C».
Seguem-se alguns exemplos de rotinas em C.
Uma função em C:
int factorial(int n) { if (n == 0) return 1; return n * factorial_of(n - 1); }
Um predicado (e por isso também uma função) em C:
int is_odd(int n) { return n % 2 != 0; }
Um procedimento em C:
void swap(int a[], int i, int j) { const int original_a_i = a[i]; a[i] = a[j]; a[j] = original_a_i;
}
variável
variable
Na programação de computadores, uma variável é uma localização na memória associada a um nome simbólico (um identificador) que contém uma quantidade ou uma informação (um valor) conhecida ou desconhecida. O nome da variável é a forma usual de referenciar o valor armazenado. A separação entre nome e conteúdo permite a utilização do nome de forma independente da informação exacta que representa. O identificador presente no código fonte pode ser associado a um valor durante o tempo de execução, o que significa que o valor da variável pode variar durante a execução do programa. As variáveis em programação podem não corresponder directamente ao conceito de variável em matemática. O valor de uma variável computacional não é necessariamente parte de uma equação ou fórmula, como na matemática. Na computação, uma variável pode ser usada num processo repetitivo: pode-se atribuir-lhe um valor num local, usá-la noutro local, atribuir-lhe depois um novo valor e usá-la outra vez da mesma forma que anteriormente (ver iteração). As variáveis computacionais têm frequentemente nomes longos, de modo a torná-las descritivas daquilo que armazenam. Pelo contrário, as variáveis matemáticas tendem a ter nomes breves, com apenas uma ou duas letras (por um lado, tais nomes tornavam mais rápida a sua manipulação e transcrição; por outro lado, o grau de abstracção das variáveis é usualmente muito maior em matemática do que na programação, pelo que a utilização de nomes mais longos não estaria associada a uma maior facilidade de compreensão pelo leitor, ao contrário do que acontece na programação). [Wikipédia] Há vários tipos de variáveis computacionais: as variáveis globais, em geral desaconselháveis, disponíveis em todos os pontos de um programa, as variáveis de instância (ou variáveis de objecto), que fazem parte do estado privado de um objecto (ou seja, da sua implementação) e que, por vezes, correspondem directamente a atributos desse objecto; as variáveis locais, cujo âmbito se restringe tipicamente a uma rotina; e os parâmetros de rotinas, que funcionam como variáveis locais, embora com a particularidade de serem inicializadas à custa dos valores dos argumentos correspondentes. (Nota: Em Snap! chama-se variáveis de objecto ou, por vezes, variáveis de actor, às variáveis de instância e chama-se variáveis de guião às variáveis locais.)
acção2
action2
A parte do passo de um ciclo na qual se realiza a acção parcial que cada passo do ciclo deve realizar para que o ciclo atinja o seu objectivo uma vez terminado. Usualmente a acção precede o progresso. A acção tem como objectivo principal garantir que o ciclo atinge o seu objectivo assim que termine.
argumento
argument
actual argument
Um argumento é uma expressão usada na invocação de uma rotina e cujo valor é usado para inicializar o parâmetro correspondente. Também se dá o nome argumento ao valor dessa expressão. Diz-se que os argumentos são passados à rotina aquando da sua invocação. (Nota: No Snap! os argumentos são os blocos colocados nas ranhuras ou forquilhas de outros blocos.)
Exemplos de invocações simples em Snap!:
atribuição
assignment
cápsula
capsula
Pode-se usar o termo cápsula para caracterizar um tipo particular de módulo que suporta o encapsulamento, expondo uma interface aos seus clientes e ocultando e restringindo o acesso à sua implementação.
contrato
contract
Compromisso estabelecido entre o produtor de um módulo (tipicamente uma rotina ou bloco) e os seus clientes. Os contratos estabelecem (a) a forma de utilização, (b) as condições a cumprir pelo cliente, ou seja, as pré-condições, e (c) as pós-condições, ou seja, as condições que o produtor garante que serão cumpridas desde que o cliente cumpra a sua parte do contrato.
Por exemplo, um bloco Snap! para o cálculo da raiz quadrada (a) chama-se (√ (x)) e invoca-se colocando o valor, i.e., o argumento, cuja raiz quadrada se pretende obter na única ranhura disponível no bloco, (b) [pré-condição] não pode ser invocado senão com argumentos não negativos e (c) [pós-condição] reporta um valor que, quando multiplicado por si mesmo, está suficientemente próximo do valor do argumento, i.e, tem um erro relativo inferior a 1e-15.
devolução
return (em parte)
Aquilo que acontece quando uma rotina, tipicamente uma função, devolve algo ao retornar.
devolver
to return (em parte)
Indicar um valor a usar como resultado da rotina em execução, tipicamente uma função, quando esta retornar, i.e., quando se abandonar a rotina em execução e se regressar ao ponto do código imediatamente após o local onde a rotina foi invocada para originar a execução corrente. [Wikipédia] Em inglês a palavra return é usada tanto para o retorno como para a devolução, que em português se distinguem. Assim, em português pode-se dizer que «um procedimento não devolve nada ao retornar» e que «uma função tem de devolver um valor apropriado ao retornar». É típico que as linguagens de programação seguindo o paradigma da programação imperativa disponibilizem uma instrução de retorno, na qual, dependendo do contexto, se pode ou não indicar o valor a devolver. Em muitas linguagens o retorno é automático se se atingir o final da sequência de instruções da rotina. Em linguagens como o Ruby, o valor devolvido nessas circunstâncias é o valor da última instrução. Em linguagens como o Pascal, o nome da função corrente pode ser usado como se se tratasse de uma variável cujo valor é devolvido automaticamente ao retornar. (Nota: Em Snap! usa-se o termo reportar com o significado de retornar devolvendo.)
efeito lateral
side effect
Diz-se que uma função ou expressão tem um efeito lateral se, para além de devolver um valor, também modificar o estado do programa ou tiver alguma interacção observável com as rotinas que a invocaram (directa ou indirectamente) ou com o mundo exterior. Por exemplo, uma função pode alterar uma variável global ou uma variável de instância, alterar um dos seus argumentos (no caso da passagem de argumentos por referência), escrever algo num ecrã ou num ficheiro, ler dados, ou invocar outras rotinas com o mesmo tipo de efeito. Na presença de efeitos laterais, o comportamento de um programa depende do seu histórico, i.e., a ordem de execução é relevante. Compreender um programa com efeitos laterais requer conhecimento acerca do contexto e do seu histórico. Um tal programa será, por isso, mais difícil de ler, compreender e depurar. Os efeitos descritos acima como laterais são a forma mais comum de fazer um programa interagir com o mundo que lhe é exterior (pessoas, sistemas de ficheiros, outros computadores em rede, etc.). O grau de utilização destes efeitos depende do paradigma de programação. A programação imperativa usa-os com frequência. A programação funcional usa-os raramente. [Wikipédia] Em programação imperativa considera-se boa prática evitar funções com efeitos laterais (i.e., prefere-se funções puras) e concentrar esse tipo de efeitos em procedimentos. Em programação funcional considera-se boa prática evitar os efeitos laterais.
encapsulamento
encapsulation
No contexto das linguagens de programação, o termo encapsulamento é usado para se referir ao resultado da aplicação de dois mecanismos distintos, embora relacionados, dessas linguagens. Por vezes é também usado para se referir ao resultado da aplicação combinada desses dois mecanismos. O primeiro dos mecanismos restringe a visibilidade e o acesso à representação interna dos objectos. Essa representação só é acessível indirectamente, através de rotinas próprias de cada objecto ou classe (que nesse contexto recebem o nome de métodos ou mesmo de atributos, quando se limitam a devolver ou manipular uma qualidade singular desses objectos). O segundo dos mecanismos permite o agupamento dos dados com as rotinas que operam sobre esses dados. [Wikipédia] Note-se que ambas as acepções são importantes no contexto da programação por contrato. A primeira, porque de outra forma o produtor de uma classe (ou de um objecto protótipo) não poderia dar garantias ao respectivo cliente. A segunda porque só agrupando em objectos os dados e as rotinas que os manipulam se pode falar com propriedade acerca de invariantes dos objectos e de garantias da sua real invariância.
estado
state
Conjunto de todas as variáveis, atributos, instâncias e objectos, bem como dos respectivos valores, associados a um programa, a um objecto ou a um outro artefacto de um programa em execução.
execução
execution
Na ciência da computação, a execução é o processo através do qual um computador leva a cabo as instruções de um programa de computador. As instruções do programa desencadeiam sequências de acções simples na máquina onde a execução decorre. Essas acções produzem efeitos de acordo com a semântica dessas instruções. O verbo «correr» é usado muitas vezes no mesmo sentido que «executar». [Wikipédia]
função pura
pure function
Uma função sem efeitos laterais. Estas funções podem ser modeladas através de funções matemáticas. (Nota: Também se pode dizer que um predicado sem efeitos laterais é um predicado puro. Os predicados puros são também funções puras.)
guarda
guard
implementação
implementation
A parte de uma cápsula que se encontra no seu interior, i.e., o seu mecanismo. O acesso do exterior, a partir do qual a cápsula é normalmente usada, é realizado através da mediação de uma interface. Uma boa interface torna a cápsula simples de usar e compreender, não deixando transparecer pormenores de implementação que são irrelevantes para os programadores que são seus clientes. É desejável que as interfaces sejam estáveis, i.e., que não se obrigue os clientes das cápsulas a se adaptarem frequentemente a alterações na forma de interagir com elas. A implementação de uma cápsula, por outro lado, pode ser alterada de forma mais liberal, desde que a interface e o contrato da cápsula se mantenham.
inicialização2
initialization2
A inicialização de uma variável ou constante é a acção de pela primeira lhe atribuir um valor. Em algumas linguagens de programação a inicialização pode ocorrer em simultâneo com a declaração (ou melhor, definição) da variável, i.e., as acções de criação e inicialização são simultâneas. (Nota: No Scratch e no Snap! as variáveis são sempre definidas e inicializadas em locais diferentes.)
instrução
instrução simples
instrução composta
statement
simple statement
compound statement
Na programação de computadores, uma instrução é o menor dos elementos independentes de uma linguagem de programação imperativa. Um programa escrito numa linguagem deste tipo consiste numa ou mais instruções. As instruções podem ter componentes internos, tais como expressões. Muitas linguagens distinguem entre instruções, contendo apenas código executável, e definições, declarando um identificador. Também é usual distinguir entre instruções simples e instruções compostas, que contêm uma sequência de outras instruções como componente. [Wikipédia] (Nota: No Scratch e Snap! dá-se o nome comando às instruções, que por isso são na prática indistinguíveis das invocações de procedimentos. É essa, de resto, uma das características do Snap! necessárias para que seja possível criar novas instruções iterativas.)
instrução condicional
conditional statement
instrução de devolução
Uma instrução de devolução é uma instrução usada para estabelecer o valor a devolver quando a rotina em execução, tipicamente uma função, retornar. É típico que as instruções de devolução sejam simultaneamente instruções de retorno, mas em linguagens como o Pascal isso não acontece. (Nota: No Snap! o comando ou instrução [reporta [o valor]] é simultaneamente uma instrução de devolução e uma instrução de retorno.)
instrução de retorno
return statement
Uma instrução de retorno é uma instrução de controlo de fluxo, disponibilizada tipicamente por linguagens de programação seguindo o paradigma da programação imperativa, cuja execução leva o fluxo de controlo a retornar da rotina em execução. Em algumas linguagens, como o C, o Java, o C# ou o Ruby, e dependendo do contexto, é possível indicar na instrução de retorno qual o valor a devolver. Nesse caso a instrução de retorno é simultaneamente uma instrução de devolução. (Nota: No Snap! o comando ou instrução [reporta [o valor]] é simultaneamente uma instrução de devolução e uma instrução de retorno.)
instrução de selecção
selection statement
interface
interface
A parte de uma cápsula que medeia entre o seu interior, contendo a implementação ou mecanismo, e o exterior, a partir do qual a cápsula é normalmente usada. Uma boa interface torna a cápsula simples de usar e compreender, não deixando transparecer pormenores de implementação que são irrelevantes para os programadores que são seus clientes. É desejável que as interfaces sejam estáveis, i.e., que não se obrigue os clientes das cápsulas a se adaptarem frequentemente a alterações na forma de interagir com elas.
invocar
chamar
to call
Provocar a execução de uma rotina de modo a usar o valor por ela devolvido, no caso de se tratar de uma função, ou a realizar determinadas acções, no caso de se tratar de um procedimento. Para invocar uma rotina é necessário passar-lhe argumentos (ou seja, expressões) compatíveis com a sua interface. No caso de se usar passagem de argumentos por valor, os valores dos argumentos serão utilizados para inicializar os parâmetros da rotina, que, exceptuando esta forma especial de inicialização, funcionam como variáveis locais da rotina durante a sua execução. No caso da programação orientada por objectos, as rotinas invocadas estão normalmente associadas a um objecto (possivelmente através da sua classe). A esse objecto chama-se receptor, designação que surge da utilização da expressão «enviar uma mensagem a um objecto» como equivalente à expressão «invocar uma operação sobre um objecto». A invocação de uma operação sobre um objecto leva à execução de um método.
módulo
modularização
module
modularization
Na concepção de software, entende-se por modularização o particionamento do software em módulos de modo a facilitar a sua implementação e a sua manutenção. A lógica de particionamento pode assentar nas funções desempenhadas pelos módulos, em critérios de implementação, na quantidade de ligações entre os módulos, etc. Usualmente os módulos são também cápsulas, i.e., expõem uma interface e ocultam uma implementação. [Wikipédia]
objecto2
object2
Na programação orientada por objectos, um objecto é uma cápsula cuja interface consiste numa colecção de atributos, que correspondem ao estado observável do objecto, e numa colecção de operações, que lhe conferem um comportamento observável. A implementação de um objecto consiste essencialmente numa estrutura de dados agregada às rotinas que a processam. Os objectos representam instâncias particulares de determinados conceitos reais ou abstractos. Por exemplo, um objecto representando um ficheiro consiste numa colecção de dados e numa colecção de rotinas para operar sobre esses dados e para ler e escrever no ficheiro real correspondente. Os objectos são usualmente considerados instâncias de uma classe, que pode ser explícita (com representação directa na linguagem de programação) ou implícita (sem essa representação directa). Por exemplo, no mundo real o Fernando Pessoa foi um poeta e um humano. Num programa seguindo o paradigma da programação orientada por objectos, o Fernando Pessoa será provavelmente uma instância da classe dos poetas, que por sua vez será uma subclasse dos humanos. Todos os objectos de uma classe têm os mesmos atributos (embora cada objecto tenha os seus próprios valores para esses atributos) e os mesmos comportamentos, conferidos pelas suas operações. Os objectos são a fundação do paradigma da programação orientada por objectos. As linguagens de programação que assentam neste paradigma de programação suportam sintáctica e semanticamente a manipulação de objectos, incluindo possivelmente um sistema de tipos hierárquico, notações especiais para declarar operações e definir os correspondentes métodos, e mecanismos para ocultar dos clientes os pormenores de implementação de cada objecto. Nas linguagens de programação que não suportam directamente a noção de classe, é comum representar cada classe implicitamente através de uma sua instância com um estatuto especial: o objecto protótipo, a partir do qual todos os restantes objectos dessa classe são criados, usando clonagem. [Wikipédia]
paradigma de programação
programming paradigm
Um paradigma da programação é um estilo fundamental de programação de computadores. Há três paradigmas de programação principais: programação imperativa (incluindo a programação orientada por objectos), programação funcional e programação lógica. Os fundamentos destes três paradigmas são modelos distintos de computação: a máquina de (Alan) Turing, no caso da programação imperativa, o cálculo lambda (de Alonzo Church), no caso da programação funcional, e a lógica de primeira ordem, no caso da programação lógica. [Wikipédia] (Nota 1: Alan Turing e Alonzo Church são duas das maiores figuras da ciência da computação. Nota 2: Ao contrário do que é feito na Wikipédia, consideramos que programação declarativa e programação lógica expressam o mesmo conceito e que a programação funcional não é uma forma de programação declarativa. Estas definições não são consensuais. Ver, por exemplo, [Allen B. Tucker e Robert E. Noonan, Programming Languages: Principles and Paradigms, segunda edição, McGraw-Hill, Boston, 2007].)
Abaixo ilustram-se os três paradigmas de programação através de implementações do algoritmo de Euclides para o obtenção do máximo divisor comum de dois números em Prolog, Scheme e Java.
Prolog (programação lógica):
> gcd(X, 0, X):- !. gcd(0, X, X):- !. gcd(X, Y, D):- X > Y, !, Z is X mod Y, gcd(Y, Z, D). gcd(X, Y, D):- Z is Y mod X, gcd(X, Z, D).
Scheme (programação funcional):
> (define (gcd a b) (if (= b 0) a (gcd b (modulo a b))))
Java (programação imperativa):
> public static int gcd(int a,
` int b) { while (b > 0) { int c = a % b; a = b; b = c; } return a; }`
passagem de argumentos por valor
pass-by-value
call-by-value
A passagem de argumentos por valor é a estratégia de passagem de argumentos a rotinas mais comum, sendo usada em linguagens de programação tão diferentes como o C ou o Scheme. Na passagem de argumentos por valor, a expressão correspondente a cada argumento é calculada e o valor resultante é usado para inicializar o parâmetro correspondente. Se a rotina puder fazer atribuições aos seus parâmetros, isso alterará apenas esses parâmetros, e não os argumentos correspondentes. Note-se que em muitas linguagens, tal como no Java (excepto no caso dos tipos primitivos) ou no próprio Snap!, as variáveis guardam referências para os valores ou objectos que lhes são atribuídos. Nesse caso, a passagem de argumentos por valor corresponde na realidade a uma cópia de referências, pelo que as entidades referenciadas podem ser alteradas, desde que sejam mutáveis. A este tipo de passagem de argumentos pode-se chamar passagem de referências por valor. [Wikipédia]
Passagem de argumentos por valor no Snap!:
passo
step
Chama-se passo ao conjunto de instruções executado repetidamente por um ciclo. É típico o passo consistir na acção seguida pelo progresso do ciclo. No entanto, em alguns tipos de instruções iterativas o progresso é implícito, podendo também ocorrer num local sintaticamente distinto (e.g., no caso da instrução iterativa «for» das linguagens derivadas do C).
predicado
predicate
programação estruturada
structured programming
A programação estruturada é um paradigma de programação que surgiu na sequência de uma carta ao editor das Communications of the ACM enviada por Edsger Dijkstra e intitulada «GoTo Considered Harmful». A programação estruturada enquadra-se na programação imperativa e assenta na ideia de que os programas devem ser concebidos usando apenas três estruturas de controlo básicas: a sequência de instruções, a instrução de controlo de fluxo e a instrução iterativa, nomeadamente o ciclo enquando [guarda] fazer [passo]. Assim, a programação estruturada propõe a rejeição da utilização de qualquer forma de instrução goto (ir para), uma vez que esta é desnecessária e encoraja a escrita de código incompreensível (conhecido como código esparguete). Nos anos 60 do século XX, a principal ferramenta de concepção de programas era o fluxograma, que encorajava também o código esparguete, com uma estrutura entrelaçada em que era difícil discernir estruturas iterativas e condicionais. [Allen B. Tucker e Robert E. Noonan, Programming Languages: Principles and Paradigms, segunda edição, McGraw-Hill, Boston, 2007] (Nota 1: O paradigma da programação estruturada não é alternativo a outros paradigmas importantes da programação imperativa, nem tão pouco complementar: na realidade integra-os. De facto, a programação orientada por objectos, hoje o mais relevante dos paradigmas da programação imperativa, inclui nele as ideias chave da programação procedimental e da programação estruturada, da mesma forma que se pode dizer que a boa programação procedimental inclui as ideias chave da programação estruturada. Nota 2: Edsger Dijkstra é uma das maiores figuras da ciência da computação.)
programação orientada por objectos
object-oriented programming
A programação orientada por/pelos/para/a/aos objectos é um paradigma da programação que assenta no conceito de objecto como cápsula. A interface de cada objecto consiste numa colecção de atributos (ou propriedades), que correspondem ao seu estado observável, e numa colecção de operações, que lhe conferem um comportamento observável. A implementação de cada objecto consiste numa colecção de variáveis de instância (ou variáveis de objecto), que correspondem ao seu estado interno, e numa colecção de métodos, que implementam as operações correspondentes. Operações e métodos podem ser vistos respectivamente como a interface e a implementação de rotinas associadas aos objectos. As operações são invocadas «sobre» um objecto dito o receptor. O termo receptor decorre da utilização da expressão «o objecto A enviou uma mensagem ao objecto B» para descrever o que acontece quando um objecto invoca uma operação de um outro objecto. É típico que os objectos sejam considerados instâncias de uma classe, tendo todos os objectos de uma classe os mesmos atributos (não necessariamente com o mesmo valor, note-se) e as mesmas operações. Em algumas linguagens as classes são representadas explicitamente (e.g., no Java, no C#, no C++, etc.). Noutras, como no Snap!, as classes são representadas implicitamente através de um objecto protótipo. Diz-se que estas linguagens suportam o paradigma da programação baseada em protótipos. Tanto os princípios da programação procedimental como os princípios da programação estruturada se aplicam na programação orientada por objectos, a primeira na forma como as operações e os métodos se organizam, a segunda na forma como os métodos são implementados. Na programação orientada por objectos, as aplicações ou programas são concebidos como uma interacção entre objectos, cada um dos quais responde a mensagens (executa os métodos correspondentes a operações suas invocadas por outros objectos), processa dados (manipula o seu estado, através das suas variáveis de instância) e envia mensagens a outros objectos (invoca operações de outros objectos). Cada objecto pode ser visto como uma «máquina» independente com um papel e uma responsabilidade próprias. [Wikipédia]
progresso
progress
A parte do passo de um ciclo na qual se actualiza as suas variáveis de controlo de modo a, reflectindo a realização da acção, garantirem que o ciclo se aproxima do seu fim. Usualmente o progresso segue-se à acção. O progresso tem como objectivo principal garantir que o ciclo termina em tempo finito.
protótipo2
objecto *
prototype2
* object
Os objectos protótipos são o conceito chave de um tipo especial de programação orientada por objectos chamada programação baseada em protótipos. Neste tipo de programação orientada por objectos o conceito de classe é implícito. A reutilização de comportamento é conseguida através da clonagem de objectos existentes e que têm o papel de protótipos. Este tipo de programação assenta numa característica das linguagens de programação chamada delegação. A primeira linguagem de programação baseada em protótipos foi o Self, desenvolvido por David Ungar e Randall Smith em meados dos anos 80 e usado para investigar na área da concepção de linguagens de programação. A partir dos finais dos anos 90 este tipo de programação ganhou popularidade: uma das linguagens mais usada hoje em dia, o JavaScript, é um bom exemplo. O Snap! é também uma linguagem assente na programação baseada em protótipos. [Wikipédia] (Nota: A palavra «protótipo» deriva do grego πρωτότυπον (prototipon), «forma primitiva», neutro de πρωτότυπος (prototipos), “original, primitivo”, de πρῶτος (protos), “primeiro” e τύπος (tipos), “impressão” [Wikipédia]. O seu significado, primeiro tipo ou primeiro exemplar [Priberam], é semelhante ao de «arquétipo», pelo menos no contexto da ciência da computação, ou seja, modelo ideal, inteligível, do qual se copiou toda a coisa sensível [Priberam].)
recursividade
recursion
A recursividade, na ciência da computação, é uma abordagem à resolução de problemas em que a solução de um problema depende de soluções de instâncias menores do mesmo problema. A abordagem recursiva pode ser aplicada a muitos tipos de problemas, sendo uma das ideias centrais da ciência da computação. «O poder da recursividade assenta evidentemente na possibilidade de definir um conjunto infinito de objectos através de uma afirmação finita. Da mesma forma, um número infinito de computações pode ser descrito por um programa recursivo finito, mesmo que esse programa não contenha repetições explícitas.» [Niklaus Wirth, Algorithms + Data Structures = Programs, Prentice-Hall, 1976, p. 126] A maioria das linguagens de programação suportam a recursividade, permitindo que uma rotina se invoque a si mesma no seu corpo ou implementação. Algumas linguagens de programação suportando o paradigma da programação funcional não possuem qualquer mecanismo para definir ciclos, recorrendo-se apenas à recursividade para executar instruções repetidamente. [Wikipédia]
Exemplo de repórter recursivo em Snap! para calcular o factorial:
retornar
to return (em parte)
Abandonar a rotina em execução e regressar ao ponto do código imediatamente após o local onde a rotina foi invocada para originar a execução corrente. Este ponto é conhecido como o endereço de retorno. Este endereço é guardado, normalmente na pilha de invocações do processo, como resultado da realização da invocação da rotina. Pode ser possível, dependendo da linguagem e do contexto exacto (e.g., se se trata de um procedimento ou de uma função), devolver um valor ao código invocador, que nesse caso pode ser parte de uma expressão. [Wikipédia] Em inglês, a palavra return é usada tanto para o retorno como para a devolução, que em português se distinguem. Assim, em português pode-se dizer que «um procedimento não devolve nada ao retornar» e que «uma função tem de devolver um valor apropriado ao retornar». É típico que as linguagens de programação seguindo o paradigma da programação imperativa disponibilizem uma instrução de retorno, na qual, dependendo do contexto, se pode ou não indicar o valor a devolver. Em muitas linguagens o retorno é automático se se atingir o final da sequência de instruções (ou seja, o final do corpo) da rotina. Em linguagens como o Ruby, o valor devolvido nessas circunstâncias é o valor da última instrução. (Nota: Em Snap! usa-se o termo reportar com o significado de retornar devolvendo.)
software
* de computadores
software
computer *
O software de computadores ou simplesmente software é qualquer colecção de programas de computador e dados relacionados que fornecem as instruções para dizer a um computador o que fazer e como fazê-lo. O termo refere-se a um ou mais programas de computador e dados armazendados no computador. Por outras palavras, software é qualquer conjunto de programas, rotinas, algoritmos e respectiva documentação relacionados com a operação de um sistema de processamento de dados. O software realiza as funções do programa que implementa, quer fornecendo directamente instruções à electrónica digital, quer servindo de entrada a outro software. O termo foi cunhado de modo a contrastar com o termo mais antigo «hardware» (que se aplica a dispositivos físicos). Ao contrário do hardware, o software é intangível (não se lhe pode tocar). [Wikipédia]
tempo de execução
run time
Na ciência da computação, tempo de execução é o período de tempo durante o qual o programa está em execução, em contraste com outras fases do ciclo de vida de um programa, tais como o tempo de compilação, o tempo de ligação, o tempo de carregamento, etc. Um erro em tempo de execução, ou simplesmente erro de execução, é um erro detectado durante ou após a execução de um programa. Um erro em tempo de compilação, ou simplesmente erro de compilação, é um erro detectado pelo compilador antes de o programa alguma vez executar. A verificação de tipos, a alocação de espaço de armazenagem (parcialmente), a geração de código e a optimização são tipicamente realizadas em tempo de compilação, embora possam ser realizadas em tempo de execução, dependendo da linguagem em particular e da sua forma de execução. [Wikipédia] É típico usar-se o adjectivo dinâmico para aquilo que ocorre ou é definido em tempo de execução. (Nota: Nas linguagens de programação interpretadas, por definição, não existe tempo de compilação.)
valor
value
Na ciência da computação, um valor é uma expressão que não é passível de cálculo adicional. Por exemplo, a expressão 1 + 2 não é um valor, uma vez que pode ser reduzida à expressão 3. Esta expressão não é passível de reduções adicionais, sendo por isso um valor. Os membros de um tipo são os valores desse tipo. [Wikipédia]
valor literal
literal
literal value
literal
Na ciência da computação, um literal é uma notação para representar um valor fixo no código fonte. Quase todas as linguagens de programação possuem notações para literais inteiros, de vírgula flutuante, cadeias de caracteres (texto) e booleanos. Algumas têm também notações para elementos de tipos enumerados e para valores compostos tais como listas, registos e objectos. Ao contrário dos valores literais, as variáveis e as constantes são símbolos que podem tomar valores, tendo as constantes a restrição adicional de não poderem sofrer alterações. [Wikipédia]
Alguns dos valores literais em Snap!:
variável global
global variable
Na programação de computadores, uma variável global é uma variável que é acessível a partir de qualquer escopo (excepto quando outra entidade com o mesmo nome se interpuser). Os mecanismos de interacção com variáveis globais são chamados mecanismos do contexto global ou do estado global. O paradigma do contexto global contrasta com o paradigma do contexto local, no qual todas as variáveis são variáveis locais sem memória partilhada. As variáveis globais são geralmente consideradas uma má prática justamente devido à sua não localidade: uma variável global pode potencialmente ser alterada a partir de qualquer local e qualquer parte do programa pode depender dela. Uma variável global tem, por isso, um potencial ilimitado para criar dependências mútuas, o que aumenta a complexidade do programa. [Wikipédia] (Nota: A utilização de constantes globais é, pelo contrário, considerada uma boa prática.)
variável local
local variable
Na programação de computadores, uma variável local é uma variável com um escopo ou âmbito local. Uma variável local é acessível apenas a partir da rotina ou do bloco de instruções (nota: não confundir com os blocos do Snap!) no qual está declarada. Em linguagens de programação com apenas dois níveis de visibilidade, as variáveis locais contrastam com as variáveis globais. Linguagens como o ALGOL e suas derivadas permitem qualquer número de níveis de rotinas aninhadas dentro de outras rotinas, com variáveis privadas, rotinas, constantes e tipos ocultados dentro deles. Na maioria das linguagens, as variáveis locais são variáveis automáticas, criadas directamente na pilha de invocações (call stack). Isso significa que quando uma rotina recursiva se invoca a si mesma, as variáveis locais em cada instância da rotina em execução num dado momento recebem endereços distintos, ou seja, há tantas instâncias (com o mesmo nome) das variáveis locais quantas as instâncias da rotina recursiva em execução. Assim, variáveis com este escopo podem ser declaradas, escritas e lidas sem qualquer risco de efeitos laterais em rotinas fora do bloco no qual estão declaradas. Nas linguagens de programação que usam a semântica de passagem de argumentos por valor, os parâmetros de uma rotina são tratados como variáveis locais dessa rotina, embora com a particularidade de serem inicializados com os valores dos argumentos usados na sua invocação. As variáveis locais são usadas para evitar os problemas de efeitos laterais que podem ocorrer com as variáveis globais. [Wikipédia] (Nota: No Snap! as variáveis locais são conhecidas como variáveis de guião.)
acção1
action1
Influência ou efeito produzido sobre o estado de um programa.
acumulador
accumulator
até que 〈a guarda〉, repete [o passo]
until 〈guard〉, do [step]
Instrução iterativa que implementa a noção de ciclo controlado por guarda. A guarda é inicial, o que significa que o passo do ciclo pode não chegar a ser executado nenhuma vez. A iteração dá-se quando a guarda é falsa. O ciclo termina quando a guarda é verdadeira. (Nota: O Snap! possui um bloco primitivo deste tipo.)