Здравствуйте, Mr.Cat, Вы писали:
MC>Я это понял как согласие с тем, что детерминированная финализация в языках без uniqueness-типов возможна только в самых простых случаях.
Нет. Это о том что решение проблем неформальными механизмами это очень простой способ отстрелить себе голову.
MC>Тут ты пожалуй прав. Сами по себе континуации и сими по себе uniqueness плохо сочетаются.
Продолжения вообще с детерминированной финализацией не совместимы.
Просто в случае с uniqueness-типами ты получишь по голове во время компиляции, а в случае с try/finally во время исполнения.
MC>Но из этого только следует то, что компилятор должен знать о контунцациях.
Гм. А компилятор языка с продолжениями вообще может не знать о продолжениях?
Или даже так: Может ли компилятор языка не знать о какой бы то ни было фиче языка который он компилирует?
MC>Например, можно встроить поддержку delimited continuations, которые позволяют ограничить захватываемую континуацию.
О! Пошли ограничения. delimited continuations действительно можно засунуть в ту часть программа которая не общается с внешним миром.
Еще можно использовать escape-only continuations которые по сути исключения вид в профиль.
Вопрос лишь в том, а оно нужно? Учти что придется под них наворачивать систему типов, а она если говорить о языке удобном для практического использования и так получается весьма кучерявой.
MC>Также, я полагаю, в некоторых случаях можно доказать, что континуация, захваченная с call/cc вызывается не более одного раза.
А это уже получается корутина... совсем другой зверь.
MC>Ну на концептуальном-то уровне все понятно. Просто я ни разу не писал на языках с uniqueness. А дьявол-то наверняка в деталях.
uniqueness-типы это лучший из известных мне способов контролировать ресурсы. Он очевидно более гибкий чем try/finally и деструкторы С++. И его нельзя использовать не правильно. Программа просто не скомпилируется.
Что касается практики использования то: Ты на С++ писал? std::auto_ptr знаешь? Вот это оно самое и есть. Только не формализовано и интерфейс дырявый. На практике std::auto_ptr обычно используется когда нужно выпустить объект из функции (внутри функции справляются обычные дуструкторы) и при этом не потерять гарантии его удаления.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
MC>>Ну на концептуальном-то уровне все понятно. Просто я ни разу не писал на языках с uniqueness. А дьявол-то наверняка в деталях. WH>uniqueness-типы это лучший из известных мне способов контролировать ресурсы. Он очевидно более гибкий чем try/finally и деструкторы С++. И его нельзя использовать не правильно. Программа просто не скомпилируется.
А как делать разделяемое владение в твоей схеме?
Всё равно кроме счётчиков ссылок ничего не придумывается, со всеми их недостатками.
Здравствуйте, Cyberax, Вы писали:
C>А как делать разделяемое владение в твоей схеме?
Ты мне лучше скажи какую задачу ты решаешь.
А потом я тебе скажу как ее решить.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>А как делать разделяемое владение в твоей схеме? WH>Ты мне лучше скажи какую задачу ты решаешь. WH>А потом я тебе скажу как ее решить.
Не, понятно что всегда разделяемый ресурс можно на уровень выше вынести и сделать его уникальным. Только это иногда ведёт к тому, что ресурсы выносятся на самый верх. У region inference (для управления памятью) проблема с этим есть как раз, и решается как раз полумерами в виде счётчиков.
Здравствуйте, Cyberax, Вы писали:
WH>>Ты мне лучше скажи какую задачу ты решаешь. WH>>А потом я тебе скажу как ее решить. C>Не, понятно что всегда разделяемый ресурс можно на уровень выше вынести и сделать его уникальным. Только это иногда ведёт к тому, что ресурсы выносятся на самый верх. У region inference (для управления памятью) проблема с этим есть как раз, и решается как раз полумерами в виде счётчиков.
Ты на вопрос пожалуйста ответь.
А то у меня есть сомнения что разделяемые ресурсы вообще нужны.
Я вот что-то не могу вспомнить ни одного случая из моей практики когда был нужен разделяемый ресурс.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>Не, понятно что всегда разделяемый ресурс можно на уровень выше вынести и сделать его уникальным. Только это иногда ведёт к тому, что ресурсы выносятся на самый верх. У region inference (для управления памятью) проблема с этим есть как раз, и решается как раз полумерами в виде счётчиков. WH>Ты на вопрос пожалуйста ответь.
К примеру, логгер пишущий в файл, который должен жить пока не закроется последняя ссылка на него.
Или случай, когда временем жизни управляет внешняя система (графическое окно, к примеру).
WH>А то у меня есть сомнения что разделяемые ресурсы вообще нужны. WH>Я вот что-то не могу вспомнить ни одного случая из моей практики когда был нужен разделяемый ресурс.
У меня есть примеры, но пока не могу придумать простой случай, где всё было бы понятно.
Здравствуйте, Cyberax, Вы писали:
C>К примеру, логгер пишущий в файл, который должен жить пока не закроется последняя ссылка на него.
Лично я давно пришел к выводу что временем жизни логера и ему подобных компонентов гораздо проще и надежнее управлять явно.
C>Или случай, когда временем жизни управляет внешняя система (графическое окно, к примеру).
Вот окно и будет жить в другом процессе (они у нас дешевые типа ерланговских) а с окном мы будет разговаривать через типизированный канал типа тех что в сингулярити.
В данном случае нашим ресурсов будет конец этого канала. Шарить его нет никакого смысла.
C>У меня есть примеры, но пока не могу придумать простой случай, где всё было бы понятно.
А может когда ты доведешь до состояния "все понятно" то будет понятно что никаких разделяемых ресурсов и не надо было?
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>К примеру, логгер пишущий в файл, который должен жить пока не закроется последняя ссылка на него. WH>Лично я давно пришел к выводу что временем жизни логера и ему подобных компонентов гораздо проще и надежнее управлять явно.
Ну вот так оно и получается.
C>>Или случай, когда временем жизни управляет внешняя система (графическое окно, к примеру). WH>Вот окно и будет жить в другом процессе (они у нас дешевые типа ерланговских) а с окном мы будет разговаривать через типизированный канал типа тех что в сингулярити. WH>В данном случае нашим ресурсов будет конец этого канала. Шарить его нет никакого смысла.
А разница-то? Для твоего кода время жизни соединения с окном будет непредсказуемо. Особенно, если это не диалог, а основное окно приложения.
C>>У меня есть примеры, но пока не могу придумать простой случай, где всё было бы понятно. WH>А может когда ты доведешь до состояния "все понятно" то будет понятно что никаких разделяемых ресурсов и не надо было?
Они всё равно есть и будут, пока у нас есть реальный мир — он разделяемый между всеми.
Здравствуйте, Cyberax, Вы писали:
WH>>Лично я давно пришел к выводу что временем жизни логера и ему подобных компонентов гораздо проще и надежнее управлять явно. C>Ну вот так оно и получается.
А оно в любом случае именно так и получается.
Иначе свихнешься.
C>А разница-то? Для твоего кода время жизни соединения с окном будет непредсказуемо. Особенно, если это не диалог, а основное окно приложения.
Что значит не предсказуемо?
C>Они всё равно есть и будут, пока у нас есть реальный мир — он разделяемый между всеми.
Понеслась...
Твоя методика фигня по тому что есть случае которые туда не вписываются.
Какие?
Не скажу. Но они есть и твоя методика фигня.
Вот к этому у нас сводятся все разговоры.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали: WH>Нет. Это о том что решение проблем неформальными механизмами это очень простой способ отстрелить себе голову.
Ну я про то и говорю. Неформальный механизм try/finally даже в сишарпе с лямбдам не является серебряной пулей.
WH>Продолжения вообще с детерминированной финализацией не совместимы.
Пока, как я понял, под этим ты понимаешь: "Продолжения несовместимы с зависимыми типами, которые гарантируют, что время владения ресурсом совпадает со временем использования".
Так вот я с этим не согласен.
WH>Просто в случае с uniqueness-типами ты получишь по голове во время компиляции, а в случае с try/finally во время исполнения.
Стоп. Способов получить по голове во время исполнения — вагон и маленькая тележка. Я так понял, мы тут обсуждаем способы не получить во время исполнения.
MC>>Но из этого только следует то, что компилятор должен знать о контунцациях. WH>Гм. А компилятор языка с продолжениями вообще может не знать о продолжениях? WH>Или даже так: Может ли компилятор языка не знать о какой бы то ни было фиче языка который он компилирует?
Зависит от того, как фича реализована. Континуации можно приделать, если произвести над кодом cps-преобразование до проверки типов и добавить в библиотеку функцию call/cc. Т.е. континуации типам будут ортогональны. А можно ввести примитивы shift и reset (для delimited continuations), а то и сам call/cc, о которых известно системе типов.
WH>О! Пошли ограничения.
А что ты хотел? Впихнуть садистскую систему типов в язык — и чтобы ничего не поменялось?
WH>delimited continuations действительно можно засунуть в ту часть программа которая не общается с внешним миром.
Ну по крайней мере не держит ссылок на ресурсы.
WH>Учти что придется под них наворачивать систему типов, а она если говорить о языке удобном для практического использования и так получается весьма кучерявой.
Ну это неспортивно. Сперва объявить, что некоторая система типов лучше других, а потом объявить, что некоторая фича Х не нужна, потому что в этой системе типов реализуется слишком сложно.
MC>>Также, я полагаю, в некоторых случаях можно доказать, что континуация, захваченная с call/cc вызывается не более одного раза. WH>А это уже получается корутина... совсем другой зверь.
Это может быть что угодно. Возможностью несколько раз вызывать континуацию не так уж часто приходится пользоваться.
Здравствуйте, WolfHound, Вы писали:
C>>Ну вот так оно и получается. WH>А оно в любом случае именно так и получается. WH>Иначе свихнешься.
А таки в С++ я могу использовать счётчик ссылок и всё ОК.
C>>А разница-то? Для твоего кода время жизни соединения с окном будет непредсказуемо. Особенно, если это не диалог, а основное окно приложения. WH>Что значит не предсказуемо?
Время жизни объекта не совпадает с лексическим диапазоном.
WH>Твоя методика фигня по тому что есть случае которые туда не вписываются. WH>Какие? WH>Не скажу. Но они есть и твоя методика фигня.
Ну вот, такой пример:
void someFunc(resource res1, resource res2)
{
window win=new window(res1, res2);
win.show();
window win2=new window(res1, res2);
win2.show();
//Окна продолжают жить дальше
}
unique resource res1;
unique resource res2;
someFunc(res1, res2);
Что произойдёт в этом случае с ресурсами?
Можешь представить окна как процессы, с которыми ты обмениваешься сообщениями — это тоже ничего не изменит. Тем более, что mutlithreaded GUI ещё ни у кого не получился на практике, слишком уж это сложная задача: http://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html
Здравствуйте, WolfHound, Вы писали:
WH>Вот к этому у нас сводятся все разговоры.
Дополню ещё. То что ты предлагаешь — это по-сути вариант region'ов без автоматического region inference.
Region inference изначально разрабатывался для автоматического управления памятью без классического GC (неудивительно, просто рассматриваем память как ресурс, который надо освободить). Очевидно, что добавив к выделяемым объектам деструктор — мы получим твою схему.
На практике, в OCaml'е с регионами и в Cyclon'е пришлось добавить refcounted-регионы, слабые ссылки и прочие аналоги С++-ности.
Здравствуйте, Cyberax, Вы писали:
C>А таки в С++ я могу использовать счётчик ссылок и всё ОК.
С логером ОК не будет. Это не та штука с которой можно так поступать.
C>Время жизни объекта не совпадает с лексическим диапазоном.
Ну так это тебе не С++ деструкторы. Примеры кода когда объект уходил далеко от того места где его создали я уже приводил в этой теме.
WH>>Твоя методика фигня по тому что есть случае которые туда не вписываются. WH>>Какие? WH>>Не скажу. Но они есть и твоя методика фигня. C>Ну вот, такой пример:
хъ C>Что произойдёт в этом случае с ресурсами?
Программа не скомпилируется.
Но ты опять придумал оторванный от реальности пример в котором нет никакой логики и пытаешься что-то доказать.
C>Можешь представить окна как процессы, с которыми ты обмениваешься сообщениями — это тоже ничего не изменит. Тем более, что mutlithreaded GUI ещё ни у кого не получился на практике, слишком уж это сложная задача: http://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html
А я и не собираюсь делать mutlithreaded. Я вообще считаю что mutlithreaded нужно искоренить ибо программисты него не понимают. Ага практически 100% не понимает.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>А таки в С++ я могу использовать счётчик ссылок и всё ОК. WH>С логером ОК не будет. Это не та штука с которой можно так поступать.
Как раз будет ОК, так как логгер обычно "листовой" объект, и мала вероятность возникновения циклических ссылок.
C>>Ну вот, такой пример: WH>хъ C>>Что произойдёт в этом случае с ресурсами? WH>Программа не скомпилируется.
Я понимаю. Но как такое сделать?
WH>Но ты опять придумал оторванный от реальности пример в котором нет никакой логики и пытаешься что-то доказать.
Пример абсолютно жизненный — у меня есть два окна, в котором показываются два вида одного ресурса. Как быть? Это просто как раз случай, когда нужно реальное разделение ресурсов.
Или более другой пример — HTTP-сессия с данными. И клиент, который с ней работает из двух табов в браузере.
Вероятно, ты просто слишком много серверного кода писал, а там обычно с временем жизни как раз всё просто — оно привязано к времени жизни вызова.
Здравствуйте, Cyberax, Вы писали:
C>Как раз будет ОК, так как логгер обычно "листовой" объект, и мала вероятность возникновения циклических ссылок.
Ссылки кончились, а через минуту он снова понадобился.
Что делать?
Геморрой все это. Логгер должен быть вечно живым.
C>Я понимаю. Но как такое сделать?
Сделать что? Передать один файл в два окна? Зачем на уровне ГУИ файл?
C>Пример абсолютно жизненный — у меня есть два окна, в котором показываются два вида одного ресурса. Как быть? Это просто как раз случай, когда нужно реальное разделение ресурсов.
Как ты собрался сокет в окне показывать?
C>Или более другой пример — HTTP-сессия с данными. И клиент, который с ней работает из двух табов в браузере.
Данные они и есть данные. Ими ГЦ рулит. Не понятно что ты тут вообще придумываешь.
C>Вероятно, ты просто слишком много серверного кода писал, а там обычно с временем жизни как раз всё просто — оно привязано к времени жизни вызова.
С временем жизни внешних ресурсов всегда все просто.
А если нет это значит косяк в дизайне.
Примеров обратного я не видел.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>Как раз будет ОК, так как логгер обычно "листовой" объект, и мала вероятность возникновения циклических ссылок. WH> Ссылки кончились, а через минуту он снова понадобился.
Если он понадобиться, то на него будет ссылка.
WH>Что делать?
Ну заново создай, если уж совсем криво сделал.
WH>Геморрой все это. Логгер должен быть вечно живым.
Не-не. Вечноживые объекты — это статики в миниатюре. А они суть зло.
C>>Я понимаю. Но как такое сделать? WH>Сделать что? Передать один файл в два окна? Зачем на уровне ГУИ файл?
Ну не файл, а модель, привязанная к соединению в БД, в котором открыта транзакция.
C>>Пример абсолютно жизненный — у меня есть два окна, в котором показываются два вида одного ресурса. Как быть? Это просто как раз случай, когда нужно реальное разделение ресурсов. WH>Как ты собрался сокет в окне показывать?
См. выше.
C>>Или более другой пример — HTTP-сессия с данными. И клиент, который с ней работает из двух табов в браузере. WH>Данные они и есть данные. Ими ГЦ рулит. Не понятно что ты тут вообще придумываешь.
Ну представь, что там у тебя не просто данные.
C>>Вероятно, ты просто слишком много серверного кода писал, а там обычно с временем жизни как раз всё просто — оно привязано к времени жизни вызова. WH>С временем жизни внешних ресурсов всегда все просто. WH>А если нет это значит косяк в дизайне. WH>Примеров обратного я не видел.
Это не значит, что их нет.
Здравствуйте, Cyberax, Вы писали:
C>Ну не файл, а модель, привязанная к соединению в БД, в котором открыта транзакция.
Ахринеть! Ты это серьезно? Держать открытой транзакцию пока юзер чай пьет? Тебя где программы писать учили?
C>Ну представь, что там у тебя не просто данные.
Не могу.
Зачем сесии что-то кроме данных?
C>Это не значит, что их нет.
В науке принято доказывать существование.
Причем это должен сделать тот кто утверждает что что-то существует.
Вот и доказывай.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>Ну не файл, а модель, привязанная к соединению в БД, в котором открыта транзакция. WH>Ахринеть! Ты это серьезно? Держать открытой транзакцию пока юзер чай пьет? Тебя где программы писать учили?
А почему бы и нет?
Hint: оптимистические транзакции ещё никто не отменял.
C>>Ну представь, что там у тебя не просто данные. WH>Не могу. WH>Зачем сесии что-то кроме данных?
А просто так.
C>>Это не значит, что их нет. WH>В науке принято доказывать существование. WH>Причем это должен сделать тот кто утверждает что что-то существует. WH>Вот и доказывай.
Я тебе привёл пример.
Здравствуйте, Cyberax, Вы писали:
C>А почему бы и нет? C>Hint: оптимистические транзакции ещё никто не отменял.
Мы наверное очень разный софт разрабатываем.
Лично я считаю длинные транзакции очень серьезной кривью.
C>А просто так.
Понятно. Значит не надо.
WH>>Вот и доказывай. C>Я тебе привёл пример.
Где? Там все либо совсем левое либо откровенные косяки.
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
C>>А почему бы и нет? C>>Hint: оптимистические транзакции ещё никто не отменял. WH>Мы наверное очень разный софт разрабатываем.
Как ты догадался?
WH>Лично я считаю длинные транзакции очень серьезной кривью.
Они кривы в общем случае. В частных случаях зато иногда полезны.
Я по этому поводу всё хочу написать в "Архитектуру"...
WH>>>Вот и доказывай. C>>Я тебе привёл пример. WH>Где? Там все либо совсем левое либо откровенные косяки.
Ну так то что не укладывается в твою модель — у тебя по определению косяк. Это, конечно, классный подход.