• Nenhum resultado encontrado

Structured Programming with go to Statements

N/A
N/A
Protected

Academic year: 2023

Share "Structured Programming with go to Statements"

Copied!
28
0
0

Texto

(1)

Structured Programming with go to Statements

Donald E. Knuth

ACM computing surveys, 6(4), 1974

Grupo 9

Barbara Bellaver ,Virginia Oliveira

bbgonç[email protected], [email protected]

(2)

Apresentação

Duração : 25 minutos (8.30 – 8:55)

Técnica mas não complexa, baseada em trechos de código (ALGOL 60) , expositiva e não impositiva.

Partes :

Background Histórico

Eliminação dos Comandos go to

Introdução dos Comandos go to

Conclusões

Dúvidas

(3)

Background Histórico

Início na década de 60

1966 – D. V. Schorre

Improved organization for procedural languages

1968 - Edsger Dijkstra

Go to statement considered harmful

- convite a fazer bagunça dentro do código

- abolição do go to de todas as linguagens de “alto nível”

- criação de comandos / instruções alternativas

1974 - Donald E. Knuth Donald Knuth

Edsger Dijkstra

(4)

Eliminação dos Comandos go to

Motivação

Evitar o código espagueti !

(5)

Eliminação dos Comandos go to (cont)

Eliminação Sistemática de go to’s

1966 - G. Jacopini e C. Böhm provaram que qualquer

programa dado pode ser sistematicamente transformado em outro programa, o qual computa os mesmos resultados do original, usando apenas as três operações básicas de

composição, condicional e iteração, mais os possíveis

comandos de atribuição e testes sobre as variáveis auxiliares.

Portanto, a princípio, comandos go to, podem sempre ser removidos.

Mas como ?

(6)

Eliminação dos Comandos go to (cont)

Eliminação Sistemática de go to’s

Construção While + if’s + variável auxiliar p

p :=1;

while p>0 do

begin if p=1 then perform step1;

p := successor of step 1 fi;

if p=2 then perform step2;

p := successor of step 2 fi;

if p=n then perform step n;

p := successor of step n fi;

end.

A variável auxiliar p serve como um contador de programa representando em qual caixa do diagrama de fluxo se está, e o programa pára quando p se

torna zero. Todos os go to’s foram eliminados , mas na realidade toda a estrutura do programa foi perdida.

(7)

Eliminação dos Comandos go to (cont)

Eliminação Sistemática de go to’s

A construção original de Jacopini não era meramente a emulação trivial de um fluxograma. Seria possível aproveitar muito da

estrutura de um fluxograma dado se ele fosse razoavelmente bem comportado.

Ashcroft e Manna em 1972 criaram outra técnica para a eliminação de go to’s , tornando possível capturar ainda mais do fluxo natural de um programa. Porém com a nova técnica um programa poderia crescer exponencialmente em tamanho ...

Quando procedimentos de eliminação de go to são aplicados a programas mal estruturados, tem-se como resultado

programas igualmente mal esruturados.

(8)

Eliminação dos Comandos go to (cont)

Eliminação Sistemática de go to’s

Pior erro :

“Programação Estruturada” = Escrever programas da forma como sempre e então eliminar os go to’s.

O que se deseja é que programas sejam concebidos de tal forma que raramente sequer se pense sobre os comandos go to . A linguagem na qual expressamos nossas idéias tem forte

influência sobre nossos processos de pensamento. Por isso Dijkstra salienta a necessidade de novas instruções

(features) em linguagens de programação - estruturas que encorajam o pensamento claro - com o objetivo de evitar a tentação do go to.

(9)

Eliminação dos Comandos go to (cont)

Novas features

A) loop until event1 or … or eventn:

statement list0; repeat;

then event1 = > statement list1;

eventn = > statement listn; fi;

B) begin until event1 or . . . or eventn:

statement list0; end;

then event1 = > statement list1;

eventn = > statement listn; fi:

Novas features

Indicadores de Evento (C.T.Zahn) : Indicadores de evento NÃO são condições que são testadas continuamente. Os comandos

event são simplesmente transferências de controle.

A 1ª. linha só declara os nomes dos indicadores de evento.

(10)

Eliminação dos Comandos go to (cont)

Novas features

Exemplo : Pesquisa e inserção em árvore binária

compare:

if A[i] > x then if L[i] ≠ 0

then i := L[i]; go to compare;

else L[i] := j; go to insert fi;

else if R[i] ≠ 0

then i := R[i]; go to compare;

else R[i] := j; go to insert fi;

fi;

insert: A[j] := x;

L[j] := 0; R[j] := 0; j := j+1;

árvore binária de pesquisa é representada por três vetores : A[i] denota a informação armazenada no nodo número i, e L[i], R[i] são os

números de nodo para as raízes das subárvores esquerda e direita do nodo i.

(11)

Eliminação dos Comandos go to (cont)

Novas features

Exemplo : Pesquisa e inserção em árvore binária

compare:

if A[i] < x then if L[i] ≠ 0

then i := L[i]; go to compare;

else L[i] := j; go to insert fi;

else if R[i] ≠ 0

then i := R[i]; go to compare;

else R[i] := j; go to insert fi;

fi;

insert: A[j] := x;

L[j] := 0; R[j] := 0; j := j+l;

loop until left leaf hit or right leaf hit:

if A[i] > x

then if L[i] ≠ 0 then i := L[i];

else left leaf hit fi;

else if R[i] ≠ 0 then i := R[i];

else right leaf hit fi;

fi;

repeat;

then left leaf hit = > L[i] := j;

right leaf hit = > R[i] := j;

fi;

A[j] := x; L[j] := 0; R[j] := 0; j := j+1;

(12)

Eliminação dos Comandos go to (cont)

Iterações Simples

 Iterações Simples :

Segundo Knuth os tipos de iteração que ele encontra mais freqüentemente em códigos têm a forma

A: S;

if B then go to Z fi;

T; go to A;

Z:

Onde S e T ambos representam longas seqüências de código. Se S é vazio, tem-se um laço while, e se T é vazio tem-se um laço repeat .

Exatamente uma condição sendo testada

(13)

Eliminação dos Comandos go to (cont)

Iterações Simples

Para evitar o uso de go to’s em tais laços pode-se :

1) duplicar o código para S escrevendo

S; while B do begin T; S end;

2) ou descobrir algum tipo de “inversa”para T de tal forma que “T-1;T” é equivalente a um comando nulo e escrever

T-1; repeat T; S until B;

3) ou duplicar o código para B e fazer um teste redundante, escrevendo repeat S; if B then T fi; until B;

 Melhor proposta de sintaxe segundo Knuth (Johan Dalh) : loop: S; while B: T; repeat;

(14)

Introdução dos Comandos go to

A principal razão para introdução de comandos go to é a

eficiência.

(15)

Introdução dos Comandos go to

Eliminação da Recursão

 Eliminação da Recursão

Surge quando se tenta otimizar programas bem estruturados que envolvem recursão explícita ou implícita.

procedure treeprint(t); integer t; value t;

if t ≠ 0

then treeprint (L[t]);

print (A[t]);

treeprint (R[t]);

fi;

(16)

Introdução dos Comandos go to (cont)

Eliminação da Recursão

Traz economias de espaço ou de tempo,

Tende a causar perda da legibilidade do programa.

Compiladores impõem um overhead às chamadas de procedimentos

Se simplificarmos à mão e não com um mecanismo genérico, podemos encontrar simplificações e adquirir um melhor

entendimento do algoritmo.

A regra para simplificação de chamadas de procedimentos é: “Se a última ação do procedimento p antes do seu retorno é chamar o procedimento q, simplesmente go to para o início do

procedimento q.”

(17)

Introdução dos Comandos go to (cont)

Eliminação da Recursão

Como resultado da aplicação da regra o exemplo anterior se torna

procedure treeprint(t); integer t; value t;

L: if t ≠ 0

then treeprint (L[t]);

print (A[t]);

t := (R[t]); go to L;

fi;

(18)

Introdução dos Comandos go to (cont)

Eliminação da Recursão

Do exemplo acima com iterações ao invés de recursão obtemos

procedure treeprint(t); integer t; value t;

begin integer stack S; S := empty;

L1: loop while t ≠ 0;

S < = t; t := L[t]; go to L1;

L2: t < = S;

print (A[t]);

t := (R[t]);

repeat;

if nonempty(S) then go to L2 fi;

end.

Go to em iteração: pecado mortal

Aceitável se bem documentado

(19)

Introdução dos Comandos go to (cont)

Eliminação da Recursão

Situação similar quando se quer provar que um programa está correto.

Para demonstrar Q, prova-se que um programa P mais simples porém menos eficiente é correto e então

prova-se que P pode ser transformado em Q por uma sequência de otimizações válidas.

Com base nisto, o autor propõe uma nova classe de software

o programador desenvolve um programa P bem

documentado e o otimiza para um programa Q que

(20)

Introdução dos Comandos go to (cont)

Sistemas de Manipulação de Programas

Sistemas de Manipulação de Programas

Um compilador para produzir código realmente eficiente necessitaria conhecer as propriedades dos dados.

Linguagem conveniente permite um sistema iterativo de manipulação de programas

Darlington e Burstall

Sistema que remove algumas recursões, faz conversões de estruturas de dados e reestruturação do programa por

combinação de loops similares em uma linguagem como Lisp.

O programador utilizando um sistema destes

Escreve o programa P e interativamente especifica as modificações para torná-lo eficiente.

O sistema fornece informações estatísticas sobre quais partes do programa devem ser otimizadas.

(21)

Introdução dos Comandos go to (cont)

Recursão vs. Iteração

 Recursão vs. Iteração

 É possível re-escrever o exemplo anterior sem a utilização de go to, utilizando apenas

iterações.

 O autor não teve sucesso em encontrar um exemplo de remoção de recursão onde o uso de go to é estritamente necessário.

 Iterativo: até duas vezes mais rápidos do que o

recursivo.

(22)

Introdução dos Comandos go to (cont)

Eliminação de Variáveis Boolenas

 Eliminação de Variáveis Booleanas

Eliminação de variáveis Booleanas por duplicação de código

i := m; j := n;

v := A[ j ]; up := true;

loop:

if up

then if A[ i ] > v

then A[ j ] := A[ i ]; up := false fi;

else if v > A[ j ]

then A[ i ] := A[ j ]; up := true fi;

fi;

if up then i := i + 1 else j := j - 1 fi;

while i < j repeat;

A[ j ] := v;

i := m; j := n;

v := A[ j ];

loop: if A[ i ] > v

then A[ j ] := A[ i ]; go to upf fi;

upt : i := i + 1;

while i < j repeat; go to common;

loop: if v > A[ j ]

then A[ i ] := A[ j ]; go to upt fi;

upf: j := j - 1 while i < j repeat;

common: A[ j ] := v;

Exemplo 2: Mais desorganizado, 25% mais eficiente

(23)

Introdução dos Comandos go to (cont)

Redução da Complicação

Redução da Complicação

Caso de uso do go to para o qual o autor não encontrou um bom substituto.

Ocorre após um programa ter executado um (multiway branch) para um grande número de casos diferentes, porém relacionados.

Exemplo: Emulador microprogramado

Decodifica o endereço e executa a busca do operando na memória, executa um salto baseado no código da operação. As rotinas seriam:

Subtract operand := - operand; go to add;

Add accum := accum + operand;

tyme := tyme + 1;

go to no op;

Jump on Overflow if overflow

then overflow := false; go to jump;

else go to no op;

fi;

(24)

Conclusões

 Há situações em que o uso de go to não é perigoso e é até mesmo desejável.

 Novos tipos de sintaxe provêem bons

substitutos sem encorajar o programador a criar “espaguetes lógicos.”

 Mas o que faz alguns go to’s ruins e outros

aceitáveis? A estrutura do programa.

(25)

Conclusões (cont)

Programação Estruturada

Programação Estruturada

Programação estruturada não é escrever um programa e depois eliminar os seus go to.

Dividir pra conquistar.

Cada nível corresponde à abstração dos detalhes referentes àquele nível.

Composição sequencial, iteração e condicionais apresentam estrutura sintática que os olhos facilmente assimilam, mas um go to não.

Estrutura visual como a dos fluxogramas.

Uma iteração é uma boa abstração se podemos atribuir uma invariante significativa.

Um comando if...then... else..fi, se pudermos estanciar um propósito geral para o comando como um todo.

Precisamos também de dados bem estruturados.

(26)

Conclusões (cont)

Com Comandos go to

Com Comandos go to

O go to pode ser uma abstração desde que se

tenha noção exata do que significa executar o go to para cada label.

É possível escrever programas bem estruturados com go to.

Dificilmente ele é a melhor alternativa uma vez que

estão surgindo novas linguagens.

(27)

Conclusões (cont)

Eficiência

Eficiência

Primeiro criar um programa legível e que funciona,

Depois pensar na sua eficência.

Geralmente só uma fração do código está envolvida e então, nesta parte, é desejável sacrificar a

legibilidade pela eficiência.

(28)

Conclusões (cont)

O Futuro

 O Futuro

Novas linguagens facilitarão o desenvolvimento de programas estruturados.

Pequenos módulos identificados por seus nomes à medida em que são usados para construir módulos maiores.

Sistemas que manipulam programas.

Diferentes níveis de linguagem.

A linguagem final terá go to em seus níveis mais altos?

Aplicando o conceito de abstração, não haverá necessidade do go to.

Ele deveria ser abolido das linguagens de nível mais alto, ao menos para os programadores iniciantes.

Referências

Documentos relacionados

Ao rever todas as análises e discussões que realizamos neste trabalho, embasadas nos preceitos funcionalistas aplicados à tradução e nos paradigmas bakhtinianos,

O romance Usina, diferentemente dos demais do conjunto da obra pertencente ao ciclo-da-cana-de-açúcar, talvez em função do contexto histórico em que se insere, não

- Remover as pastilhas usadas e retornar todo o parafuso de regulagem em seguida montar uma pastilha nova do lado da roda, empurrando com a mão a pinça no sentido do cilindro de

Podem treinar tropas (fornecidas pelo cliente) ou levá-las para combate. Geralmente, organizam-se de forma ad-hoc, que respondem a solicitações de Estados; 2)

Sistemas Computacionais de Sistemas Computacionais de Suporte à Decisão Suporte à Decisão Sistemas Especialistas Lógica Fuzzy Redes Neurais Algoritmos Genéticos Sistemas

ATENÇÃO: se não for utilizado o receptor rádio presente no quadro electrónico, conigurar JR4=OFF e remover o módulo memória BIXMR2.. Memorização

O destaque é dado às palavras que abrem signi- ficados e assim são chaves para conceitos que fluem entre prática poética na obra de arte e sua reflexão em texto científico..