[флейм] Нужен ли оператор GOTO?
копирайты! помним про копирайты!
---
A2: Потому что так завещал великий и мудрый Ибеме, и по другому делать некошерно.
Сообщение удалил
является композиция из классического набора BEGIN-WHILE-UNTIL.
Как основу для примера можно взять что-нибудь наподобие strchr.
---
...Я работаю антинаучным аферистом...
Сообщение удалил
В случае цикла есть break, т.е. вместо goto для избежания дублирования кода всегда можно пользоваться универсальной комбинацией infinite loop + break:Что-то я не понял, ни твоего примера, ни примера KOHTPы. Но здесь про php говорят? Для выхода из вложенных циклов/switch (одна из частых ситуаций, когда нужен goto) в php есть оператор break N; (например break 2 где N - уровень вложенности. Но вообще, иногда goto может быть реально полезен, в первую очередь тогда, когда код из себя представляет, по сути, реализацию несложного конечного автомата. В случае, когда его структура будет достаточно хитрой, удобно использовать goto. Например, такая задача возникает при парсинге чего-либо (даже если использовать регулярные выражения - просто в этом случае потребность возникает при более сложных выражениях, которые нельзя закодировать одним выражением).
PS: Я не понимаю, почему так много людей страдает готофобией.
Есть подозрение, что это как-то связано с широким распространением недоязыка Паскаля и высокой проникающей способностью космических идеек его создателя, Великого Теоретического Программиста Никлауса Вирта. Дийкстра про бейсик сказал, что он damages brain, но вообще, пожалуй, мозг, способный порождать концепции вроде этой: "В случае цикла есть break, т.е. вместо goto для избежания дублирования кода всегда можно пользоваться универсальной комбинацией infinite loop + break", должен быть разрушен намного основательней, чем это могут сделать даже три бейсика одновременно.
A
while ( condition )
{
B
A
}
=>
while (1)
{
A
if ( !condition ) break;
B
}
Брандис в 1995 г. защищал диссертацию по оптимизирующим компиляторам для языков структурного программирования (научный рук-ль Х.Мессенбок). В ней про goto особых поворотов нет, а вот в его работе, представленной на JMLC-конференции в Ульме (1994 г. есть искомый материал.
Делался back-end для Oberon-компилятора OP2. Одним из сложных моментов была оптимизация unstructured control-flow (куда входит goto, break, continue в Си, а также EXIT и RETURN в Обероне).
Брандис решил выяснить практику использования goto в Си и Обероне.
В качестве сравнения брались
1. X Window 11 R5 (MIT)
2. GNU C Compiler 2.6.0 (для IBM RS/6000 Free Software Foundation
3. ANSI C Compiler LCC 3.0
Выбор продуктов (в основном компиляторы) обусловлен видимо тем, что в ETH очень любят тестировать компиляторы на самих компиляторах. В принципе подход Вирта дает хорошие результаты.
Сначала проводилась фильтрация: например, в GNU CC кол-во goto было 5701 штук, потом выяснилось, что более 5000 лежали в одном-единственном файле , где реализовывался конечный автомат. Причем текст автомата генерировался автоматически из описания. Естественно из расчета выбросили.
Что получилось – см. ниже.
пакет | исх.файлов | строк | #goto | строк/goto |
X Window 11 R5 | 1747 | 735038 | 900 | 817 |
GNU CC 2.6.0 | 111 | 288510 | 679 | 425 |
LCC 3.0 | 29 | 24684 | 18 | 1371 |
всего | 1887 | 1048232 | 1597 | 656 |
Вывод Брандиса: относительно небольшое кол-во goto говорит о том, что структурное программирование не забывают и в Си. Более того, выявилась тенденция кучкования goto в небольшом числе файлов. Так, напр., ни одного goto не было в 92% исходников (смотрелись только *.c) для X Window, в 50% для GNU CC и в 90% для LCC. Брандис приводит подробный график распределения, из которого видно, что критичные 5, 20, 100 и 200 строк на одно goto занимают от 20 до 500 файлов (в основном в X Window).
Более детальное изучение исходных текстов натолкнуло Брандиса на мысль, что по большей части goto использовались из-за неаккуратного программирования вполне конкретными людьми.
Но на этом он не остановился. Интересно было узнать, как соотносятся так называемые скрытые goto (break + continue в Си и EXIT в Обероне). Напомню, что EXIT -- это оператор выхода из безусловного цикла LOOP (обычно по IF). Управление передается на первый оператор, идущий за END данного цикла. Он назвал эти скрытые goto переходами (branches).
пакет | исх.файлов | строк | переходов | строк/переход |
X Window 11 R5 | 1747 | 735038 | 1103 | 666 |
GNU CC 2.6.0 | 111 | 288510 | 887 | 325 |
LCC 3.0 | 29 | 24684 | 40 | 617 |
всего | 1887 | 1048232 | 2030 | 516 |
Oberon System | 97 | 37386 | 210 | 178 |
В рассмотрение добавились исходные тексты системы Oberon (97 модулей) для IBM RISC/6000.
Брандиса удивило, что Оберон-программы содержат больше скрытых goto, чем Си-программы. Причем распределение было также неравномерным. См. табл.
пакет | исх.файлов | файлов без перех. | % от всех файлов |
X Window 11 R5 | 1747 | 1500 | 86% |
GNU CC 2.6.0 | 111 | 45 | 40% |
LCC 3.0 | 29 | 20 | 69% |
Oberon System | 97 | 61 | 63% |
По циклам в Обероне выявилось, что из 1479 циклов доля WHILE -- 1113, REPEAT -- 232, а LOOP -- 134. Т.е. LOOP-EXIT занимали 9,1%.
LOOP с одной точкой выхода Оберон-программисты использовали, чтобы избегать дублирования кода. Но можно легко трансформировать эту структуру в WHILE.
LOOP
stat0;
IF pred THEN EXIT END;
stat1
END;
эквивалентен
stat0;
WHILE ~pred DO
stat1;
stat0
END;
Интересно, что Гризмер (Griesmer) переписал фрагменты своего компилятора Oberon-V, избавившись от LOOP в пользу WHILE. При этом он обнаружил, что в большинстве случаев текст стал понятней.
Вот что показало распределение операторов EXIT по безусловным циклам LOOP
кол-во EXIT 0 1 2 3 4 5 6
кол-во LOOP 9 62 51 6 3 2 1
Выводы Брандиса:
1. Скрытые goto в программах -- вполне нормальное явление и не нужно пытаться обязательно от них избавляться. Чаще всего, оптимизирующий компилятор сделает это при необходимости сам.
2. Что касается обычного goto, то лучше, когда в языке его нет (как в Modula-2 и Oberon но когда он есть, то концентрируется обычно там, где код пишется неаккуратно (плохой стиль конкретного программиста). Разумеется, особые случаи вроде автоматической генерации текстов для конечных автоматов, сетей Петри и подобных абстракций в счет не идут.
1. За что ты так не любишь Pascal?
2. Какой язык по-твоему хорош как первый язык?
Надеюсь на развёрнутые ответы.
---
...Я работаю антинаучным аферистом...
Вот такой вопрос.
Как на структурном Си надо писать такое
BEGIN <1> WHILE <2> WHILE <3> REPEAT <4> ELSE <5> THEN
где все <n> --- непусты.
Такая вещь используется, в частности, для выковыривания числа из строки.
---
...Я работаю антинаучным аферистом...
BEGIN <1> WHILE <2> WHILE <3> REPEAT <4> ELSE <5> THENЧто-то страшно как-то.
Такая вещь используется, в частности, для выковыривания числа из строки.Для выковыривания числа из строки уже довольно давно рекомендуется пользоваться регулярными выражениями.
А стандартные функции (вроде strtoXX или atoXX) тяжеловесны
и обладают, к тому же, неприятными свойствами.
---
...Я работаю антинаучным аферистом...
А стандартные функции (вроде strtoXX или atoXX) тяжеловесныА чо, уже только C есть? В C++ и C# синтаксис практически тот же, но все почему-то сильно проще (особенно в C#).
и обладают, к тому же, неприятными свойствами
Не уже, а только и есть.
А приплюснутые си ещё отсутствуют и ещё не ожидаются.
Если тебе так хочется, скажи, как это на приплюснутых сях.
Точно такое же часто требуется для разгребания файлов.
---
...Я работаю антинаучным аферистом...
На приплюснутых не скажу, их же нет. А на C# запросто могу. Тебе что конкретно показать?
написать предложенное наиболее ясно, без дублирования кода и проч.
---
...Я работаю антинаучным аферистом...
Их тоже нет.
---
...Я работаю антинаучным аферистом...
Даны 5 законченных грамматических конструкцийЭто про тот страшный ужас с циклами всех мастей? Ну пусть даны, нафиг они не нужны. Что еще показать?
С#, к сведению, это недоприплюснутые.Сегодня и последнюю неделю - да, нету. Праздники все-таки. А еще 30 декабря они были. Я их видел
Их тоже нет.
Они не везде могут выжить.
---
...Я работаю антинаучным аферистом...
Все эти приплюснутые си слишком тяжеловесны и делать их вряд ли кто будет.Недоплюснутые полегче малек (с некоторой точки зрения).
Они не везде могут выжить.Везде выживает только вирус гриппа. На мобильниках уже и C++, и C# есть.
---
"Я знаю правду! Все прежние правды --- прочь!"
Встроенные?
- Штурман, приборы?Аналогично, что встроенные?
- Семьдесят
- Что семьдесят?
- А что приборы?
---
...Я работаю антинаучным аферистом...
На борту."Товарищ капитан, на борту А-495 за время дежурства происшествий не произошло".
Вы не могли бы более точно формулировать вопросы? Их чрезмерно краткая форма не позволяет однозначно толковать смысл.
Что тут неясного?
---
...Я работаю антинаучным аферистом...
Меня интересует (и в первом же моем ответе был задан этот вопрос вопрос целесообразности такой конструкции.
Это обычная схема однопроходной обработки файла.
---
...Я работаю антинаучным аферистом...
Целесообразна.Хм. Не смог соотнести приведенную конструкцию со схемой однопроходной обработки файлов. Можно более подробный пример (видимо, с подставленными <1>, <2>...)?
Это обычная схема однопроходной обработки файла.
Учти, со временем люди будут видеть всё меньше разницы между вами.
За то, что это язык не предназначенный для написания кода. Он придумывался для обучения студентов программированию, потом на него долго лепили заплатки чтобы таки можно было писать какие-нибудь программы отличные от "считать с консоли десять чисел, посортировать их пузырьком, вывести результат" (например, прикрутили пойнтеры потом к нему прикрутили загадочную объектную модель ещё. Но вообще остаётся жуткое ощущение, что его придумывал не программист. На нём тяжело, плохо и неудобно кодить. В нём длинные служебные слова, неортогональный синтаксис, из синтаксиса не вытекает непосредственно способ расставления отступов. До универа я очень много программировал на Паскале, причём в том числе и коммерческие проги, поэтому я как бы знаю о чём говорю.
Самое в этом всём неприятное - что после того, как человека научили программировать на паскале, он с большой вероятностью попытается использовать паскаль в реальной жизни.
>> 2. Какой язык по-твоему хорош как первый язык?
Наиболее разумной мне кажется следующая последовательность:
1) Машына Тьюринга + нормальные алгоритмы Маркова
2) С# или жава без объяснения механизмов наследования (чисто на статических функциях похожий подход есть в Развивающей Игре Colobot.
3) С# или жава в полном объёме.
4) С + unix environment.
5) Ассемблер
Четвёртый и пятый пункты, возможно, следует поменять местами. Плюсы идут нах. Возможно, ещё следует добавить шестым пунктом какой-нибудь лисп или хаскелл. А седьмым - какой-нибудь нетипизованный скриптовый язык, типа жаваскрипта/вбскрипта под WSH, типа целую одну лекцию + лабу можно посвятить.
succeded else error then
---
...Я работаю антинаучным аферистом...
Уточни, пожалуйста, на каком языке написан кусок кода. Из предыдущего объяснения непонятно, по виду не идентифицируется
А плюсы чем не угодили? Слишком сложны? Просто я как раз освежаю знания С++. По моему, он просто неузнаваемо изменился за последние ~10 лет. Прямо-таки, другой язык.
Можно сразу выкинуть 1-3 в мусорку.
В сях не только неортогональный синтаксис,
так ещё и неочевидная семантика впридачу.
Если в недоприплюснутых сях и прочих произведениях
сантехников остался "break", то это относится и к ним.
---
...Я работаю антинаучным аферистом...
> сантехников остался "break", то это относится и к ним.
Согласен с тем, что использовать break - не сильно лучше, чем goto.
Но - как ты относишься к исключениям? Ведь в плане структурности программы, исключения (или аналогичные конструкции) ломают её на порядки сильнее... Так можно дойти и до того, что и исключения не нужны, и return может быть лишь единственный, в конце тела функции.
Не очень хорошо.
Но жить можно.
Без исключений жить сложнее.
> return может быть лишь единственный, в конце тела функции.
Вот этого не надо.
Чем break, лучше return.
---
...Я работаю антинаучным аферистом...
Самое в этом всём неприятное - что после того, как человека научили программировать на паскале, он с большой вероятностью попытается использовать паскаль в реальной жизни.Где поклонники Delphi?
Fj, ты не прав. Может быть служебные слова и длинные - однако код радует глаз и легко читается (в отличие от C).
И что значит
неортогональный синтаксис, из синтаксиса не вытекает непосредственно способ расставления отступовотступы легко и просто расставляются тем же ConTEXT
вытекает способ отступов?
begin
bla;
bla;
while bla do
bla-bla-bla;
bla;
bla;
end.
bla, ни в коем случае так не пишиbegin
bla;
bla;
while bla do
bla-bla-bla;
bla;
bla;
end.
Ты думаешь, твой код после тебя никто читать небудет?
Надо:
begin
bla;
bla;
while bla do begin
bla-bla-bla;
end;
bla;
bla;
end.
Никогда не пиши
begin
bla;
bla;
while bla do begin
bla-bla-bla;
end;
bla;
bla;
end.
Ты думаешь, твой код после тебя читать никто не будет?
Надо писать так:
begin
bla; bla; while bla do bla-bla-bla;
bla; bla;
end.
---
...Я работаю антинаучным аферистом...
BEGIN
Bla-bla-bla;
WHILE bla DO
Bla-bla-bla
END;
Bla-bla-bla
END Bla-bla;
а что до begin и end в while, так для одного оператора в цикле они не обязательны
END Bla-bla;это уже что-то нечто
И что?
> но мы говорили о расставлении отступов!
Вот именно.
---
...Я работаю антинаучным аферистом...
а ты своим
bla; bla; while bla do bla-bla-bla;всё изгадил
---
...Я работаю антинаучным аферистом...
И кто что изгадил?
---
...Я работаю антинаучным аферистом...
а что до begin и end в while, так для одного оператора в цикле они не обязательныДа, необязательны. Это огромный минус.
Если ты напишешь while/if/ещё что-нибудь с одним оператором, без begin и end, и расставишь отступы - будет огромная вероятность, что тот, кто после тебя будет менять этот код, если ему понадобиться вставить второй оператор - вставит его, не добавив begin и end. Как потом прикажешь ловить глюки, порождённые этим?И зачем, если можно без особых усилий обойтись без создания этих глюков?
Это не минус, а плюс.
> Если ты напишешь while/if/ещё что-нибудь с одним
> оператором, без begin и end, и расставишь отступы
...
> Как потом прикажешь ловить глюки, порождённые этим?
Это означает только одно: отступы --- вредны.
Отступы --- порождение зла и их надо выжигать калёным железом.
> И зачем, если можно без особых усилий обойтись без создания этих глюков?
---
"Теперь
не промахнёмся мимо.
Мы знаем кого --- мети!"
Не согласен. Лично я не помню, чтобы когда-нибудь скобочки забывал поставить при добавлении операторов, а вот дополнительная компактность - очень и очень помогает. А тем более, если использовать чудовичные begin end вместо {}. В этом плане очень раздражает Perl, который позволяет кучу всяких трудночитаемых конструкций, нафиг нормальным лядям не нужных, но не позволяет для if/for использовать тело, состоящее из одного оператора, без скобок.
а вот дополнительная компактность - очень и очень помогаетОткуда там появляется дополнительная компактность? Количество строк одинаковое...
А тем более, если использовать чудовичные begin end вместо {}.Преимущество "{" перед "begin" - совсем другой вопрос. Мы тут не это обсуждаем.
А ещё бывают конкурсы "кто напишет самую запутанную программу, в которой никто другой не разберётся".
Вот только для коммерческого программирования (точнее, для программирования, когда твоим кодом будет пользоваться кто-то другой - читать/модифицировать) это нах не нужно, и выжигать калёным железом надо как раз твои примерыю
какой именно код легче читать и изменять.
Точно так же, как и те горе-"программисты", которые проверяют код.
---
...Я работаю антинаучным аферистом...
Для проверки кода используются именно горе-программисты, а не КОНТРА. Значит, надо делать так, как удобно этим горе-программистам, а не КОНТРЕ.
Для проверки кода используются именно горе-программистыА что бывает проверка кода, ну вместо тестироавния, да?
В том числе --- содержит меньше ошибок.
А т. н. "коммерческие программисты" --- балбесы,
ибо сами себе создают кучу трудностей,
которых можно было бы легко избежать.
---
...Я работаю антинаучным аферистом...
Бывают еще code-review c применением заклинаний "это что тут за фигня?!"
Прикинь?
---
...Я работаю антинаучным аферистом...
Как из синтаксисаНу, например, есть такой язык - python.
вытекает способ отступов?
>> Отступы --- порождение зла и их надо выжигать калёным железом.
Дружёк, отступы вредны в функциональных языках, в которых каждое слово осмысленно само по себе, а функция на десять строк содержит такую бездну смысла, что её вообще мало кто осознать способен.
Видишь ли, процедурные языки типа шарпа или С немножко по-другому построены. Они больше похожи на стихи, чем на прозу.
bla = bla.Bla * bla + bla;
bla.Bla(bla.Bla 10, bla);
if (bla.Bla)
{
bla.Bla(1);
}
Видишь - если в форте, например, логических брейков вообще почти нет -- ну, типа, стек, всё такое, -- то здесь они видны невооружённым взглядом: каждая строчка - это одно какое-то действие, причём это действие может иметь достаточно большую длину. Вот тот пример, который ты рисовал - у тебя там максимальная длина действия - 8 символов, считая ";". В мире процедурных/ООП языков это 20-30 символов, а то и больше. Поэтому больше чем два действия на строчку вряд ли поместятся, а произвольное спаривание различных действий сбивает с ритма и мешает читать код.
И не нужно говорить, что процедурные языки сосут. Это не так.
Когда ты пишешь свой свободный код, ты пишешь его максимально запутанно, чтобы после тебя в нём никто не разобрался?
Ты честно считаешь, что можешь достать меня такими
дешёвыми приёмами, или ты честно забыл правописание?
> отступы вредны в функциональных языках,
Отступы полезны везде.
> Видишь ли, процедурные языки типа шарпа или С
> немножко по-другому построены.
> Они больше похожи на стихи, чем на прозу.
Они больше похожи на распечатку дизассемблера:
bla = bla.Bla * bla + bla;
bla.Bla(bla.Bla 10, bla);
if (bla.Bla)
{
bla.Bla(1);
}
Одно действие --- одна строка.
А то и больше.
> произвольное спаривание различных действий
> сбивает с ритма и мешает читать код.
Произвольная расстановка отступов мешает не меньше.
В твоём примере, условное исполнение является одним
логическим действием, а не четырьмя различными.
> И не нужно говорить, что процедурные языки сосут.
Я говорю, что ваша расстановка отступов --- ересь,
и не соответствует заложенным в язык свойствам.
---
A2: Потому что так завещал великий и мудрый Ибеме,
и по другому делать некошерно.
Оставить комментарий
margadon
тебе не надо хотеть узнать как пользоваться goto и есть ли он в PHP