Jump to content
Zex

Break - debate sobre o seu uso em Pascal

Recommended Posts

Zex

O presente tópico vem do seguimento deste post. thoga31


Acho que um moderador não deveria cometer a heresia de colocar break num programa de Pascal.

Se os vossos professores ensinam isso, então seria melhor eles ensinarem java.

Edited by thoga31
Tópico dividido

Share this post


Link to post
Share on other sites
nunopicado

Acho que um moderador não deveria cometer a heresia de colocar break num programa de Pascal.

Se os vossos professores ensinam isso, então seria melhor eles ensinarem java.

Eu gosto do break...

O problema não é o comando em si, mas sim o que se faz com ele.


"A humanidade está a perder os seus génios... Aristóteles morreu, Newton já lá está, Einstein finou-se, e eu hoje não me estou a sentir bem!"

> Não esclareço dúvidas por PM: Indica a tua dúvida no quadro correcto do forum.

Share this post


Link to post
Share on other sites
thoga31

Acho que um moderador não deveria cometer a heresia de colocar break num programa de Pascal.

Se os vossos professores ensinam isso, então seria melhor eles ensinarem java.

Qual é o problema com o break? E o que tem a ver o facto de ser Moderador ou não?


Knowledge is free!

Share this post


Link to post
Share on other sites
Zex

Qual é o problema com o break? E o que tem a ver o facto de ser Moderador ou não?

Tem a ver com boas práticas de programação.

Talvez já ninguém se lembre mas a filosofia do Pascal diz que cada zona de código deve terminar a execução num "end" ou fim de ciclo.

O break provoca o fim de execução numa parte indeterminada...

Assim, só deve ser usado para casos inesperados que não deveriam ocorrer numa execução ideal.

Os professores deviam ensinar isso. E, aqui, os moderadores fazem o papel de professores.

Share this post


Link to post
Share on other sites
thoga31

Tem a ver com boas práticas de programação.

Talvez já ninguém se lembre mas a filosofia do Pascal diz que cada zona de código deve terminar a execução num "end" ou fim de ciclo.

O break provoca o fim de execução numa parte indeterminada...

Assim, só deve ser usado para casos inesperados que não deveriam ocorrer numa execução ideal.

Ou em situações em que devemos terminar o ciclo naquele ponto devido àquela condição e não deixar executar até ao fim. Evita situações clássicas como a repetição de uma instrução antes e dentro do ciclo relacionado com input. Fora o resto.

A filosofia é teoria, a prática é a realidade das coisas. Não vejo ali um mau uso do break.

Além disso, estás a assumir que fomos ou estamos a ser ensinados numa escola ou universidade. Então digo-te: se estás a ser ensinado numa escola/universidade e o teu professor deu tanta filosofia, um conselho para ele: desça à Terra e deixe de fazer programas-exemplo, e experimente fazer programas "a sério". Quereria ver onde parava a "filosofia".

E, aqui, os moderadores fazem o papel de professores.

Ah sim? Porquê?

Edited by thoga31
  • Vote 2

Knowledge is free!

Share this post


Link to post
Share on other sites
Warrior

A utilização de breaks e continues por si só não representa qualquer má prática, as más prática advêm sempre do modo como são utilizados.

Pode-se fazer um exercício muito simples: seriam igualmente contra a cópia do código de input para uma nova função e a utilização de algo como "return -1;" em vez de "break"? O break é muito mais legível e só por fundamentalismo podemos defender o segundo em vez do primeiro.

  • Vote 2

Share this post


Link to post
Share on other sites
Zex

legibilidade (e performance!) do código.

O break torna o programa mais eficiente - mas não é programação estruturada...

Share this post


Link to post
Share on other sites
Kline777

Quanto a nao ser tecnicamente programação estruturada até podes ter razão.... mas isto não é nenhum artigo cientifico, é natural que as sugestões dadas sejam mais vocacionadas para a aplicação prática da linguagem do que para a teorica ou de aprendizagem.

Edited by Kline777

Share this post


Link to post
Share on other sites
passarito

Boas e más práticas de programação tem muito que se lhe diga...

Não sou fundamentalista ao ponto de criticar alguém por usar o Break, no entanto na minha forma de programar tento evitá-lo ao máximo.

Mas isto tem tudo haver da forma como eu QUERO programar e não posso impigir a minha forma de programar a outro.

  • Vote 1

Share this post


Link to post
Share on other sites
thoga31

A meu ver o Break e o Continue podem coexistir em plenitude com a programação estruturada desde que se faça um uso pensado e consciente.

Portanto, IMO, o problema não é usar a ferramenta - é a forma como uso a ferramenta. As facas são perigosas, mas eu uso-as para cortar cebola e descascar fruta, há outros que usam para esfaquear e matar.

Da mesma forma, há quem use o Break e o Continue com contra-peso e medida e há quem use e abuse deles em "situações what the hell".

Entre ver aquele Break e ver uma repetição do código de input, prefiro mil vezes ver o Break.

Eu apoiaria a crítica caso fosse utilizada uma estupidez que certas pessoas continuam a utilizar:

repeat
  if n < 0 then goto wth;
  // ...
until ({...});

wth:
// continua...

Isto sim é desestruturação completa. O Break não tem muito sítio para onde ir: vai ao final do ciclo. A label "wth" pode estar em qualquer lado, é onde me der na "real gana".


Knowledge is free!

Share this post


Link to post
Share on other sites
pwseo

Zex,

O break faz parte do paradigma da programação estruturada, é uma das instruções de saída precoce, muito usadas como forma de assegurar pré-condições em funções/procedimentos e, neste caso, em ciclos. O que podes argumentar é que a sua utilização vai contra o princípio dos single exit points, mas isso é apenas um princípio e não uma imposição do paradigma. Mais ainda, se há quem escreva código potencialmente perigoso/mal estruturado com recurso a break e continue então há uma grande probabilidade de que essa pessoa pura e simplesmente não saiba escrever código estruturado, independentemente das "boas práticas" que lhe forem ensinadas. Além disso, os paradigmas são entidades dinâmicas, mudam com o tempo à medida que vamos descobrindo as suas falhas (e elas existem!).

Falando agora um pouco de programação estruturada, será que encaixam nesse paradigma os programas que os ditos professores ensinam a fazer que são enfiados no bloco principal begin .. end sem qualquer fragmentação? Será que também são bem estruturados os programas que sem mais nem porquê recorrem a variáveis globais ou de outra forma todo o tipo de side-effects em vez de serem escritos de uma forma isolada e reutilizável? Parece-me redundante discutirmos aqui a utilidade dos professores ensinarem ou não a utilizar break quando tudo o que o paradigma estruturado tem de fundamental fica mal ensinado.

EDIT: E com isto pedia que parássemos com o off-topic nesta thread. De facto, eu próprio ajudei a ele, mas apercebi-me agora que estamos a fugir ao tópico original.

Edited by pwseo
reparo sobre o âmbito do tópico
  • Vote 1

Share this post


Link to post
Share on other sites
thoga31

Já estava a dividir o tópico, mas fui a tempo de incluir a nova resposta :D

Tópico dividido, pode-se debater este assunto à vontade.


Knowledge is free!

Share this post


Link to post
Share on other sites
Rui Carlos

Pode-se fazer um exercício muito simples: seriam igualmente contra a cópia do código de input para uma nova função e a utilização de algo como "return -1;" em vez de "break"? O break é muito mais legível e só por fundamentalismo podemos defender o segundo em vez do primeiro.

Eu acho qualquer uma das formas pouco recomendável (embora use qualquer uma das formas por vezes :) ).

Eu apoiaria a crítica caso fosse utilizada uma estupidez que certas pessoas continuam a utilizar:

repeat
  if n < 0 then goto wth;
  // ...
until ({...});

wth:
// continua...

Isto sim é desestruturação completa. O Break não tem muito sítio para onde ir: vai ao final do ciclo. A label "wth" pode estar em qualquer lado, é onde me der na "real gana".

O problema não é tu não saberes para onde vais quando tens um break, o problema é não saberes à partida que tens um break no meio do ciclo, o que te impede de saberes a verdadeira condição de paragem do ciclo sem leres o código todo.

No caso em discussão, o facto do break estar próximo do início do ciclo, ajuda à legibilidade. Já agora, também não acho grande piada à utilização de true/false como condição de paragem de um ciclo...

Share this post


Link to post
Share on other sites
pwseo
Já agora, também não acho grande piada à utilização de true/false como condição de paragem de um ciclo...

Nem eu :\ Gostava que houvesse um forever algures na linguagem.

Share this post


Link to post
Share on other sites
thoga31

O problema não é tu não saberes para onde vais quando tens um break, o problema é não saberes à partida que tens um break no meio do ciclo, o que te impede de saberes a verdadeira condição de paragem do ciclo sem leres o código todo.

No caso em discussão, o facto do break estar próximo do início do ciclo, ajuda à legibilidade. Já agora, também não acho grande piada à utilização de true/false como condição de paragem de um ciclo...

Eu cá uso comentários :D

Pessoalmente habituei-me a meter no início dos ciclos sem condição uns comentários que indicam as condições de paragem e as descrevem brevemente. Por exemplo (um exemplo muito simples, nunca faria isto na realidade):

while true do begin
  (* Condições de paragem:
   * #1 break -> (a < 1) -> número >=0 indica fim do input
   * #2 continue -> (a > 100) -> limite válido = [1..100], ignorar input *)
  readln(a);
  if a<1 then break;
  if a>100 then continue;
  // adicionar algures o número, ou whatever...
end;

(Também não gosto de ver o True/False ali...)

Nem eu :\ Gostava que houvesse um forever algures na linguagem.

Ai o Haskell :D

Mais "simples" (na medida em que fica mais dentro da sintaxe do Pascal) seria algo como isto:

do begin
  // código
end;

Simples e eficaz, parece-me. Não estou a ver a priori como farias um forever no contexto da sintaxe típica do Pascal. :)


Knowledge is free!

Share this post


Link to post
Share on other sites
Zex

Quem sabe o que está a fazer, pode fazer de qualquer maneira.

Mas, eu referia-me a uma pergunta dum programador principiante.

O post original dizia:

"Sou estudante e estou começando a estudar Pascal, e preciso de ajuda com meu código. Preciso que ele finalize caso eu digite um número negativo."

1 - Trata-se evidentemente de alguém que sabe muito pouco e que provavelmente não vai querer saber muito. Por isso, aconselho a usar apenas comandos básicos para não confundir o estudante.

2 - Aconselho a usar apenas linguagem estruturada simples porque a maior parte dos estudantes percebe melhor assim. E, provavelmente não aprenderam nas aulas comandos como "break" e "goto". Mesmo comandos úteis como "with" podem confundir o principiante.

3 - Aconselho a fazer o mínimo de alterações no programa do aluno.

Neste caso, bastaria alterar "while num>=0 do" para "while num>0 do".

4 - Para um programa que vai ser executado 2 ou 3 vezes a legibilidade tem muito mais importância que a eficiência. Por isso, é inútil optimizar a velocidade à custa da legibilidade. Também é aconselhável que cada função não tenha mais de um ecran de tamanho para se poder ler tudo de uma vez.

Lembrem-se: estamos a responder a um principiante amedrontado e não a um programador que quer saber tudo sobre programação.

Edited by Zex
  • Vote 1

Share this post


Link to post
Share on other sites
thoga31

5 - Se o principiante não começar a ver entretanto algumas coisas úteis e porreiras do Pascal, ficará a pensar para sempre que o Pascal é fraco.

6 - Se não mostrarmos ao principiante tais coisas úteis, explicando devidamente e esclarecendo sempre as suas dúvidas, estaremos sempre a renegá-lo ao seu estatuto de principiante e a colocarmo-nos num patamar superior, o que eu sinceramente abomino.

7 - Não há mal nenhum em mostrar as coisas que o Pascal tem.

1 - Trata-se evidentemente de alguém que sabe muito pouco e que provavelmente não vai querer saber muito. Por isso, aconselho a usar apenas comandos básicos para não confundir o estudante.

Estou para saber como deduziste isso. Quando eu comecei também perguntava coisas do género, e não me fiquei pelos básicos.

3 - Aconselho a fazer o mínimo de alterações no programa do aluno.

Neste caso, bastaria alterar "while num>=0 do" para "while num>0 do".

Se o código do aluno está demasiado extenso, demasiado complexo ou demasiado confuso, é nossa obrigação (no mínimo moral) de mostrar que há formas mais elegantes de se atingir o objectivo, e por último ensinar métodos mais eficientes.

4 - Para um programa que vai ser executado 2 ou 3 vezes a legibilidade tem muito mais importância que a eficiência. Por exemplo, cada função não deve ter mais de um ecran de tamanho para se poder ler tudo de uma vez.

Se a eficiência não é ensinada logo de raiz, quando será ensinada? Uma criança que aprenda a falar mal logo desde o início dificilmente irá acertar o seu discurso na vida adulta, será sempre um trambolho a falar.

Moral da história: o nosso papel é ajudar, ensinar e mostrar novos horizontes, não é meter um paninho bonito à frente deles a tapar tais horizontes e dizer "muito bem", é à conta disso que temos alunos de programação, e no final programadores, miseráveis nas escolas e universidades deste e doutros países. E, neste caso em concreto, o Pascal sofre particularmente pois nunca ninguém tem os dito-cujos para mostrar as potencialidades da linguagem, preferindo manter em mente "ah e tal, vamos manter as coisas simples para não confundir".

Última nota: foi com as "confusões" que me deram aqui no P@P que aprendi muito - vi mais do que aquilo que pensei que existia. Hoje em dia faço o mesmo, e com orgulho.

Edited by thoga31

Knowledge is free!

Share this post


Link to post
Share on other sites
Flinger

Concordo com o Zex até certo ponto, e é muito fácil de explicar o porquê. No início do ensino de programação o ponto mais importante é os alunos aprenderem a lógica, e não a eficiência. Dominar ciclos e condições, todo o fluxo de controlo de uma aplicação, e, para mim, só se devem preocupar com a eficiência apartir do momento em que já dominam o resto.

Aliás, é algo que vem naturalmente.

Se ensinassem esses truques logo de início, aposto que o código de 90% dos estudantes não passava de goto's e breaks, com uns if's à mistura.

Claro que, com o domínio da programação vêm as optimizações e aprender maneiras mais eficientes de fazer o mesmo, mas para isso é preciso dominar as várias formas de resolver um problema. Hoje em dia uso diversas vezes código semelhante ao que o pwseo colocou no post original, por várias razões, incluindo facilidade, rapidez e legibilidade. Um aparte, o facto de ele ser moderador não creio que tenha importância para o assunto.

Se a eficiência não é ensinada logo de raiz, quando será ensinada? Uma criança que aprenda a falar mal logo desde o início dificilmente irá acertar o seu discurso na vida adulta, será sempre um trambolho a falar.

Não é bem assim thoga... Tenta-te lá lembrar de quando te ensinaram a escrever... será que foi: o papá tem um pópó ou o meu progenitor tem um automóvel?

Edited by Flinger

Share this post


Link to post
Share on other sites
thoga31

Fazer um edit ao post após este ter recebido resposta pode gerar alguma confusão.

Lembrem-se: estamos a responder a um principiante amedrontado e não a um programador que quer saber tudo sobre programação.

Amedrontado? Que estávamos a responder a um principiante, sim. Agora que estava amedrontado, não podemos inferir tal coisa. A não ser que infiras que todo e qualquer principiante é amedrontado.

Só queria acrescentar uma coisa que me tinha esquecido. Este é o código a partir do qual tal debate surgiu:

program NumPrimos(input{teclado}, output{video});

function primo(x{e}: integer): boolean;
  var
     i: integer;
  begin
    i:= 2;
    while (i<x) and ((x mod i)<>0) do
       i:= i+1;
    primo:= (i=x);
  end;
var
  num, qtd,  soma, maior, menor, maiorPrimo, menorPrimo: integer;
begin
    write(output, 'Digite um n£mero: ');
    readln(input, num);
    if num<0 then writeln('Nenhum numero lido foi maior que zero')
    else
       begin
          qtd:= 0;
          maior:= num;
          menor:= num;
          maiorPrimo:= -1;
          soma:= 0;
          while num>=0 do
             begin
                inc(qtd);
                soma:= soma + num;
                if num>maior then maior:= num
                else
                   if num<menor then menor:= num;
                if primo(num) then
                   if maiorPrimo = -1 then
                      begin
                         maiorPrimo:= num;
                         menorPrimo:= num;
                      end
                   else
                      if num<menorPrimo then menorPrimo:= num
                      else
                         if num>maiorPrimo then maiorPrimo:= num;
                write(output, 'Digite um numero: ');
                readln(input, num);
             end;
          writeln(output, 'O maior numero = ', maior, ' e o menor numero = ', menor);
          writeln(output, 'A media de todos os numeros lidos = ', soma/qtd:5:2);
          if maiorPrimo=-1 then
             writeln(output, 'Nenhum numero primo foi lido')
          else
             writeln(output, 'Maior primo = ', maiorPrimo, ' e o menor primo = ', menorPrimo);
       end;
    readln(input);
end.

E isto foi o que disseste:

Também é aconselhável que cada função não tenha mais de um ecran de tamanho para se poder ler tudo de uma vez.

Primeiro, uma função não tem de ter só um "ecrã", além de que é uma definição vaga. E, no presente caso, a dita função tinha bem mais que um ecrã, e a legibilidade era terrível.

Em suma, acho que até estávamos a indicar um caminho que levava a mais legibilidade e a uma função mais pequena, e que, por coincidência, levava a mais eficiência.

A questão era o uso do break, e agora já estamos a falar de batatas. @Zex, se não queres ver o break, aqui tens a solução sem break:

repeat
 write('Número? ');
 readln(n);

 if n >= 0 then begin
   if n > max then max := n;
   if (n < min) or (count = 0) then min := n;

   if isprime(n) then begin
     if n > maxp then maxp := n;
     if n < minp then minp := n;
     inc(pcount);
   end;

   inc(sum, n);
   inc(count);
 end;
until n < 0;

Estás contra este código? Viola aquilo que disseste que se devia mostrar aos principiantes? A única diferença é não ter break.

My point is, tudo aquilo que disseste em nada se enquadra na solução dada pelo @pwseo. A única coisa que estava colocada em causa era o uso de break, e entretanto estávamos a falar do tamanho de funções (esta cumpre o suposto requisito), de estruturação simples (esta só tem if's e repeat), de legibilidade vs eficiência (esta é legível, não vejo onde a legibilidade foi comprometida em nome da eficiência), e de alterações mínimas ao programa do aluno.

Neste último ponto discordo totalmente: se um aluno dá a volta a Faro para ir do Terreiro do Paço até Almada, eu vou deixar estar e não ensinar que basta atravessar a Ponte 25 de Abril e cortar na primeira saída?


Knowledge is free!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.