goto - с любимыми не расставайтесь, или break не тащит

Вопросы программирования на Free Pascal, использования компилятора и утилит.

Модератор: Модераторы

goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 16.10.2020 21:57:44

При компиляции примера
Код: Выделить всё
var
q3,w3: byte;
//label
//1;
begin
q3:=2;
w3:=3;
case q3 of
1: ;
2: begin
   if w3>10 then begin
      if w3>11 then break; //goto 1;
      w3:=8;
                 end;
//1: //метка
   if w3<7 then begin
      w3:=4;
                end;
   end;
end;
end.

компилятор выдаёт ошибку
Код: Выделить всё
(12,21) Error: BREAK not allowed

А если использовать goto, то не только самому понятнее куда выполнение прыгает,
Код: Выделить всё
var
q3,w3: byte;
{//}label
{//}1;
begin
q3:=2;
w3:=3;
case q3 of
1: ;
2: begin
   if w3>10 then begin
      if w3>11 then {break; //}goto 1;
      w3:=8;
                 end;
{//}1: //метка
   if w3<7 then begin
      w3:=4;
                end;
   end;
end;
end.

но и компилятору! Он тоже путается, когда конкретное goto заменяют абстрактной хренью.
Сквозняк
энтузиаст
 
Сообщения: 777
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Awkward » 16.10.2020 23:21:26

Начнем с того, что автор, видимо, поклонник Си, плохо знаком с синтаксисом Паскаля. Оператор break допустим внутри циклов. Он прерывает выполнение цикла, но не оператора выбора case. А помещать внутри case метки с тем же именем, что и значение условия выбора - это вообще... даже не извращение, это провокация просто какая-то.
Awkward
новенький
 
Сообщения: 30
Зарегистрирован: 19.01.2017 00:06:47

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 17.10.2020 02:59:06

Сквозняк, что за бред написан в коде? Давай начнём с того, что ты сам разберёшься, что ты там понаписал. GOTO так не используется. BREAK так же не используется.
Сделай для себя процедуру, которая будет вызываться, чтоб не лепить в условиях, ещё одни условия. Либо разбери то, что происходит на подуровне CASE. Потому что то, что написано это на уровне новичка. Да, так же, в условиях существует ELSE, который вполне подойдёт заменить многое в данном коде.
Seenkao
новенький
 
Сообщения: 86
Зарегистрирован: 01.04.2020 03:37:12

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Alex2013 » 17.10.2020 19:02:20

Упс! Вот это действительно "Альтернативная архитектура " ... Хорошо хоть Continue не вызвал . В Сase доступен только один фокус ЕLSE которое работает также как и в обычном if :idea:
.
Но вообще не понимаю как можно в принципе избегать GoTo , да это некрасиво и иногда запутывает сложный код но в принципе использование gоto может быть единственным разумным вариантом . (Например если нужно надежно выскочить из "многоярусного цикла" в "одно касание" )
Alex2013
долгожитель
 
Сообщения: 1856
Зарегистрирован: 03.04.2013 11:59:44

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 17.10.2020 19:28:39

Alex2013, его не рекомендуют для использования, потому что это один из способов выстрелить себе в ногу, если не понимаешь, что делаешь.
Объявляешь глобально метку, в одной процедуре вход, а в другой выход. Если не понял для чего это сделано, то весь код полетит к чертям.
Seenkao
новенький
 
Сообщения: 86
Зарегистрирован: 01.04.2020 03:37:12

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Alex2013 » 17.10.2020 19:43:14

Seenkao писал(а):Объявляешь глобально метку, в одной процедуре вход, а в другой выход. Если не понял для чего это сделано, то весь код полетит к чертям.

По моему подобный фокус (я о глобальных метках ) в FPC вообще не работает ! .... :idea:
Но вот из одного if (или for) в другой послать вполне можно и это действительно ... я даже цензурных слов не подберу что! :idea:
Alex2013
долгожитель
 
Сообщения: 1856
Зарегистрирован: 03.04.2013 11:59:44

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 17.10.2020 20:24:10

Alex2013, не проверял, но раньше точно в паскале работало. Но это было раньше...
Если это не работает, это и правильно и ... не правильно. ))) По идее должен сам программист определять, можно это делать или нет. Но раз убрали такую возможность, то, думаю, тому, кому это надо в доступности, это не остановит.

А проверка циклов на метки... это сверх меры, мы всё-таки программируем, а не клепаем код, поэтому так же сами должны понимать, что мы делаем. :)
Seenkao
новенький
 
Сообщения: 86
Зарегистрирован: 01.04.2020 03:37:12

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 17.10.2020 20:28:08

Awkward писал(а):Начнем с того, что автор, видимо, поклонник Си, плохо знаком с синтаксисом Паскаля. Оператор break допустим внутри циклов. Он прерывает выполнение цикла, но не оператора выбора case. А помещать внутри case метки с тем же именем, что и значение условия выбора - это вообще... даже не извращение, это провокация просто какая-то.


Си тут не при чём - куча народа орёт про то, что гото плохо и лучше всю программу испохабить, но лишь бы там его не было. И много кто знает весь синтаксис паскаля целиком :mrgreen: Новую документацию часто приходится читать при помощи яндекстранслита, потому лишнее не всегда охота читать. Компилятор же подскажет о его нарушении, это в C/C++ его нужно знать лучше, потому что там абракадабра и компиляция долгая.

А на метках в case стоит комент что это метки - читаемость соблюдена. Цифры используемого диапазона не резиновые, если использовать из другого диапазона, то случится отвлечение внимание на анализ вопроса "а с хрена тут метка не 2: а 10000000:".

Добавлено спустя 16 минут 20 секунд:
Seenkao писал(а):Сквозняк, что за бред написан в коде? Давай начнём с того, что ты сам разберёшься, что ты там понаписал. GOTO так не используется.


Ты не поверишь, но это упрощённый пример реального, кода, в котором замечательно разбираюсь, а гото там нужны ПАЧКИ! Потому что этот код делает не что-нибудь, а управляет ИИ. Есть куча процедур, которые нужно по каким-то событиям запускать или делать так чтобы они не запускались. Весь список таких процедур за один оборот главного цикла программе нужно обмозговать. А процедуры там нормальные процедуры, у каждой имя есть, которое нужно ручками во все нужные места прописать. Потому списочек процедур в case и радом с ним только растёт. Ну а для навигации по этой ленте замечательно подходят goto. Казалось бы, для прыжка на близкое расстояние подойдёт и break - а вот хрен тут.

Seenkao писал(а):Сделай для себя процедуру, которая будет вызываться, чтоб не лепить в условиях, ещё одни условия. Либо разбери то, что происходит на подуровне CASE.


Знаешь сколько мусора образуется в коде после этого? Это как слона в цирке распылить на мелкие частички, которые потом случайно смогут вдохнуть зрители представления! А так имеется процедура на несколько экранов, которая понятно что делает.

Awkward писал(а):Потому что то, что написано это на уровне новичка. Да, так же, в условиях существует ELSE, который вполне подойдёт заменить многое в данном коде.


Вот спасибо за предложение заменить работающий код на бяку с ООП, ошибки которой потом придётся ловить изучая выхлоп на ассемблере - я его плохо знаю между прочим. ELSE тоже всё не заменяет, потому что условий, при которых процедуру запускать не надо, может быть больше одного, двух или трёх, а в будущем они могут измениться - что-то не учёл или новое появится. Я должен заранее их все предусмотреть и сосчитать? Это талмуд на 500 страниц писать надо. А кто его весь прочитает и в памяти удержит? А тут взглянул на переключатели с коментами и всё прекрасно видно. Даже без отладчика и ассемблера!
Сквозняк
энтузиаст
 
Сообщения: 777
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 17.10.2020 21:16:00

Сквозняк, есть макросы, которые не захламляют код, используй их, если нет желания делать вызовы процедур.
и, вот переделка кода что ты выложил (под цифрой 2):
Код: Выделить всё
begin
  if w3>10 then
  begin
    if w3 <= 11 then
        w3 := 8;
  end;
  if w3 < 7 then
  begin
    w3 := 4;
  end;
end;

не нужен в этом коде ни Break ни GoTo.
И, это не искусственный интеллект, это выбор, возможно на чём-то основанный (близкий к ИИ), но на самом деле ИИ нельзя разрабатывать через CASE. По простой причине, что выбор должен меняться в зависимости от изменений (внутренних, наружных, случайных, не случайных и прочее). Точнее, какие-то части можно сделать, но срабатывать они должны очень редко.

Это не выбор, "надо взять": ручку? ложку? пенал? подушку? жвачку? конфету?

ИИ - это набор событий основывающихся на вопросах выбора, а не набор вопросов.

Поэтому, надо каждое событие прописать и для каждого события сделать выбор! (возможно перейти в другое событие). А не просто перебрать: то, то , то, это , не это или ещё что.

Надеюсь не запутал. :mrgreen:

Добавлено спустя 10 минут 41 секунду:
перечитал, да, вероятно я в чём-то не прав! :!: Сделал поспешные выводы, основанные на изначальном коде, который был дан в качестве примера.

Но, я думаю, если такой пример появился, то изначальный код стоило бы пересмотреть! В нём уже, похоже, много хлама, раз появляются подобные примеры.
Seenkao
новенький
 
Сообщения: 86
Зарегистрирован: 01.04.2020 03:37:12

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 17.10.2020 21:57:39

Seenkao писал(а):не нужен в этом коде ни Break ни GoTo.
И, это не искусственный интеллект, это выбор, возможно на чём-то основанный (близкий к ИИ), но на самом деле ИИ нельзя разрабатывать через CASE. По простой причине, что выбор должен меняться в зависимости от изменений (внутренних, наружных, случайных, не случайных и прочее). Точнее, какие-то части можно сделать, но срабатывать они должны очень редко.


Да ну? А фантазия, чтобы представить процедуру с таким кодом длиной в несколько экранов, и не одну такую процедуру, отсутствует? Без гото такой код превратится в какашку, которую ни прочитать толком, ни добавить, ни исправить. Код без гото при апгрейде нужно сильно переписывать а потом тестировать. И чтобы обойтись без гото Вирт придумывал новые языки - обероны. Которые представляют собой паскалеподобную среду NET Framework. Вот какую хрень нужно сотворить чтобы с какой-то долей успеха заменить гото.

Seenkao писал(а):Это не выбор, "надо взять": ручку? ложку? пенал? подушку? жвачку? конфету?

ИИ - это набор событий основывающихся на вопросах выбора, а не набор вопросов.


ИИ, это прыжки по базе знаний и умений выстраиваемые каким-то умным способом, ну или рандомом, там где у программиста ни знаний, ни вангований, ни сил предусмотреть нет. А гото как раз прыгает! Мы же не пишем ИИ для робота хирурга режущего и пришивающего на основе своих представлений о прекрасном :mrgreen: Потому, пусть прыгает, а если запрыгает не туда, тогда и ограничим.

Seenkao писал(а):Поэтому, надо каждое событие прописать и для каждого события сделать выбор! (возможно перейти в другое событие). А не просто перебрать: то, то , то, это , не это или ещё что.


Асинхронность и желание обладателя ИИ на своё мнение, лень и т.д. тут где? Без этого будет слишком скучно. То что ты описываешь, подходит для какого-нибудь станка режущего из болванок шестерёнки строго по заданию и чертежу оператора.

Seenkao писал(а):Но, я думаю, если такой пример появился, то изначальный код стоило бы пересмотреть! В нём уже, похоже, много хлама, раз появляются подобные примеры.


Вот именно код, упрощённый пример которого тут показан, работает как часики. Не хватает процедур, которые он бы запускал и не все из них достаточно "жирные" - этот код ещё подрасти должен.
Сквозняк
энтузиаст
 
Сообщения: 777
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Pavia » 17.10.2020 22:55:39

Сквозняк писал(а):Си тут не при чём - куча

А зачем вы goto на пустой код делаете? Короче вам надо синтаксис паскаля выучить.
Сквозняк писал(а):И много кто знает весь синтаксис паскаля целиком :mrgreen: Новую документацию часто приходится читать при помощи яндекстранслита, потому лишнее не всегда охота читать. Компилятор же подскажет о его нарушении, это в C/C++ его нужно знать лучше, потому что там абракадабра и компиляция долгая.

Что за бред? Стандарт паскаля более 20 лет не менялся. И давно всё переведено.
Сквозняк писал(а): Потому что этот код делает не что-нибудь, а управляет ИИ. Есть куча процедур, которые нужно по каким-то событиям запускать или делать так чтобы они не запускались. Весь список таких процедур за один оборот главного цикла программе нужно обмозговать. А процедуры там нормальные процедуры, у каждой имя есть, которое нужно ручками во все нужные места прописать. Потому списочек процедур в case и радом с ним только растёт. Ну а для навигации по этой ленте замечательно подходят goto. Казалось бы, для прыжка на близкое расстояние подойдёт и break - а вот хрен тут.

Для этих целей есть конечные автоматы.
Код: Выделить всё
function TStatementParser.Parse(Anchor: TSimvol): TStatementAST;
//   
const
  CommandCount=10;
var
  Prog:array [0..CommandCount-1] of TCaseCommand;
  procedure Init;
  begin
  Prog[0].Value:='For';    Prog[0].Woker:=ParseFor;
  Prog[1].Value:='While';  Prog[1].Woker:=ParseWhile;
  Prog[2].Value:='Repeat'; Prog[2].Woker:=ParseRepeat;
  Prog[3].Value:='If';     Prog[3].Woker:=ParseIf;
  Prog[4].Value:='Case';   Prog[4].Woker:=ParseCase;
  Prog[5].Value:='Goto';   Prog[5].Woker:=ParseGoto;
  Prog[6].Value:='Begin';  Prog[6].Woker:=ParseCompaundStatement;
  Prog[7].Value:='End';    Prog[7].Woker:=Nop;
  Prog[8].Value:='Else';   Prog[8].Woker:=Nop;
  Prog[9].Value:='until';  Prog[9].Woker:=Nop;
  end;
var
  Woker:TParserProcedure;
  NodeAST:TNodeAST;
begin
Init;
Self.Anchor:=Anchor;
Result:=ASTFabric.NodeCreate(atTStatementAST) as TStatementAST;
ASTFabric.ActivLeaf:=Result;
Result.Line:=(Compiler.LexAnaliser as TFileSimvler).PosRow;
// repeat
    NodeAST:=Nil;
    Woker:=ChooseOfWork(CommandCount,@Prog, CurrentSimvol());

    if @Woker=nil then
       begin
       ParseLabelingStatement(NodeAST);
       if NodeAST=Nil then
          begin
          ErrorWay(Anchor);
      //    Break;
          end;
       Result.Add(NodeAST);
       end else
       if Not IsNop(Woker) then
          begin
          Woker(NodeAST);
          Result.Add(NodeAST);
          end;
//  if SimvolsEQ(CurrentSimvol,Anchor);
// until  IsAnyAnchor or IsNop(Woker);
  ASTFabric.LevalUp;
  if (NodeAST=Nil) then
      FreeAndNil(Result);
end;


Сквозняк писал(а):Вот спасибо за предложение заменить работающий код на бяку с ООП, ошибки которой потом придётся ловить изучая выхлоп на ассемблере - я его плохо знаю между прочим. ELSE тоже всё не заменяет, потому что условий, при которых процедуру запускать не надо, может быть больше одного, двух или трёх, а в будущем они могут измениться - что-то не учёл или новое появится. Я должен заранее их все предусмотреть и сосчитать?


Это называется таксичный код. Rad студия умеет подсчитывать таксичность кода. Если в функции больше 2-х условий или больше 2-х циклов, то его становиться трудно поддерживать. Для чего и придумали писать качественный код, а не как у вас.
Это талмуд на 500 страниц писать надо. А кто его весь прочитает и в памяти удержит?

И не нужно Вирт придумал структурированный подход. А потом родился ООП и семантический подход когда по названию понимаешь что делает функция.
Ещё Вирт писал о сокрытии информации изобретая свои модули. Что бы студентом было проще делать более сложные вещи. К примеру вам не нужно знать как работают транзистеры телевизор чтобы переключить каналы или открыть ютуб. Такую же идею и используют при проектировании дробя код на независимые модули.
Это же основы проектирования архитектуры. Сокрытие и уменьшение связности. Последнее достигается за счёт применения теоремы Барбары которая позволяет уменьшить число case.

Асинхронность и желание обладателя ИИ на своё мнение, лень и т.д. тут где? Без этого будет слишком скучно. То что ты описываешь, подходит для какого-нибудь станка режущего из болванок шестерёнки строго по заданию и чертежу оператора.

В паскале нет асинхронности вам следует перейти на новые языки с поддержкой await и yield. Кооперативную многозадачность засунуть в автомат проще.
Да ну? А фантазия, чтобы представить процедуру с таким кодом длиной в несколько экранов, и не одну такую процедуру, отсутствует? Без гото такой код превратится в какашку, которую ни прочитать толком, ни добавить, ни исправить. Код без гото при апгрейде нужно сильно переписывать а потом тестировать.

Какашка это ваш goto. Он ломает темпоральную логику не позволяя формально доказать правильность работы программы на соответствие спецификации описанной на языке TLA+.
работает как часики.
Т.е кроме как показывать время ни на что больше не годится? :mrgreen:
Аватара пользователя
Pavia
постоялец
 
Сообщения: 274
Зарегистрирован: 07.01.2011 12:46:51

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Seenkao » 17.10.2020 23:32:48

Pavia, тут другая проблема по коду, он выложил "упрощённый" код и вполне вероятно, настоящий код выглядит по другому, а он показал "пробу" пера.
Pavia писал(а):Какашка это ваш goto. Он ломает темпоральную логику не позволяя формально доказать правильность работы программы на соответствие спецификации описанной на языке TLA+.
ну... мне так-то вообще плевать где, что, чего ломает, я не пренебрегаю использовать GoTo.
Но это будет извечный спор, нужен он или нет. Но лучше пусть будет, чем нет.
Seenkao
новенький
 
Сообщения: 86
Зарегистрирован: 01.04.2020 03:37:12

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Сквозняк » 18.10.2020 00:07:12

Pavia писал(а):А зачем вы goto на пустой код делаете? Короче вам надо синтаксис паскаля выучить.

А вы серьёзно считаете, что я должен был выложить сюда половину проекта ещё до его релиза специально чтобы люди со спящей фантазией увидели не пустой код? Я выложил минимальный пример такого синтаксиса всего с двумя переменными и без процедур. Если вам интересны сами процедуры, то увы, боюсь. что после их выкладывания останусь у разбитого корыта.
Pavia писал(а):Что за бред? Стандарт паскаля более 20 лет не менялся. И давно всё переведено.

Ага, не менялся, а новые версии fpc всё выходят и выходят. А с переводом не всё хорошо, часть его грохнули и всё подмяли под лазарус. Та справка в html формате, что идёт вместе с дистрибутивом исходников - вообще без перевода! А именно несколько её файлов открыты у меня в браузере почти постоянно. Также её можно открывать в fp-ide, но там хуже видно чем в браузере.

Pavia писал(а):Для этих целей есть автоматы.


И зачем для такой простой вещи подключать лазарус с другим диалектом паскаля и всё усложнять указателями и прочей хренью? Мой пример нормально работает при
{
{$MODE FPC}

А ваш не сможет. Для него и редактор другой применять придётся!
Pavia писал(а):Это называется таксичный код. Rad студия умеет подсчитывать таксичность кода. Если в функции больше 2-х условий или больше 2-х циклов, то его становиться трудно поддерживать. Для чего и придумали писать качественный код, а не как у вас.


А мой код должен принести _мне_ пользу и быть по возможности нереализуем другими программистами увидевшими конечный результат. Капитализм на дворе и сражение за миску супа. Кто проиграл, тот бомж и подыхает под мостом. Причём мой код нормально пишется и анализируется из консольки, в простой паскалевской ИДЕ, и не требует Rad студии. И какой из кодов тогда более токсичный?

Pavia писал(а):И не нужно Вирт придумал структурированный подход. А потом родился ООП и семантический подход когда по названию понимаешь что делает функция.

А потом вдруг нужно залезть в класс чтобы что-то исправить и начинается поиск мест по которым размазана реализация. ООП, это не про удобство понимания кода, а про удобство копипасты однажды кем-то накоденных решений. Клац, клац по формам, что-то прописал в обработчиках событий и готово. Ну так вот, ООП интерфейс у меня давно готов, там только что-то мелкое подправить можно, когда необходимость созреет. Так что описанным вами методом пока кодить нечего. Нету готовых классов в лазарусе для ненаписанной части кода, а значит он может отдохнуть в сторонке. Как ООП, так и несчастье - то из стека вылетишь, то память подтекает. Причём часть мин ловушек имеют замедленное действие, их не сразу заметишь и тогда - здравствуй отладчик и замена паскалевских гото ассемблерными :mrgreen:

Pavia писал(а):Такую же идею и используют при проектировании дробя код на независимые модули.
Это же основы проектирования архитектуры.


Считаете, что у меня код с гото такой маленький, что его удобно редактировать в одном файле?

Pavia писал(а):Сокрытие и уменьшение связности. Последнее достигается за счёт применения теоремы Барбары которая позволяет уменьшить число case.


А вот связности мне нужно побольше, а теорем поменьше. Такой вот проект.

Pavia писал(а):В паскале нет асинхронности вам следует перейти на новые языки с поддержкой await и yield.


Не знаю, что это за операторы, но про асинхронность вы сильно ошибаетесь. Давно уже сказано, что на паскале можно написать всё. А вот как это "всё" писать без гото и касе, данный мыслитель ничего не изрёк.

Pavia писал(а):Какашка это ваш goto. Он ломает темпоральную логику не позволяя формально доказать правильность работы программы на соответствие спецификации описанной на языке TLA+.


Гото, это замечательный логический элемент, который соответствует русскому народному посыланию на 3 весёлых буквы и в прочие интересные места. А в математике гото нет, но это ещё раз подтверждает ту истину, что математика это подмножество логики, а никак не наоборот. Если вы не смогли написать логическую спецификацию, то идите и переписывайте нормально.
Pavia писал(а):Т.е кроме как показывать время ни на что больше не годится? :mrgreen:

Маленькая часть не должна уметь всего. Ну а количество параллельных времён там около десяти, так что даже и время там показать не такая простая задача. Говорю же, есть в паскале асинхронность, это в лазарусе её так сломали, что приходится кидать на форму элемент "будильник" - тимер :mrgreen: и прописывать в его обработчике кучу событий.
Сквозняк
энтузиаст
 
Сообщения: 777
Зарегистрирован: 29.06.2006 22:08:32

Re: goto - с любимыми не расставайтесь, или break не тащит

Сообщение Vadim » 18.10.2020 04:25:05

И вечный спор, покой нам только снится,
Про GOTO. Уж сотни лет он длится.
Но если в компилятор до сих пор загружен,
Наверно, для чего-то, всё же нужен?

:-)
Vadim
долгожитель
 
Сообщения: 3918
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск


Вернуться в Free Pascal Compiler

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8

Рейтинг@Mail.ru