Автор Тема: Чем Вирту WITH не угодил?  (Прочитано 87194 раз)

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #75 : Апрель 27, 2012, 10:08:44 pm »

Да нет никакой принципиальной дырки в WITH. Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами. Т.е., делать полноценную копию (и лучше даже с другим именем). Тогда не надо будет никаких специальный телодвижений в компиляторе. Я уже об этом говорил (не помню в личке с Ильей или на оборонкоре).
Гораздо проще   прекратить  треп про герметичность... как не соответствующий действительности - мне вот лично на нее  начхать, тем кто использует ББ  полагаю тоже... принципиальность этому вопросу придали коровцы... а те в свою очередь (боюсь ошибиться) - от статей учеников Вирта.

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #76 : Апрель 27, 2012, 10:10:14 pm »
Вообще сама идея, что одна и та же переменная в разных участках процедуры имеет разный тип - мягко говоря нездоровая (для статически типизированного ЯП).
Естественно, но вопрос в другом - см. выше.

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #77 : Апрель 27, 2012, 10:23:07 pm »
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
Беда в том, что это юзанье  вполне может быть и не явным - например, когда глобальный указатель и меняющие его тип процедуры определены в  стороннем  откомпилированном модуле - человек вызывающий эти процедуры может даже не знать о изменении фактического типа данных... просто вызывая в охране безобидную на вид документированную  процедуру DoSomething() без параметров или с параметрами не относящимися напрямую к охраняемому указателю.

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #78 : Апрель 28, 2012, 12:31:08 am »
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
Беда в том, что это юзанье  вполне может быть и не явным - например, когда глобальный указатель и меняющие его тип процедуры определены в  стороннем  откомпилированном модуле - человек вызывающий эти процедуры может даже не знать о изменении фактического типа данных... просто вызывая в охране безобидную на вид документированную  процедуру DoSomething() без параметров или с параметрами не относящимися напрямую к охраняемому указателю.

Если компилятор не будет реюзать переменную, то не важно, что делает DoSomething(). После каста в WITH на руках остается кастнутая ссылка (новая переменная) на оригинал. Так что с герметичностью все хорошо.

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #79 : Апрель 28, 2012, 05:42:02 am »
Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами.
Беда в том, что это юзанье  вполне может быть и не явным - например, когда глобальный указатель и меняющие его тип процедуры определены в  стороннем  откомпилированном модуле - человек вызывающий эти процедуры может даже не знать о изменении фактического типа данных... просто вызывая в охране безобидную на вид документированную  процедуру DoSomething() без параметров или с параметрами не относящимися напрямую к охраняемому указателю.

Если компилятор не будет реюзать переменную, то не важно, что делает DoSomething(). После каста в WITH на руках остается кастнутая ссылка (новая переменная) на оригинал. Так что с герметичностью все хорошо.
Ну нет,  так не пойдет... компилятор ДОЛЖЕН юзать то что ему пропишет программист руководствуясь алгоритмом.. а в языке четко прописан смысл понятий- глобальная переменная, и передача параметра по ссылке- я это к тому, что соответствующее изменение необходимо вносить в первую очередь в ЯП. Но даже в этом случае это не есть самое простое решение..  ;)  :D   ;D  вот Вирт, например, просто взял и удалил WITH из ЯП....  Ну как хорошо то -  вы можете назвать  с ходу реализацию от отцов- основателей языка свободную от этого недостатка (конечно, возможен такой вариант - им по барабану была герметичность раздутая до абсолюта некоторыми коровцами)? 

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Чем Вирту WITH не угодил?
« Ответ #80 : Апрель 28, 2012, 06:43:00 am »
vlad, вы меня опередили  :D

Мне вчера в голову пришла та же мысль. Для реализации безопасного WITH необходимо и достаточно делать копию указателя после проверки типа.

Внутри блока все разыменования должны происходить с копией указателя.

В конце блока можно по вкусу делать проверку на равенство типов у исходного указателя и копии. Либо проверять равенство указателей, т.к. исходный мог косвенно измениться. Это уже вопрос семантики WITH.

А можно еще запретить внутри блока явные присваивания охраняемому указателю(т.е. копии) и не делать никаких проверок в конце. Если исходный указатель косвенно изменился, ну и шут с ним. Это уже вопрос соглашений.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Чем Вирту WITH не угодил?
« Ответ #81 : Апрель 28, 2012, 06:44:32 am »
Уточнение:
Все мной сказанное конечно должен делать компилятор а не программист  ;)

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Чем Вирту WITH не угодил?
« Ответ #82 : Апрель 28, 2012, 07:00:27 am »
Кстати, можно пойти другим путем. Например как я уже говорил запретить передавать охраняемый указатель VAR и OUT параметром. Плюс везде запретить передавать глобальные переменные VAR параметром. Т.е. тут вопрос правильной расстановки запретов. Конечно тут доказать правильность посложнее, но если нужна максимальная эффективность, то почему бы и нет.

И я согласен с вами DIzer и vlad, проблема то большей частью в том, у кого откуда руки растут.  :)
Но ради справедливости хочу заметить, что в описании языка семантика WITH должна быть очень точно описана. Тогда разработчика можно ткнуть носом... чегой мол твоя реализация прописанную семантику не обеспечивает.

p.s. Если философски на все это посмотреть, то проблемы WITH отражают проблемы языка WIRTH'а вообще  ;D

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #83 : Апрель 28, 2012, 08:43:26 am »
vlad, вы меня опередили  :D

Мне вчера в голову пришла та же мысль. Для реализации безопасного WITH необходимо и достаточно делать копию указателя после проверки типа.

Внутри блока все разыменования должны происходить с копией указателя.

В конце блока можно по вкусу делать проверку на равенство типов у исходного указателя и копии. Либо проверять равенство указателей, т.к. исходный мог косвенно измениться. Это уже вопрос семантики WITH.

А можно еще запретить внутри блока явные присваивания охраняемому указателю(т.е. копии) и не делать никаких проверок в конце. Если исходный указатель косвенно изменился, ну и шут с ним. Это уже вопрос соглашений.
Это понятно.. но я говорю про другое... - вопрос о такой интерпретации ДОЛЖЕН быть декларирован языком... ибо принципиально он допускает работу с  глобальными переменными- а это значит, что ЛЮБОЕ изменение делается с непосредственно с  соответствующей ячейкой памяти - а тут на время выполнения охраняемой последовательности это правило нарушается...  к чему это может привести я не хочу обсуждать - сейчас Оберон позиционируется как  примитивный язык общего назначения смусорозборником -(ко всем дополнительным "достоинствам" его расписываемым коровцами у  меня веры нет, как впрочем и к ним самим), из этого следует, что формальная( именно формальная) область его использования ничем не ограничена.

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Чем Вирту WITH не угодил?
« Ответ #84 : Апрель 28, 2012, 08:55:10 am »
Дело в том, что семантически внутри WITH изменение типа охраняемого указателя невозможно по определению:
Цитировать
Оператор WITH выполняет операторную последовательность в зависимости от результата проверки типа и применяет охрану типа к каждому вхождению проверяемой переменной внутри операторной последовательности.
http://www.inr.ac.ru/~info21/cpascal/cp_report_1.4_rus.htm#9.11

Следовательно той же семантикой запрещено и косвенное изменение типа. Т.е. должно быть исключение времени выполнения.

На входе в WITH и на выходе из него тип должен быть одним и тем же. Как это реализовано дело десятое...
« Последнее редактирование: Апрель 28, 2012, 08:58:03 am от ilovb »

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #85 : Апрель 28, 2012, 09:04:44 am »
А вот этого мы и не наблюдаем... по этому и есть несоответствие определению  в существующих реализациях... что бы там Влад не говорил, а если сделать так как предлагает Влад - то это будет немного другой язык - правило о котором я говорил (одно из фундаментальных правил всех императивных языков) выше будет нарушаться . Естественно , я не говорю что оно плохое.. просто оно меняет язык и потенциально влияет на алгоритмы решения задач (ее отсутствие не является недостатком существующих реализаций компиляторов)
« Последнее редактирование: Апрель 28, 2012, 09:08:42 am от DIzer »

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #86 : Апрель 28, 2012, 09:12:25 am »
плохое - в смысле предложение Влада.. мне оно нравиться

DIzer

  • Гость
Re: Чем Вирту WITH не угодил?
« Ответ #87 : Апрель 28, 2012, 09:16:32 am »
хотя повторюсь.. я лично УВЕРЕН на 100%, что не заметил бы этой проблемы в своих приложениях даже с текущей реализацией KП.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Чем Вирту WITH не угодил?
« Ответ #88 : Апрель 28, 2012, 09:34:05 am »
Да нет никакой принципиальной дырки в WITH. Все что нужно - это перестать реюзать одну и ту же переменую (поинтер) с разными типами. Т.е., делать полноценную копию (и лучше даже с другим именем). Тогда не надо будет никаких специальный телодвижений в компиляторе. Я уже об этом говорил (не помню в личке с Ильей или на оборонкоре).
WITH p1: derived_p1: Derived1 DO

Где derived_p1 - локальная переменная с типом Derived1. С типом оригинальной переменной p1 ничего не происходит.

Гм. Я не уверен что эта модификация органично впишется в весь язык. Перепиши ка вот этот кусок кода:
(* Language: Oberon
   WithStatement  =  WITH qualident ":" qualident DO StatementSequence END *)

TYPE
    R0 = RECOR bar : INTEGER END
    R1 = RECORD (R0) foo : INTEGER END

PROCEDURE Foo(VAR x : R0);
BEGIN
    WITH x : R1 DO
        x.foo := 42;
    END
END Foo

PROCEDURE Test;
VAR
    x : R1
BEGIN
    Foo(x);
END Test
Как понимаешь, никаких указателей тут не фигурирует.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Чем Вирту WITH не угодил?
« Ответ #89 : Апрель 28, 2012, 09:45:28 am »
хотя повторюсь.. я лично УВЕРЕН на 100%, что не заметил бы этой проблемы в своих приложениях даже с текущей реализацией KП.
Аналогично