Re[17]: Sqrt - хороший пример компонента обороняющегося от о
От: Курилка Россия http://kirya.narod.ru/
Дата: 10.12.05 12:59
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Я что-то переврал?

AVC>В приведенной цитате Макконнелла не содержалось совета использовать утверждения?

AVC>Или я отрицал важность статического контроля типов?

Речь у Сергея о динамических проверках, minorlogic же говорил, что они по смыслу не совпадают с нормальными статическими assert'ами, принятыми в других языках (насколько я это понял).
Ты же привёл как раз цитату о статических проверках, противопоставляя утверждению о них же по сути.
AVC>В чем претензия?
Претензия к неправомерности твоей претензии.
Re[17]: Sqrt - хороший пример компонента обороняющегося от о
От: Mikhail Polykovsky Россия http://glader.ru
Дата: 10.12.05 13:25
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Здравствуйте, Mikhail Polykovsky, Вы писали:



AVC>>>Стыд и позор также Стиву Макконелу за такие вот мысли:

AVC>>>

AVC>>>... Старайтесь преобразовывать семантические элементы интерфейса в програм-
AVC>>>мные, используя утверждения (assertions) или иными способами.


MP>>Есть практические рекомендации, как этого достигать? С примерами?


AVC>Да, есть.

AVC>См. главы 11 и 12 книги Мейера "Объектно-ориентированное конструирование программных систем".
AVC>Там вводится понятие Design By Contract (проектирование по контракту).
AVC>А одним из примеров в 12-й главе является как раз функция вычисления квадратного корня sqrt(x).

Статью про контрактное программирование читал. Еще что-нибудь интересное есть? Можете ссылку дать?
Re[18]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 10.12.05 14:10
Оценка:
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, AVC, Вы писали:


AVC>>Я что-то переврал?

AVC>>В приведенной цитате Макконнелла не содержалось совета использовать утверждения?

AVC>>Или я отрицал важность статического контроля типов?

К>Речь у Сергея о динамических проверках, minorlogic же говорил, что они по смыслу не совпадают с нормальными статическими assert'ами, принятыми в других языках (насколько я это понял).
К>Ты же привёл как раз цитату о статических проверках, противопоставляя утверждению о них же по сути.
AVC>>В чем претензия?
К>Претензия к неправомерности твоей претензии.

Вообще-то говоря, assert (=утверждать) — по определению связан именно с рантаймом.
Утверждение привязано к определенной точке выполнения программы.
Интересно, в каком же это языке иначе сделано?
Во всяком случае — не в Си/Си++.
Другое дело, что иногда компилятор может вычислить значение утверждения (оно константно).
Например, BlackBox отказывается компилировать следующий ASSERT:
  ASSERT(SIZE(INTEGER) # 4, 20);

и пишет: ASSERT fault.
Макконнелл же, ИМХО, призывает не оставлять интерфейсные семантические требования только в качестве благих пожеланий в документации, а вводить соответствующие им программные конструкции, например — ASSERT.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[18]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 10.12.05 21:43
Оценка:
Здравствуйте, Mikhail Polykovsky, Вы писали:

MP>Статью про контрактное программирование читал. Еще что-нибудь интересное есть? Можете ссылку дать?


Первое, что приходит в голову — упомянутый Сергеем Губановым BlackBox.
Там принцип программирования по контракту применяется "всерьез".
Вот пример из модуля Math:
    PROCEDURE ArcTan2* (y, x: REAL): REAL;
    BEGIN
        ASSERT((y # 0)  OR (x # 0), 20);
        ASSERT((ABS(y) # INF)  OR  (ABS(x)  # INF), 21);
        FLD(y); FLD(x); FATAN; WAIT; RETURN TOP()
    END ArcTan2;

Здесь где-то высказывалась мысль, что математические функции могли бы просто вернуть NaN. Дескать, ничего страшного.
Я с этой мыслью не согласен. (Хотя NaN и лучше, чем ошибочное значение, притворяющееся числом.)
AFAIK, на BlackBox написаны программы, производящие очень сложные и длительные вычисления. Некоторые из этих программ могут требовать нескольких месяцев вычислений. А теперь представьте себе, что Вы дождались и наконец получили долгожданный результат. И читаете: NaN.
Что Вы после этого скажете о программистах, не следующих принципу контрактного программирования?
Конечно, принцип программирования по контракту применяется не только в вычислительных задачах.
Вот другой простой пример: проход по списку. У Вас есть две функции: First и Next.
Предусловием цепочки вызовов Next является предварительный вызов First, инициализирующий итератор и присваивающий ему значение первого элемента в списке или NIL, если список пуст.
И т.д. и т.п.
Если Вас заинтресуют исходные тексты BlackBox (на предмет использования в них design-by-contract), то вот сайт Oberon Microsystems Inc.:
http://www.oberon.ch

Но я думаю, что этот принцип должен применяться значительно шире.
Предположу, что имеет смысл покопаться в исходниках стандартных библиотек Си++ и др. языков. Наверняка там обнаружится большое количество исключений, выбрасываемых в случае нарушения контракта клиентом.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[9]: Почему нельзя отключать ASSERT-ы в релизе
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 11.12.05 11:24
Оценка:
Здравствуйте, Сергей Губанов, Вы писали:

MS>>А что произойдет если компоненту передать неправильные аргументы?

MS>>Идеальный (с моей точки зрения) компонент вернет с помощью того или иного механизма ошибку, а клиент компонента вправе сам решать что ему делать в этом случае — падать или продолжать работать.

Поддерживаю

MS>>Оставляя ASSERT в компоненте программа аварийно завершится по инициативе компонента.

MS>>Вы считаете это правильным?

Только если вы автор и клиента и компоненты. Хотя это все равно неправильно.

СГ>Так ведь об этом-то и речь! Против неправильных данных передаваемых внутрь компонента стоит именно ASSERT. Это потому, что в интерфейсе к компоненту чётко прописано какие данные в него передавать можно. В функцию Sqrt можно передавать только неотрицательные числа. В качестве индекса массива можно использовать только число из соответствующего диапазона. Делить на ноль нельзя и т.д. Если программа всё-таки позволяет себе передавать отрицательное число в Sqrt, неправильный индекс массива, собирается разделить на ноль и т.д., то значит программа — ошибочна — получи ассертом по башке и иди ищи ошибку.


Мощно, однако. Особенно, когда речь идет про невизуальные компоненты, работающие в невизуальном клиенте. Типа OLEDB провайдера в MSSQL сервере, обслуживающем промышленную базу данных. Тебе потом за этот assert клиенты такой ... вломят — "мама не горюй"

СГ>ASSERT — оборона одного компонента от других: тот кто собирается не правильно использовать этот компонент — жестоко поплатится за это.


Поплатится тот, кто не понимает разницы между внутренними ошибками компоненты и ошибками, связанными с неправильным использованием.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[7]: Почему нельзя отключать ASSERT-ы в релизе
От: pvgoran Россия  
Дата: 11.12.05 11:51
Оценка:
Здравствуйте, Кодёнок, Вы писали:

>>> Что должна делать программа марсохода при обнаружении _внутренней

>>> ошибки_ на Марсе, когда ASSERT отключен (а ошибка не отключена)?

C>>Перезагружать систему, после N перезагрузок входить в безопасный режим.


Кё>...командировать специалиста...


Шутки — шутками, а один из "ненаших" сторонников Лиспа, насколько я помню, где-то писал про "незабываемые впечатления от использования REPL, работающего где-то там на расстоянии N километров". REPL использовался для отладки/исправления ошибок, естественно.
... << RSDN@Home 1.1.4 stable rev. 510>>
Re[15]: Sqrt - хороший пример компонента обороняющегося от о
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 11.12.05 12:48
Оценка: +1
Здравствуйте, AVC, Вы писали:

M>>3. Стыд разработчикам , что они использовали такое узнаваемое слово как "ASSERT" в ключе отличном от общепринятого.


AVC>Стыд и позор также Стиву Макконелу за такие вот мысли:

AVC>По мере возможности делайте интерфейсы программными, а не семан-
AVC>тическими Каждый интерфейс состоит из программной и семантической
AVC>частей. Первая включает типы данных и другие атрибуты интерфейса, которые могут
AVC>быть проверены компилятором. Вторая складывается из предположений об ис-
AVC>пользовании интерфейса, которые компилятор проверить не может.
AVC> Старайтесь преобразовывать семантические элементы интерфейса в програм-
AVC>мные, используя утверждения (assertions) или иными способами.


Дык надо различать понятие внешних и внутренних интерфейсов.

Во внутренних, в случае ошибки входящих параметров, что хочешь, то и делай — хоть в трубу дуди, хоть приложение терминируй. Ибо это связано с некорректной "внутренней" работой компоненты. Которая, вообще говоря, проверяется во время разработки всякими извращенческими автоматизированными тестами.

А вот параметры внешних интерфейсов, извольте проверять без вот этих крайностей. Поскольку трубу могут не услышать. А за терминирование могут сразу дать по башке. Правильно, не правильно — это потом разбираться будут.

Более того, кто писал компоненты для DCOM, тот обычно прорюхивает еще одно правило внешних интерфейсов — сначало проинициализируй OUT-параметры, а уж потом проверяй IN-параметры и возвращай всякие там коды ошибок.

Кстати еще один замечательный пример — компонент может использоваться в дизайнере. И что — если юзер (ну программер, то есть), указал в инспекторе не то значение — нам всю студию закрывать что ли? Типа "ах ты, негодяй такой, а еще программировать лезешь!"
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[16]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 11.12.05 22:32
Оценка:
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Дык надо различать понятие внешних и внутренних интерфейсов.


Если можно, уточните, что Вы понимаете под внутренними и внешними интерфейсами.
На всякий случай скажу, что принцип проектирования по контракту не применяется к операциям ввода/вывода.

КД>Кстати еще один замечательный пример — компонент может использоваться в дизайнере. И что — если юзер (ну программер, то есть), указал в инспекторе не то значение — нам всю студию закрывать что ли? Типа "ах ты, негодяй такой, а еще программировать лезешь!"


ASSERT не ведет к "терминированию" BlackBox.
Думаю, что и для других программ "терминирование" необязательно.

ИМХО, Сергей Губанов затронул очень серьезную тему: что делать, если обеспечить корректную работу компонента в сложившихся обстоятельствах невозможно.
(Единственное критическое замечание, которое я могу сделать: ИМХО, он слишком много раз употребил выражение "дать по башке". Создается впечатление, что ПО — это война всех против всех, а компонент компоненту — волк. )
Кроме прочих причин невозможности обеспечить корректную работу компонента, назову две.
1) Ограничения реализации. Вам надо получить сумму X и Y, а у Вас случилось переполнение. Такая жалость!
2) Частичные функции. Функция применима не ко всем сочетаниям элементов входных множеств.
Простые примеры:
— sqrt(x) неприменима к случаю x < 0:
— inv(x) = 1/x неприменима к случаю x = 0.
В основном, тема, затронутая Сергеем, относится ко второму случаю.
Подчеркну, что (ИМХО) причина этой ситуации не может быть устранена полностью, т.к. здесь мы упираемся в математический факт. А именно — существование частичных функций.
Думаю, что существует не единственный способ бороться с этой бедой.
Например, на здешних форумах сторонники Си++ не раз приводили примеры классов, гарантирующих некоторые свойства своих объектов. Например, класс реализует указатель и гарантирует, что он — ненулевой.
Я с интересом читаю подобные посты, но мне кажется, что подобный "укрепленный" код не слишком читабелен. (Здесь — жирное ИМХО, конечно.)
На мой взгляд, ASSERT (или другое синтаксическое средство проверки утверждений), проверяющие предусловия подпрограммы (метода) — проще. И потому предпочтительнее в использовании.

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[17]: Sqrt - хороший пример компонента обороняющегося от о
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 12.12.05 07:20
Оценка:
Здравствуйте, AVC, Вы писали:

КД>>Дык надо различать понятие внешних и внутренних интерфейсов.


AVC>Если можно, уточните, что Вы понимаете под внутренними и внешними интерфейсами.


Если уточнять на конкретном примере, то COM-интерфейсы — относятся к категории внешних. А интерфейс, например, std::vector — к категории внутренних. По крайней мере — в моей голове именно такое представление об устройстве мира.

AVC>ИМХО, Сергей Губанов затронул очень серьезную тему: что делать, если обеспечить корректную работу компонента в сложившихся обстоятельствах невозможно.


Компонентная технология сама по себе тема серьезная. И компромиссы с реальной практикой здесь играют не последнюю роль.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[15]: Sqrt - хороший пример компонента обороняющегося от о
От: minorlogic Украина  
Дата: 12.12.05 08:44
Оценка: +1
Здравствуйте, AVC, Вы писали:


AVC>Стыд и позор также Стиву Макконелу за такие вот мысли:


Да,нет , наоборот . Все вроде нормально сказанно. В чем вы увидели недостаток этого кучка текста ? И главное где там и что про асерты в релизе говорится ?
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[19]: Sqrt - хороший пример компонента обороняющегося от о
От: Курилка Россия http://kirya.narod.ru/
Дата: 12.12.05 08:49
Оценка:
Здравствуйте, AVC, Вы писали:

AVC>Здравствуйте, Курилка, Вы писали:


К>>Претензия к неправомерности твоей претензии.


AVC>Вообще-то говоря, assert (=утверждать) — по определению связан именно с рантаймом.

На основаниии чего ты такое утверждаешь?
Чем утверждение времени компиляции не утверждение?
Прочитай ещё раз приведённую тобой цитату и покажи — где там рантайм есть? (про компилятор я тебе уже показывал)
Re[15]: Sqrt - хороший пример компонента обороняющегося от о
От: minorlogic Украина  
Дата: 12.12.05 08:53
Оценка: +1
Кратко о C/C++:
Assert — с которым я знаком это элемент контроля ошибок ПРОГРАММИСТА а не программы.
У программы есть свои методы контроля, исключения к примеру, коды ошибок.

И большая неразбериха возникнет если путать инструменты и использовать их не по назначению.
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[10]: Почему нельзя отключать ASSERT-ы в релизе
От: Сергей Губанов Россия http://sergey-gubanov.livejournal.com/
Дата: 12.12.05 09:59
Оценка: -1
Здравствуйте, Коваленко Дмитрий, Вы писали:

КД>Поплатится тот, кто не понимает разницы между внутренними ошибками компоненты и ошибками, связанными с неправильным использованием.


Ваша мысль в той или иной форме здесь уже многократно высказывалась. И я на неё уже отвечал (в той или иной форме). Потрудитесь сначала прочитывать все сообщения...
Re[19]: Sqrt - хороший пример компонента обороняющегося от о
От: MShura  
Дата: 12.12.05 16:05
Оценка:
AVC>Здесь где-то высказывалась мысль, что математические функции могли бы просто вернуть NaN. Дескать, ничего страшного.
AVC>Я с этой мыслью не согласен. (Хотя NaN и лучше, чем ошибочное значение, притворяющееся числом.)
AVC>AFAIK, на BlackBox написаны программы, производящие очень сложные и длительные вычисления. Некоторые из этих программ могут требовать нескольких месяцев вычислений. А теперь представьте себе, что Вы дождались и наконец получили долгожданный результат. И читаете: NaN.
Если в документации к Sqrt написано, что в случае ошибки она вертает NaN, а вы никогда результат не проверяете, то виноваты будете именно вы.
Re[20]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 12.12.05 23:48
Оценка: 15 (1)
Здравствуйте, MShura, Вы писали:

AVC>>Здесь где-то высказывалась мысль, что математические функции могли бы просто вернуть NaN. Дескать, ничего страшного.

AVC>>Я с этой мыслью не согласен. (Хотя NaN и лучше, чем ошибочное значение, притворяющееся числом.)
AVC>>AFAIK, на BlackBox написаны программы, производящие очень сложные и длительные вычисления. Некоторые из этих программ могут требовать нескольких месяцев вычислений. А теперь представьте себе, что Вы дождались и наконец получили долгожданный результат. И читаете: NaN.
MS>Если в документации к Sqrt написано, что в случае ошибки она вертает NaN, а вы никогда результат не проверяете, то виноваты будете именно вы.

Совершенно согласен.
Допустим, я всегда проверяю значение, возвращаемое функцией sqrt, на предмет, является ли оно числом.
Значит ли это, что теперь я могу спокойно "подсовывать" этой функции отрицательный аргумент, не утруждая себя проверкой его на неотрицательность?
И разве следующий код
    y = sqrt(x);
    if (IsNaN(y)) { ... }

лучше, чем
    if (x >= 0.0)
        у = sqrt(x);
    else { ... }

?
(Разумеется, есть куча ситуаций, когда необходимо проверять возврат функции: открытие файла, запрос памяти в куче с помощью malloc etc. Но есть ситуации, где клиенту надо проверить корректность аргументов вызываемой функции. О них и идет речь.)
Клиент должен отвечать не только за корректность аргументов вызываемых функций, но и за
— корректность значения индекса элемента массива;
— предотвращение переполнения при выполнении арифметической операции;
— корректное (например — ненулевое) значение указателя и т.д и т.п.
Во всех этих случаях не предусмотрено специального значения "ошибка", а происходит исключение (в лучшем случае) или ошибка остается незамеченной, что можно привести к непредсказуемым последствиям (в худшем).

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[20]: Sqrt - хороший пример компонента обороняющегося от о
От: AVC Россия  
Дата: 13.12.05 00:24
Оценка: 6 (1)
Здравствуйте, Курилка, Вы писали:

К>Здравствуйте, AVC, Вы писали:


AVC>>Здравствуйте, Курилка, Вы писали:


К>>>Претензия к неправомерности твоей претензии.


AVC>>Вообще-то говоря, assert (=утверждать) — по определению связан именно с рантаймом.

К>На основаниии чего ты такое утверждаешь?

На основании того, что есть такое понятие — мониторинг утверждений.
И того, что assert() в Си/Си++ в случае невыполнения утверждения вызывает abort().
Вызывать abort() необязательно (это крайность), но согласись, что вызов abort() имеет смысл только для рантайма.
Не компилятор же будет терминироваться.

К>Чем утверждение времени компиляции не утверждение?


Частный (вырожденный) случай утверждения.

К>Прочитай ещё раз приведённую тобой цитату и покажи — где там рантайм есть? (про компилятор я тебе уже показывал)


Покажи, где его там нет.
Приведи пример осмысленного использования assertion в твоем понимании.
Вот Сергей Губанов привел такой пример:
PROCEDURE Sqrt(x: REAL): REAL;
BEGIN
  ASSERT(x >= 0.0, 20);

Хороший это пример или плохой, наверное, можно спорить.
Но он осмысленный.
А вот вы на пару с minorlogic пока кроме особо изысканного
assert(sizeof(int) == 32); /* почему именно 32, я не понял */

ничего путного пока не предложили (имхо, конечно ).

Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.

Хоар
Re[6]: Почему нельзя отключать ASSERT-ы в релизе
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.12.05 01:52
Оценка: :)
Здравствуйте, Кодёнок, Вы писали:

Мужики, не спорьте. У меня друг только что приехал из европы и он говорит, что там теперь модно делать так:
if (!CloseHandle(...))
    throw InvalidHandleException("Все козлы! Жизнь не удалась с самого утра :(!");

Ну, нормальные пацаны ваще вот так лабают:
string[] lines = File.ReadAllLines();


... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Почему нельзя отключать ASSERT-ы в релизе
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.12.05 02:16
Оценка: :)
Здравствуйте, 0rc, Вы писали:

0rc>А если ASSERT включен на Марсе, что тогда, легче будет?


Ещё бы! Сейчас не те времена! Залезаем на марсоход через терминалку и жмем "Ignore". А если писать код на интерпретаторе или на языке поддерживющем модификаци кода без перекомпиляции, то ваще жмем "Retry" и правим код!
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Почему нельзя отключать ASSERT-ы в релизе
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.12.05 02:16
Оценка:
Здравствуйте, Alex Fedotov, Вы писали:

Какие люди в Голиваде?

AF>ASSERT проверяет условие, которое истинно всегда. Если вы уже знаете, что вы не контролируете входные данные и они могут быть недействительными, то ASSERT, очевидно, для этого не подходит. Вместо этого там должна быть полноценная проверка аргументов, с возвратом кодов ошибок, выбрасыванием исключений, и т.д, и все это является частью интерфейса вашего компонента.


А может пусть компилятор выкидывает проверки не имеющие смысла и выносит их из критичных мест повыше? А мы просто всегда будем с "выбрасыванием исключений" жить?

Не, ну, кто гарантирует, что тот же выход за пределы массива не возникнет именно в релизе?

AF>С другой стороны, если я в release версии своего компонента оставлю все ASSERTs, и в один прекрасный момент вы обнаружите, что срабатывает ASSERT где-то на двенадцатом уровне вызовов, чем вам это поможет?


Исключине поможет всегда.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[3]: Почему нельзя отключать ASSERT-ы в релизе
От: VladD2 Российская Империя www.nemerle.org
Дата: 13.12.05 02:16
Оценка:
Здравствуйте, AVC, Вы писали:

Д>>про это еще Страуструп говорил

Д>>примененять защитные проверки в debug конфигурации и отключать их в release — это всё равно что плавать на корабле с полным набором спасательных кругов и шлюпок возле берега, и сгружать их на берег перех выходом в открытое море.

AVC>Да-да, еще Страуструп.

AVC>А до Страуструпа — еще Хоар.

Ага. Еще царь такой то в таком то году говаривал "я вас баяре на сквозь вижу я вас бояре...". Так что и шлюпки тоже на нас запишите, плиз.
... << RSDN@Home 1.2.0 alpha rev. 620>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.