OberonCore https://forum.oberoncore.ru/ |
|
Почему программа должна быть структурной https://forum.oberoncore.ru/viewtopic.php?f=82&t=2348 |
Страница 4 из 8 |
Автор: | Сергей Губанов [ Понедельник, 15 Февраль, 2010 12:35 ] |
Заголовок сообщения: | Re: Песни партизан: "Ява после Оберона" |
А ещё ретурны из середины мешают "автоматическому рефакторингу" В MS VS C# есть такая фича: выделяешь мышью кусок процедуры, нажимаешь на правую кнопку мыши, выбираешь Refactor->Extract Method: Вложение: и этот кусок АВТОМАТИЧЕСКИ оформляется как отдельная процедура (имя процедуры вводишь в диалоговом окне появляющемся после нажатия на этот пункт меню). Так вот, если внутри куска кода есть return, break, continue, goto, то студия, разумеется, гневно ругается как-то так: дурачина ты простофиля, алл кодэ павз маст би терминайтэд... |
Автор: | Евгений Темиргалеев [ Понедельник, 15 Февраль, 2010 12:58 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Рэйлвэй Каген писал(а): Однако из-за этого ain-овскую запись нельзя называть проектной ошибкой. Она даже более эргономична, чем Ваша... Допустим. Однако, я бы не стал отождествлять крастоту записи с качеством проектных решений. Илья Ермаков писал(а): Свобода программиста ставить EXIT-ы ограничивается в силу того, что эта свобода ограничила бы свободу других (осуществлять ЗАКОННУЮ композицию этого блока). Перефразируя ранее упоминавшийся Ермаковым, если не ошибаюсь, пример про качество материала: применение позолоченных кирпичей, слепленных из песка, вместо обычных не может быть обосновано тем, что они блестят.
|
Автор: | Сергей Губанов [ Понедельник, 15 Февраль, 2010 13:08 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Berserker писал(а): В традиционном стиле писать проще. По ходу мыслей вырисовывается алгоритм. А чтобы написать более менее красивый вариант с разбиением большого кода на автономные части, без break-return-ов, нужно изрядно "попариться". Это с непривычки.Berserker писал(а): Функция получения очередного элемента выражения может вернуть ошибку. А почему бы их не совместить, то есть почему бы не расширить множество элементов дополнительным типом элемента "элемент-ошибка"? У меня сканер, например, может возвращать символ "Error". Алгоритм обработки упрощается: вместо двух аргументов - один.
|
Автор: | Рэйлвэй Каген [ Понедельник, 15 Февраль, 2010 13:24 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Евгений Темиргалеев писал(а): ..Однако, я бы не стал отождествлять крастоту записи с качеством проектных решений. Безусловно. Собственно из-за чего я и встрял в разговор - проектное решение(по схеме) можно считать правильным. Но текстовые реализации существенно разнятся:1. м.б.эргономичная(сразу понятная?), неуниверсальная, плохо рефакторится 2. универсальная, хорошо рефакторится, м.б.неэргономичная(заставляет прикладывать доп.усилия для понимания?) Вот и вопросы выползают: 1. обучать понятному, затем переводить на универсальное? 2. рефакторить из проектного уровня вместо уровня реализации? |
Автор: | Александр Шостак [ Понедельник, 15 Февраль, 2010 16:09 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Евгений Темиргалеев писал(а): Попробуйте. Если взять соответствующий язык, который не даст расслабляться Delphi, например. Ручное управление памятью определённо не даёт раслабиться )) Где-то ошибся - исключения или память утекает по мере работы. Цитата: А почему бы их не совместить, то есть почему бы не расширить множество элементов дополнительным типом элемента "элемент-ошибка"? У меня сканер, например, может возвращать символ "Error". Алгоритм обработки упрощается: вместо двух аргументов - один. Ничего не изменится, если ввести такой тип. В плане количества проверок в коде без break/return-ов. Впрочем, меня и текущий вариант не напрягает. Кроме того, таким образом унифицируется работа с функциями. В подпрограмме верхнего уровня я пишу: RESULT:=TExprExecutor.Execute(Expr, ResValue); IF RESULT = ERR_OK THEN ... END; Если произошла ошибка, то мне не нужно освобождать ResValue, ибо она будет NIL. В вашем случае мне придёт объект TError, который нужно будет вручную удалить. Определённо, в Обероне таких забот нет, а в делфи с числами (RESULT: INTEGER) работать безопаснее и удобнее. |
Автор: | Евгений Темиргалеев [ Понедельник, 15 Февраль, 2010 17:06 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Евгений Темиргалеев писал(а): Berserker писал(а): Лучше больше времени потратить на создание кода, чем отладку или доработку в будущем. Вполне возможно, что если взять за правило структурный стиль , то через какое-то время это войдёт в привычку. Попробуйте. Если взять соответствующий язык, который не даст расслабляться, то 100% через некоторое время Вы обнаружите, что так и есть.Berserker писал(а): Delphi, например. Ручное управление памятью определённо не даёт раслабиться )) Где-то ошибся - исключения или память утекает по мере работы. Уточню: я говорил о языке, который не даст нарушать структурный стиль. Под "расслабиться" подразумевалось забивание на структурном стиле, без привычки требующем определённых усилий.
|
Автор: | ain [ Понедельник, 15 Февраль, 2010 17:30 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Илья Ермаков писал(а): ain писал(а): Илья Ермаков писал(а): Выделено: viewtopic.php?p=42549#p42549 Вы использовали следующую композицию: if cond1 then A; if cond2 then B; if cond3 then C; … Зачем вы сделали подмену? У меня совсем иная конструкция. Код: if cond1 then Exit(A); if cond2 then Exit(B); if cond3 then Exit(C); Result := D; Я? Подмену?? Я подставил переменную вместо конкретного элемента. По синтаксису имеем "if" boolean_expr "then" block. То, что у Вас там частный случай, когда block состоит из одной операции Exit - это как раз Ваши проблемы. Единой отдельной конструкции if then Exit в языке нет. Вы сделали подмену. Смысловую. У меня стоит выход, с передачей вычисленного значения (функция в Exit), у вас вызов процедуры и продолжение выполнения - проверка следующих условий. Илья Ермаков писал(а): Может быть, я сбил с толку тем, что обозвал всё так же A, B, C? (хотя у вас там маленькие буквы). Замените на X, Y, Z - несущественно. Речь о том, что эти X, Y, Z не имеют права влиять на верхний блок управления, в который они встроены. Т.е. наличие и использование Exit - нелегально, с точки зрения проектной культуры. Нет, вы не сбиты с толку. Вы просто заменили мой пример, совсем иным - вашим. Евгений Темиргалеев писал(а): Код: if cond1 then Exit(A); Уточните (для меня) Exit(A) и Result := D - это случаем не RETURN A и RETURN D в КП? ... последнее что я про делфи/ТП помню -- Exit вроде без параметров была.... Result := D; Если так, то сравниваются не равноценные понятия -- способ записи (мат.) функции и способ построения алгоритма из блоков... Exit – сейчас в Delphi с параметром. Exit(A); эквивалентно Result=A; exit; Info21 писал(а): ain писал(а): Код: if cond1 then Exit(A); if cond2 then Exit(B); if cond3 then Exit(C); Result := D; Код: IF cond1 THEN A ELSIF cond2 THEN B ELSIF cond3 THEN C ELSE D END; RETURN Да, так приятней. Я всегда пишу именно в таком стиле. В смысле, со всякими выравниваниями. Вот скопировал прямо из программы как есть: Код: procedure TfBuy.vsPriceBuyGetText(Sender: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
var Data: PPrice; begin Data := Sender.GetNodeData(Node); CellText := ''; if not Assigned(Data) then Exit; if Data.Title then if Column = 0 then CellText := string(Data.Name) else else case Column of pbName: CellText := string(Data.Name); pbCount: CellText := IntToStr(Data.Count-Data.CountTMP); pbCost: CellText := IntToStr(Data.Cost); pbBall: CellText := IntToStr(Data.Ball); pbBallV: CellText := IntToStr(Data.BallV); end; end; |
Автор: | Евгений Темиргалеев [ Понедельник, 15 Февраль, 2010 18:03 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Код: Data := Sender.GetNodeData(Node); Правильно переписал (учитывая что сокращённые вычисления логич. операций в силе)?
if not Assigned(Data) or Data.Title and (Column # 0) then CellText := '' else if Data.Title and (Column = 0) then CellText := string(Data.Name) else case Column of pbName: CellText := string(Data.Name); pbCount: CellText := IntToStr(Data.Count-Data.CountTMP); pbCost: CellText := IntToStr(Data.Cost); pbBall: CellText := IntToStr(Data.Ball); pbBallV: CellText := IntToStr(Data.BallV); else CellText := '' или АВОСТ(неверный номер колонки)? end |
Автор: | Александр Шостак [ Понедельник, 15 Февраль, 2010 18:13 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Berserker писал(а): Уточню: я говорил о языке, который не даст нарушать структурный стиль. Под "расслабиться" подразумевалось забивание на структурном стиле, без привычки требующем определённых усилий. Даже КП под определение такого языка не подходят. Здесь есть и выходы из цикла (Loop) и RETURN-ы из произвольного места. Компилятор такж Евгений Темиргалеев писал(а): Правильно переписал (учитывая что сокращённые вычисления логич. операций в силе)? ain писал(а): if not Assigned(Data) then Exit;
|
Автор: | Александр Шостак [ Понедельник, 15 Февраль, 2010 19:26 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Размышляя над атомарностью операций пришёл к интересному решению для языков без сбора мусора. Есть переменная - владелец объекта, а есть - ссылки на объект. И первые и вторые имеют тип Объект. Причём владелец может храниться каким-нибудь i-ым элементом в списке. При удалении объекта, стоит ли явно обнулять все ссылки на него, даже если это приводит к дублированию кода (бесполезной нагрузке)? Сюда же относится и перемещение объекта в другую область (переменную/структуру) с последующем занулением оригинала. При этом сохраняется атомарность операций. Чтобы пояснить несколько сумбурно изложенное вышесказанное, приведу пример: Func:=TExprFunc(SubExpr[i]); ... RESULT:=Func.Handler(Args, Res); ... FreeAndNIL(Func); SubExpr[i]:=NIL; SubExpr[i]:=Res; Res:=NIL; Если один из аргументов подвыражения - функция, то она вызывается. Объект-функция освобождается, а на её место в список попадает результат её выполнения. Как видно из кода, SubExpr[i]:=NIL;SubExpr[i]:=Res - изыточно. Тем не менее, на каждой строке выражения атомарны. Если их разъеденить, ничего страшного не произойдёт. А вот если SubExpr:=NIL убрать, а перед SubExpr[i] добавить какой-то код, то есть опасность работы с мёртвым объектом в SubExpr[i]. |
Автор: | Евгений Темиргалеев [ Понедельник, 15 Февраль, 2010 21:37 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
ain писал(а): Код: if cond1 then Exit(A); Вот скопировал прямо из программы как есть:if cond2 then Exit(B); if cond3 then Exit(C); Result := D; Код: begin Data := Sender.GetNodeData(Node); CellText := ''; if not Assigned(Data) then Exit; if Data.Title then if Column = 0 then CellText := string(Data.Name) else else case Column of pbName: CellText := string(Data.Name); pbCount: CellText := IntToStr(Data.Count-Data.CountTMP); pbCost: CellText := IntToStr(Data.Cost); pbBall: CellText := IntToStr(Data.Ball); pbBallV: CellText := IntToStr(Data.BallV); end; end; 2) В нескольких местах неявное завершение приводит к одному и тому-же умолчальному результату. Навроде Код: if cond1 then Exit(A); Итого: схема эквивалентна варианту if - elsif - else - end (см. viewtopic.php?p=42832#p42832 и следующие два сообщения), а приведённый код нет.
if cond2 then Exit(B); if cond3 then Exit(A); |
Автор: | Илья Ермаков [ Понедельник, 15 Февраль, 2010 22:27 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
ain писал(а): Вы сделали подмену. Смысловую. У меня стоит выход, с передачей вычисленного значения (функция в Exit), у вас вызов процедуры и продолжение выполнения - проверка следующих условий. Я Вам про то и толкую. Что у Вас там стоит выход. А синтаксически ваш Exit является оператором более низкого ранга (вложенности), чем основные if. Поэтому я имею полное право в рассуждениях заменить его условным обозначением SomeOperator (чисто синтаксически). Так вот, суть в том, что я не желаю, чтобы этот SomeOperator имел возможность влиять на логику выполнения окружающего блока. Я хочу, чтобы я мог не думать, какой там SomeOperator, а полагаться исключительно на свойства цепочки if-ов. P.S. Вот блин; как, оказывается, остро стоит проблема "литературности". Видимо, мы не отдаём себе отчёт - а у людей-то в подкорке это отношение к программе, как к "тексту, объясняющему компьютеру, что надо делать". Полпары с новой группой сегодня специально посвятил разъяснениям природы подходов "сверху вниз", "снизу вверх", структуры и архитектуры систем, в сугубо инженерных категориях-терминах, чтобы заранее предотвратить формирование такого "литературного" стереотипа, а подготовить восприятие блочно-конструкционное. |
Автор: | Galkov [ Понедельник, 15 Февраль, 2010 23:52 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Илья Ермаков писал(а): P.S. Вот блин; как, оказывается, остро стоит проблема "литературности". Видимо, мы не отдаём себе отчёт - а у людей-то в подкорке это отношение к программе, как к "тексту, объясняющему компьютеру, что надо делать". Полпары с новой группой сегодня специально посвятил разъяснениям природы подходов "сверху вниз", "снизу вверх", структуры и архитектуры систем, в сугубо инженерных категориях-терминах, чтобы заранее предотвратить формирование такого "литературного" стереотипа, а подготовить восприятие блочно-конструкционное Отдаем Но от этого не легче. Все думают, что цель написания кода - работающая программа. А на самом деле - понимание (быстрое вхождение, остутствие волновых эффектах при внесении изменений, и т.п.) твоего кода другими людьми. А вовсе не компьютером. И объяснить это - невозможно. Только "через руки" (увольнение с работы, и т.п..) И тут - хучь в ухо мочись... Думаете, Ваша "новая группа" поверила Вам за пол-пары ??? НЕ ВЕРЮ |
Автор: | Илья Ермаков [ Вторник, 16 Февраль, 2010 00:04 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Ну, у них вообще ещё чистый лист в проф. плане... так что тут важно задать угол зрения на всё, что рассказывается. Чтобы не казалось, что препод буковки для компьютера пишет |
Автор: | AVC [ Вторник, 16 Февраль, 2010 02:25 ] |
Заголовок сообщения: | Re: Песни партизан: "Ява после Оберона" |
Илья Ермаков писал(а): Да, вот внезапно чётко понял, с примером, что меня раздражает в досрочном выходе. Мы ходим по кругу: viewtopic.php?f=73&t=1805&p=29996#p29996 IMHO, убедительных аргументов в пользу синтаксической (обязательной) привязки RETURN к концу процедуры-функции пока не появилось. Хотя, спора нет, единственный RETURN в конце функции - удачное решение во многих случаях. |
Автор: | ain [ Вторник, 16 Февраль, 2010 06:57 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Евгений Темиргалеев писал(а): Код: Data := Sender.GetNodeData(Node); Правильно переписал (учитывая что сокращённые вычисления логич. операций в силе)?if not Assigned(Data) or Data.Title and (Column # 0) then CellText := '' else if Data.Title and (Column = 0) then CellText := string(Data.Name) else case Column of pbName: CellText := string(Data.Name); pbCount: CellText := IntToStr(Data.Count-Data.CountTMP); pbCost: CellText := IntToStr(Data.Cost); pbBall: CellText := IntToStr(Data.Ball); pbBallV: CellText := IntToStr(Data.BallV); else CellText := '' или АВОСТ(неверный номер колонки)? end У, нет. По мне это некрасиво. 1.Если что не так, выходное значение должно быть пусто, потому для меня логично сделать это в самом начале и более не проверять. 2.Всякие совмещения проверок — для меня дурной тон. 3.По объему if и else у нас с вами паритет. 2(if)+3(else) у вас 3(if)+2(else) у меня. Но, у меня с лету всё понятно и ясно, даже мозг включать не нужно, чтобы сообразить. У вас даже три условия в одном if. В ваш текст нужно вчитываться и терять на это время и силы. Но, это лично мои предпочтения. |
Автор: | ain [ Вторник, 16 Февраль, 2010 07:27 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Илья Ермаков писал(а): ain писал(а): Вы сделали подмену. Смысловую. У меня стоит выход, с передачей вычисленного значения (функция в Exit), у вас вызов процедуры и продолжение выполнения - проверка следующих условий. Я Вам про то и толкую. Что у Вас там стоит выход. C маленьким нюансом — расчет и выход. Илья Ермаков писал(а): А синтаксически ваш Exit является оператором более низкого ранга (вложенности), чем основные if. Поэтому я имею полное право в рассуждениях заменить его условным обозначением SomeOperator (чисто синтаксически). Не можете. Exit – элемент управления ходом выполнения программы. Равно, как если бы вы сказали, вот тут у вас стоит GoTo, так я имею полное право заменить его условным обозначением SomeOperator. Поэтому вы, при переписывании моего примера, должны добавить ветки else, а не просто заменить exit на нечто. Илья Ермаков писал(а): Так вот, суть в том, что я не желаю, чтобы этот SomeOperator имел возможность влиять на логику выполнения окружающего блока. Я хочу, чтобы я мог не думать, какой там SomeOperator, а полагаться исключительно на свойства цепочки if-ов. Опираясь на ваши рассуждения, можно любую конструкцию заменить на SomeOperator. Тот же if. Илья Ермаков писал(а): P.S. Вот блин; как, оказывается, остро стоит проблема "литературности". Видимо, мы не отдаём себе отчёт - а у людей-то в подкорке это отношение к программе, как к "тексту, объясняющему компьютеру, что надо делать". Полпары с новой группой сегодня специально посвятил разъяснениям природы подходов "сверху вниз", "снизу вверх", структуры и архитектуры систем, в сугубо инженерных категориях-терминах, чтобы заранее предотвратить формирование такого "литературного" стереотипа, а подготовить восприятие блочно-конструкционное. Я лично пишу так, чтобы мне было как можно проще и понятней. Чем меньше нужно времени на понимание, что же именно происходит в данной процедуре, тем лучше программа для меня. В некоторых случаях важно и очень важны знания о том, как будет выполняться программа. |
Автор: | Info21 [ Вторник, 16 Февраль, 2010 09:16 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
Galkov писал(а): Думаете, Ваша "новая группа" поверила Вам за пол-пары ??? НЕ ВЕРЮ Студенты препода в несколько другом режиме слушают -- в режиме "это надо учить", и на так упорно сопротивляются, как уже-профессионалы. (Тут утверждение статистическое по ансамблю студентов.) |
Автор: | Info21 [ Вторник, 16 Февраль, 2010 09:18 ] |
Заголовок сообщения: | Re: Песни партизан: "Ява после Оберона" |
Рад видеть снова, Алексей Вячеславович. AVC писал(а): IMHO, убедительных аргументов в пользу синтаксической (обязательной) привязки RETURN к концу процедуры-функции пока не появилось. Есть такой общий принцип из которого следует, что в данном случае обосновывать надо вариативность, нарушающую структурность и вводящую вероятность ошибок. |
Автор: | Евгений Темиргалеев [ Вторник, 16 Февраль, 2010 10:16 ] |
Заголовок сообщения: | Re: Почему программа должна быть структурной |
ain писал(а): Евгений Темиргалеев писал(а): Правильно переписал (учитывая что сокращённые вычисления логич. операций в силе)? У, нет. По мне это некрасиво....Но, это лично мои предпочтения.2) Вопрос про соответствие кода-примера с общей схемой. viewtopic.php?p=42864#p42864 (записан более подробно) |
Страница 4 из 8 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |