OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Четверг, 28 Март, 2024 18:01

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 234 ]  На страницу Пред.  1, 2, 3, 4, 5, 6 ... 12  След.
Автор Сообщение
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 03:40 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Дмитрий Сурков писал(а):
В результате выполнения оператора RETURN могут начать выполняться побочные действия, например, FINALLY-секции операторов TRY.


Ну и пусть выполняются. Если эти действия начинают неправильно работать при "неожиданном" RETURN, то значит FINALLY используется не по назначению. Серьезно. Предназначение FINALLY секции четко определено - подчистка захваченных ресурсов. Если пытаться организовывать с помощью FINALLY более сложную логику - ничего хорошего не выйдет, независимо от наличия RETURN. Использование FINALLY подразумевает наличие исключений, а исключение может броситься в любом месте блока. Поэтому наличие внутри такого блока RETURN никаких дополнительных "неожиданностей" привнести уже не может.

Дмитрий Сурков писал(а):
Если разработчик на каком-то этапе решает добавить проверку пост-условия в свою процедуру, или послать уведомление о выполнении операции, то сделать это надежно, без сильного изменения логики процедуры, можно лишь в том случае, если в ней нет операторов RETURN.


1) Проверку пост-условий можно вынести в отдельную процедуру.
2) Некоторые языки позволяют сделать это явно или более другими способами, нежели явным ASSERT в конце функции.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 08:49 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Ага, вот чтобы "добавить... или послать...", не ломая плохо написанного кода, народ изобрёл аспектно-ориентированное программирование :-) :-) :-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 09:06 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1428
info21 писал(а):
Не как GOTO -- про RETURN всегда ясно, куда он прыгает.


GOTO тоже всегда известно куда прыгает - на соответствующую метку. ;-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 09:24 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Vlad писал(а):
...
Странная у вас логика. Никто никуда не прыгает, функция возвращает результат. С точки зрения вызывающего кода точка возврата одна. Вас не пугает оператор IF? Он тоже "прыгает" в ветку ELSE (которая в случае принципиального отказа от RETURN может оказаться довольно "далеко" и слабо различима на фоне кучи других вложенных IF).
...
Вот такая процедура (проверяет инварианты для записи и возвращает номер не выполняющегося). Пока у неё был булевский результат, я делал с RETURN в конце, правда были лишние проверки. Когда потребовалось вернуть код в виде целого - если реализовывать такую функцию с RETURN в конце - тут вложеность IF-в будет более 10. Такой код читать и понять гораздо сложнее, по крайней мере для меня.

Или есть возможность сделать принципиально по другому?
Код:
   PROCEDURE Check (IN rec: Record): INTEGER;
   BEGIN
      IF ~(rec.az.no >= 1) THEN RETURN 1 END;
      IF ~Dates.ValidDate(rec.az.date) THEN RETURN 2 END;
      IF ~Dates.ValidDate(rec.ddate) THEN RETURN 3 END;
      IF ~(rec.known - { lname..paddr } = { }) THEN RETURN 4 END;
      IF (lname IN rec.known) &
         ~((rec.lname # "") & Misc.HasSingleSpaces(rec.lname)) THEN RETURN 5 END;
      IF (fname IN rec.known) &
         ~((rec.fname # "" ) & Misc.HasSingleSpaces(rec.fname)) THEN RETURN 6 END;
      IF (mname IN rec.known) &
         ~((rec.mname # "" ) & Misc.HasSingleSpaces(rec.mname)) THEN RETURN 7 END;
      IF (bdate IN rec.known) &
         ~Dates.ValidDate(rec.bdate) THEN RETURN 8 END;
      IF (doc IN rec.known) THEN
         IF ~((rec.doc.s # "") & Misc.HasSingleSpaces(rec.doc.s)) THEN RETURN 9 END;
         IF ~((rec.doc.n # "") & ~Misc.HasSpaces(rec.doc.n)) THEN RETURN 10 END;
         IF ~Dates.ValidDate(rec.doc.d) THEN RETURN 11 END;
         IF ~((rec.doc.o # "") & Misc.HasSingleSpaces(rec.doc.o)) THEN RETURN 12 END
      END;
      IF (index IN rec.known) &
         ~((rec.resided.index # "") & ~Misc.HasSpaces(rec.resided.index)) THEN RETURN 13 END;
      IF (paddr IN rec.known) &
         ~((rec.resided.paddr # "") & Misc.HasSingleSpaces(rec.resided.paddr)) THEN RETURN 14 END;
      (* Зависимости между полями *)
      IF ~(Misc.CmpDates(rec.ddate, rec.az.date) <= 0) THEN RETURN 15 END;
      IF (doc IN rec.known) THEN
         IF ~(Misc.CmpDates(rec.doc.d, rec.ddate) <= 0) THEN RETURN 16 END;
         IF ~(Misc.CmpDates(rec.bdate, rec.doc.d) < 0) THEN RETURN 17 END;
      ELSE
         IF (bdate IN rec.known) &
            ~(Misc.CmpDates(rec.bdate, rec.ddate) <= 0) THEN RETURN 18 END;
      END;
      RETURN 0
   END Check;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 09:31 
Модератор
Аватара пользователя

Зарегистрирован: Среда, 16 Ноябрь, 2005 00:53
Сообщения: 4625
Откуда: Россия, Орёл
Евгений Темиргалеев писал(а):
Или есть возможность сделать принципиально по другому?

Гм...кажется я забыл про ELSIF.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 10:31 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Евгений Темиргалеев писал(а):
Или есть возможность сделать принципиально по другому?

Подобные вещи лучше писать процедурами, а не функциями, т.е. вообще без RETURN-ов:
Код:
PROCEDURE Check (IN rec: Record; OUT res: INTEGER);
BEGIN
  IF cond0 THEN res := res0
  ELSIF cond1 THEN res := res1
  ELSIF cond2 THEN res := res2
  ELSIF cond3 THEN res := res3
  ELSE res := default
  END
END Check;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 17:22 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Евгений Темиргалеев писал(а):
Или есть возможность сделать принципиально по другому?


В данном случае, как уже подсказали, замечательно работает ELSIF. Проблемы (вложенность) начинаются, когда каждая следующая проверка имеет обе ветки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 17:32 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Подобные вещи лучше писать процедурами, а не функциями, т.е. вообще без RETURN-ов:


Зачем? Чтобы RETURN не писать? ;) Или чтобы было очень удобно проверять результат такой "функции" (заводя дополнительную никому не нужную временную переменную)? ;)

P.S. Да, да, давайте уберем из Оберона RETURN. А что, жить можно, все будем возвращать через OUT параметры. Совершенно лишняя конструкция, да еще и по мнению некоторых "противоречит структурному программированию". Вирт и правда чего-то не доглядел, есть еще что обрезать, есть способ сделать компилятор еще проще, а язык еще менее человеческим ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 18:29 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Ума не приложу, чем может мешать единственный RETURN в конце функции?

При множественном использовании RETURN возникают проблемы с проверкой значений глобальных переменных и VAR параметров.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Вторник, 20 Ноябрь, 2007 18:37 

Зарегистрирован: Суббота, 12 Май, 2007 08:41
Сообщения: 102
Откуда: Беларусь, Минск
Valery Solovey писал(а):
Ума не приложу, чем может мешать единственный RETURN в конце функции?

Так в конце функции Вирт RETURN и оставил, его задача - возвращать значение функции, но не прерывать её выполнение где-то в середине. Об этом и речь.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 09:00 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Valery Solovey писал(а):
Ума не приложу, чем может мешать единственный RETURN в конце функции?


См. предыдущие сообщения.

Valery Solovey писал(а):
При множественном использовании RETURN возникают проблемы с проверкой значений глобальных переменных и VAR параметров.


Чего?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 09:10 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
kreol писал(а):
Так в конце функции Вирт RETURN и оставил, его задача - возвращать значение функции, но не прерывать её выполнение где-то в середине. Об этом и речь.


Для возврата значения только в конце функции достаточно чуть-чуть изменить синтаксис:
END <function name> <expression>;

Неужели Вирт упустил такую возможность избавиться от целого ключевого слова и придать еще больше строгости языку? ;) Или все-таки в данном случае здравый смысл победил в неравной борьбе за простоту языка и компилятора? ;)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 10:45 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 18:55
Сообщения: 2272
Откуда: Россия, Нижний Новгород
Vlad писал(а):
END <function name> <expression>;
...борьбе за простоту языка и компилятора? ;)

Это не упрощение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 10:46 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Vlad писал(а):
Или все-таки в данном случае здравый смысл победил в неравной борьбе за простоту языка и компилятора? ;)

На ключевых словах Вирт никогда не экономил, в отличие от ++{}>>->-ников :-)

Зато ни одного правильного компилятора ++-са нету :-D :-D


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 11:05 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Vlad писал(а):
Valery Solovey писал(а):
При множественном использовании RETURN возникают проблемы с проверкой значений глобальных переменных и VAR параметров.


Чего?
Что значит "Чего"? В смысле "Шо?!"?

Для того, чтобы проверить значение функции, в идеале достаточно прослеживать изменения только лишь возвращаемого значения. То есть, смотрим, какая переменная стоит после RETURN, и прослеживаем её изменения с начала подпрограммы. Но если в подпрограмме (процедуре или функции) изменяются какие-то внешние значения (глобальные переменные или VAR параметры), то приходится прослеживать и их значения, чтобы удостовериться в их корректности на момент выхода из подпрограммы по одному из множества ретурнов.

Я не говорю, что использование одного RETURN решит проблему, но, как я заметил, это подталкивает к более простому решению.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 16:47 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Сергей Губанов писал(а):
Vlad писал(а):
END <function name> <expression>;
...борьбе за простоту языка и компилятора? ;)

Это не упрощение.


По-моему, очень даже упрощение. Ну уж точно не усложнение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 17:06 

Зарегистрирован: Суббота, 26 Ноябрь, 2005 18:38
Сообщения: 1857
Valery Solovey писал(а):
Для того, чтобы проверить значение функции, в идеале достаточно прослеживать изменения только лишь возвращаемого значения. То есть, смотрим, какая переменная стоит после RETURN, и прослеживаем её изменения с начала подпрограммы.


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

Valery Solovey писал(а):
Но если в подпрограмме (процедуре или функции) изменяются какие-то внешние значения (глобальные переменные или VAR параметры), то приходится прослеживать и их значения, чтобы удостовериться в их корректности на момент выхода из подпрограммы по одному из множества ретурнов.


Я ж уже писал - используйте две процедуры. Например, основную работу делает вложенная процедура, ее результат проверяется и возвращается внешней.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 17:16 

Зарегистрирован: Среда, 29 Август, 2007 11:04
Сообщения: 91
Вариант похуже:
Код:
PROCEDURE Check(IN rec: Record): INTEGER;
VAR result: INTEGER
BEGIN
  IF cond0 THEN result := res0
  ELSIF cond1 THEN result := res1
  ELSIF cond2 THEN result := res2
  ELSIF cond3 THEN result := res3
  ELSE result := default
  END
  RETURN result
END Check;

Вариант получше:
Код:
PROCEDURE Check(IN rec: Record): INTEGER;
BEGIN
  IF cond0 THEN RESULT := res0
  ELSIF cond1 THEN RESULT := res1
  ELSIF cond2 THEN RESULT := res2
  ELSIF cond3 THEN RESULT := res3
  ELSE RESULT := default
  END
END Check;
Второй вариант основан на существовании псевдопеременной RESULT, таким образом процедура
Код:
PROCEDURE Check(IN rec: Record): INTEGER;
эквивалентна процедуре
Код:
PROCEDURE Check(IN rec: Record; OUT RESULT: INTEGER);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 17:21 
Администратор

Зарегистрирован: Вторник, 15 Ноябрь, 2005 01:14
Сообщения: 4695
Откуда: Россия, Орёл
Дмитрий Сурков писал(а):
Вариант получше:
Код:
PROCEDURE Check(IN rec: Record): INTEGER;
BEGIN
  IF cond0 THEN RESULT := res0
  ELSIF cond1 THEN RESULT := res1
  ELSIF cond2 THEN RESULT := res2
  ELSIF cond3 THEN RESULT := res3
  ELSE RESULT := default
  END
END Check;


А что делать в случае:
Код:
PROCEDURE Check(IN rec: Record): INTEGER;
BEGIN
  IF cond0 THEN RESULT := res0
  ELSIF cond1 THEN RESULT := res1
  ELSIF cond2 THEN RESULT := res2
  END
END Check;

:?:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Оберон-07
СообщениеДобавлено: Среда, 21 Ноябрь, 2007 18:15 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1538
Откуда: Беларусь, Минск
Vlad писал(а):
Valery Solovey писал(а):
Для того, чтобы проверить значение функции, в идеале достаточно прослеживать изменения только лишь возвращаемого значения. То есть, смотрим, какая переменная стоит после RETURN, и прослеживаем её изменения с начала подпрограммы.


А зачем? :) Это ж так не удобно - отслеживать изменения какой-то там переменной. Намного удобнее проверять результат каждой под-операции.
То есть, предлагаете скормить входные данные, сверить выходные данные с полученными вручную и в случае совпадения считать данный отрезок кода верным? Это не достаточное основание для того, чтобы считать код достоверным, всё зависит от его сложности. А сколько тестов надо? Пять будет много или мало? Чтобы ответить на данный вопрос, требуется анализ кода. Именно это я подразумевал: анализ кода с оглядкой на переменную, значение которой будем возвращать.
Vlad писал(а):
По-моему такой подход проистекает из другой проблемы - необходимости объявлять все переменные сразу и в одном месте. Отсюда боязнь, что по ходу дела в какую-нибудь переменную (например в ту, которая используется для возвращаемого значения) запишется что-то не то :)
Я постепенно исправляюсь в лучшую сторону, но раньше в моём коде был сущий бардак. Однако, случайно записать в результат что-то не то как-то не получалось даже тогда. Тут есть другая проблема: иногда, процедуры приходится делать большими с огромным числом отдельных переменных. Вот тогда единый блок объявления меня действительно раздражал. А как насчёт того факта, что признаком дурного тона при программировании на Си считается объявлять переменные где-либо не в начале подпрограммы? К тому же, объявления переменных, распределённые по всей подпрограмме, тоже создают проблемы.

Vlad писал(а):
Valery Solovey писал(а):
Но если в подпрограмме (процедуре или функции) изменяются какие-то внешние значения (глобальные переменные или VAR параметры), то приходится прослеживать и их значения, чтобы удостовериться в их корректности на момент выхода из подпрограммы по одному из множества ретурнов.


Я ж уже писал - используйте две процедуры. Например, основную работу делает вложенная процедура, ее результат проверяется и возвращается внешней.
Получается оригинальная динамическая проверка, которая иногда будет очень сказываться на производительности. А откуда уверенность, что внешняя процедура работает верно? Её тоже надо проверять. Причём, не факт, что она будет проще вложенной.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 234 ]  На страницу Пред.  1, 2, 3, 4, 5, 6 ... 12  След.

Часовой пояс: UTC + 3 часа


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

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


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2024, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB