Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Общие вопросы по программированию, компьютерный форум
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.01.2012, 00:46   #21
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,568
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Это субъективный фактор. Тебе читабельнее продублировать код, мне - вынести в одно место.
Не понял о каком дублировании речь?
Какой из вариантов читабельнее и понятнее?
Этот:
Код:
K := DoSomething;
if K = 0 goto Error;
K := DoSomethingElse;
if K = 0 goto Error;
K := Funcenstein;
if K = 0 goto Error;
Result := True;
Exit;

Error:
WriteLn('Ошибка');
Result := False;
end;
Или этот:
Код:
if (DoSomething = 0) or (DoSomethingElse = 0) or (Funcenstein = 0) then
begin
  WriteLn('Ошибка');
  Result := False;
else Result := True;
Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Несложно сообразить, что между вызовами функций может стоять код. Если не понятно, то код примера - аналог try/finally.
Не знаю, не телепат, что там может стоять. Я конкретный пример рассматривал. А так да, все зависит от ситуации. Тем более, что нет смысла придумывать аналоги try/finally. Надеюсь, на Turbo Pascal никто уже не пишет...

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Ну, началось....

Каких только слонов, подпорок и обходных путей не придумают противники GOTO, чтобы только его не использовать.
Я бы это сделал по второму варианту, с выносом в отдельную функцию.

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Как видно из примера, это замаскированный GOTO.
Не совсем. Он понятнее, т.к. мы явно указываем, какой блок прервать или в какой блок перейти. Не на конкретную метку, а выход из блока. А с метками и возникает путаница. То ли она сразу после блока, то ли где-то ниже. Особенно если кода больше, чем на страницу, не видно даже, куда переход будет.
Arigato вне форума Ответить с цитированием
Старый 12.01.2012, 00:57   #22
rpy3uH
добрый няша
Старожил
 
Аватар для rpy3uH
 
Регистрация: 29.10.2006
Сообщений: 4,804
По умолчанию

Цитата:
Сообщение от Arigato Посмотреть сообщение
Не понял о каком дублировании речь?
Какой из вариантов читабельнее и понятнее?
посмотри мой пример и всё поймёшь

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
rpy3uH, я бы лучше спроектировал код на работу с исключениями. и тогда привет try finally.
try finally - не всегда спасает, например в том же С и при программировании драйверов. и опять же, этот блок тоже довольно-таки сильно загромождает код.
rpy3uH вне форума Ответить с цитированием
Старый 12.01.2012, 01:27   #23
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
ещё пример где метки очень нужны
Именно этот пример я пытался привести.

Цитата:
Тем более, что нет смысла придумывать аналоги try/finally. Надеюсь, на Turbo Pascal никто уже не пишет...
Вот я и говорил, что вот есть такая ситуация, но в современных прикладных языках она не актуальна.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 12.01.2012, 01:30   #24
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Грузин верно подметил насчет С.
там то или метки, или выкручиваться.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.01.2012, 01:35   #25
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Не совсем. Он понятнее, т.к. мы явно указываем, какой блок прервать или в какой блок перейти. Не на конкретную метку, а выход из блока. А с метками и возникает путаница. То ли она сразу после блока, то ли где-то ниже. Особенно если кода больше, чем на страницу, не видно даже, куда переход будет.
Вот ты привёл пример:
Код:
scopeName "main";
while {true} do
{
  scopeName "loop1";
  while {true} do
  {
    scopeName "loop2";
    if (condition1) then {breakTo "main"}; // Breaks all scopes and return to "main"
    if (condition2) then {breakOut "loop2"}; // Breaks scope named "loop2"
    sleep 1;
  };
  sleep 1;
};
Ты говоришь, что для тебя это хороший и правильный пример.

Окей, положим в моём гипотетическом языке GOTO называется BREAK. Тогда я мог бы написать:
Код:
while True do
begin
  while True do
  begin
    if condition1 then break Main; 
    if condition2 then break Loop2;
    Sleep(1);
  end;
  Loop2:
  Sleep(1);
  Loop1:
end;
Main:
Чем принципиально отличаются эти два фрагмента? Ничем. Синтаксисом. Тем не менее, первый тебе почему-то понятен и очевиден, а второй - "читабельность снижается, т.к. надо еще найти, где эта метка находится". Просто чудеса какие-то.

Аналогично:
Код:
while True do
begin
  ...
end;
и
Код:
Loop:
  ...
goto Loop;
Почему-то первый фрагмент по твоим словам получается читабельнее, чем второй (ты же предлагал заменять метки на бесконечные циклы). И это несмотря на то, что первый фрагмент - это явный хак, а второй фрагмент для любого стороннего человека читабельнее (потому что одним именем подписан начало и конец).
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.

Последний раз редактировалось GunSmoker; 12.01.2012 в 01:56.
GunSmoker вне форума Ответить с цитированием
Старый 12.01.2012, 01:54   #26
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,568
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
Грузин верно подметил насчет С.
там то или метки, или выкручиваться.
Это проблемы языка. Никто не спорит, что если язык не позволяет обойти goto, то его нельзя использовать. К примеру, в древних BASIC без goto вообще невозможно было что-либо сделать. Но языки стремятся к тому, что бы свести необходимость в goto к минимуму или вообще избавиться от него.

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Вот ты привёл пример:
Код:
scopeName "main";
while {true} do
{
  scopeName "loop1";
  while {true} do
  {
    scopeName "loop2";
    if (condition1) then {breakTo "main"}; // Breaks all scopes and return to "main"
    if (condition2) then {breakOut "loop2"}; // Breaks scope named "loop2"
    sleep 1;
  };
  sleep 1;
};
Ты говоришь, что для тебя это хороший и правильный пример.

Окей, положим в моём гипотетическом языке GOTO называется BREAK. Тогда я мог бы написать:
Код:
while True do
begin
  while True do
  begin
    if condition1 then break Main; 
    if condition2 then break Loop2;
    Sleep(1);
  end;
  Loop2:
  Sleep(1);
  Loop1:
end;
Main:
Чем принципиально отличаются эти два фрагмента? Ничем. Синтаксисом. Тем не менее, первый тебе почему-то понятен и очевиден, а второй - "читабельность снижается, т.к. надо еще найти, где эта метка находится". Просто чудеса какие-то.
Еще раз повторю. В моем примере break осуществляет выход из блока, а не переход по метки, в этом разница. Метка может стоять и не сразу за end, а где-то неизвестно где ниже (или даже выше). А там мы даем название блоку и можем прервать выполнение блока с любой вложенностью. Тем более, что название идет в начале блока, а не в конце, как в случае с меткой. Что бы понять, из какого блока мы выходим, нам не надо пролистывать код вниз.
Arigato вне форума Ответить с цитированием
Старый 12.01.2012, 02:27   #27
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
Это проблемы языка. Никто не спорит, что если язык не позволяет обойти goto, то его нельзя использовать.
"нельзя"?

Ладно, даже если исправить фразу - вообще-то C прекрасно позволяет обходится без goto. Это доказал всем известный дядька в известной работе. Вопрос-то не в том, можно или нет, а зачем мне обходится без goto?

Цитата:
В моем примере break осуществляет выход из блока, а не переход по метки, в этом разница.
Любой Break - это goto на неявную метку.

А Break с именем - это goto в чистом виде.

Цитата:
Метка может стоять и не сразу за end, а где-то неизвестно где ниже (или даже выше).
И, собственно, что? Конкретно здесь она стоит не "где-то", а во вполне определённом месте.

В обоих подходах (именованный блок и GOTO), если ты видишь break/goto что-то - ты в первую очередь проверяешь границы циклов/блоков. И видишь или имя блока или имя метки. И в чём же тогда разница?

Это примерно как говорить "я обычно храню ключи от дома в шкафчике у зеркала, поэтому я начну их искать с туалета".

Цитата:
Тем более, что название идет в начале блока, а не в конце, как в случае с меткой. Что бы понять, из какого блока мы выходим, нам не надо пролистывать код вниз.
Подмена понятий.

Если код умещается на странице/в твоей памяти - между вариантами кода нет разницы, если код не умещается - тебе в любом случае придётся листать. С именованными блоками листать надо вверх, с метками - вниз.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 12.01.2012, 09:49   #28
Arigato
Высокая репутация
СуперМодератор
 
Аватар для Arigato
 
Регистрация: 27.07.2008
Сообщений: 15,568
По умолчанию

GunSmoker, не вижу смысла что-либо доказывать, думайте как хотите.
Единственное, что было бы удобно, что бы можно было бы давать имена циклам прямо в заголовке. Как-то так:
Код:
while <...> do name while1
begin
  ...
  while <...> do
  begin
    ...
    if <...> then break while1;
    ...
    if <...> then continue while1;
    ...
  end; {while}
  ...
end; {while while1}
То, что я привел, близко к такому. Но такой вариант был бы лучше.
Arigato вне форума Ответить с цитированием
Старый 12.01.2012, 11:18   #29
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Давай-ка точки над i расставим.

Метки и GOTO могут стать кошмаром, если ими злоупотреблять. Но в то же время есть парочка ситуаций, где их применение легитимно. Ты уж извини, но любые аргументы "это не читаемо" тут высосаны из пальца. "Мне не нравится" - это нифига не аргумент.

Итого получаем, что есть несколько известных случаев хорошего применения и куча способов плохого применения.

Так почему бы не узаконить хорошие случаи и запретить плохие? К примеру, ввести имена для блоков и указывать в Break имя блока?

Ну и пожалуйста. Я двумя руками за и даже не отказался бы от такого в Delphi (я на нём пишу).

НО.

Это - GOTO и метки в явном виде. Даже хотя они так не называются. И говорить что вот этот вот код надо переписать, потому что тут GOTO, а вот тот код надо использовать, потому что там именованные блоки - это двоемыслие в чистом виде. Типа, если цветы переименовать в тырбырмыр, то дарить их девушке уже не надо?
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 12.01.2012, 11:48   #30
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Цитата:
Вот и выросло поколение не знающее goto... Мир уже не торт . И куда только Земля катится?
+1
Дак в сети куча надуманных примеров когда очень неплохо подходят метки.
_-Re@l-_ вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
зачем учить Pascal krot_zdes Свободное общение 52 31.05.2011 16:48
Зачем эта перменная (Delphi) reasons Помощь студентам 9 15.07.2010 22:22
Метки в Tbarseries (Delphi 7) Николай ПН Помощь студентам 0 31.03.2010 18:40
Что такое коды ASCII и зачем они?? Ларик Помощь студентам 2 27.01.2008 19:41
обновление в блоге - Ресурсы. Зачем они нужны. Pblog Обсуждение статей 0 27.05.2007 03:17