Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, kaa.python, Вы писали:
KP>>и это приводит к...? S>Нуу... к тому же самому — утечке, нет?
Каким образом? Или речь прерывании потока каким-нибудь хакерством за пределами языка, типа KillThread какой-нибудь? Ну тогда да, против лома нет приема. С тем же успехом можно прибить поток, в котором крутится сам сборщик мусора.
Банальная задача расширяемости (плагинов) — сводится к той проблеме которую я описал.
Возможно кому-то привычнее видеть краш всего процесса, вместо выгруженного плагина с аккуратно залогированным экзепшном, хотя — похоже все IDE, которые я видел — так не думают. А многие даже позволяют работать дальше.
Задача расширяемости — часто встречается и в рамках одного продукта, как один из видов разделения зон ответственности, владения, жизненного цикла.
Что-то очень похоже что ты ищешь замену плюсам. А это малость бессмысленно. Если проект большой и старый с плюсов никто не уйдет. Если проект новый, писать на плюсах по меньшей мере странно. Разве что много сторонних и специфичных либ нужно будет использовать. В 90% случаях писать на плюсах == домножить оценку минимум на 1.5-2
Тот же JS более чем реальная замена на клиентской стороне(гусары молчать! ему еще подрасти нужно). Тренд то вполне уверенный, тонкий клиент + облако. И не важно тонкий клиент это вэб, приложение или мобильник. Как результат динамические языки и функциональщина проникает в мэинстрим. А на сервере плюсы не нужны.
Из постепенно проникающих языков я бы выделил Erlang.
З.Ы.
Понятно что очередь умирать не скоро дойдет до CAD/CAM и подобных систем но тренд он такой
Здравствуйте, fddima, Вы писали:
F>Банальная задача расширяемости (плагинов) — сводится к той проблеме которую я описал. F>Возможно кому-то привычнее видеть краш всего процесса, вместо выгруженного плагина с аккуратно залогированным экзепшном, хотя — похоже все IDE, которые я видел — так не думают. А многие даже позволяют работать дальше. F>Задача расширяемости — часто встречается и в рамках одного продукта, как один из видов разделения зон ответственности, владения, жизненного цикла.
Я немного думал над этим вопросом и пришел к выводу, что с точки зрения корректности лучшим способом является полный запрет расширяемости в рамках одного процесса, как это сделано в Singularity. Там любое расширение — это уникальный процесс, общающийся по типизированным каналам с родителем.
Понятно, что в существующих ОС такой подход не работает и мы имеем выбор из различных, но плохих вариантов.
Здравствуйте, AlexRK, Вы писали:
ARK>Я немного думал над этим вопросом и пришел к выводу, что с точки зрения корректности лучшим способом является полный запрет расширяемости в рамках одного процесса, как это сделано в Singularity. Там любое расширение — это уникальный процесс, общающийся по типизированным каналам с родителем.
Если под процессом, понимается изолированный юзер-спейс, то — это один из наихудших вариантов, особенно для исходного примера. Код собственно говоря хочет работать с документом (state), используя stateful API, а не с набором сообщений (непосредственно или через прокси — это не так важно).
Но вообще-то в исходном примере была простая лямбда.
ARK>Понятно, что в существующих ОС такой подход не работает и мы имеем выбор из различных, но плохих вариантов.
Во всех существующих ОС такой подход как раз работает, и это единственный путь выполнить что-нибудь в "песочнице". Проблема в том, что это довольно дорого с любой сточки зрения, но в осмысленных случаях — он успешно используется.
Здравствуйте, fddima, Вы писали:
ARK>>Я немного думал над этим вопросом и пришел к выводу, что с точки зрения корректности лучшим способом является полный запрет расширяемости в рамках одного процесса, как это сделано в Singularity. Там любое расширение — это уникальный процесс, общающийся по типизированным каналам с родителем. F> Если под процессом, понимается изолированный юзер-спейс, то — это один из наихудших вариантов, особенно для исходного примера. Код собственно говоря хочет работать с документом (state), используя stateful API, а не с набором сообщений (непосредственно или через прокси — это не так важно).
Да, именно изолированный юзерспейс. В Singularity каналы предоставляют stateful API. Только вот использовать его "как попало" нельзя — для канала задаются четкие правила — что, когда и откуда идет, обойти которые нельзя (компилятор запрещает). Ошибки являются частью контракта канала.
F> Но вообще-то в исходном примере была простая лямбда.
Ну, я в контексте плагинов чуть развил тему.
ARK>>Понятно, что в существующих ОС такой подход не работает и мы имеем выбор из различных, но плохих вариантов. F> Во всех существующих ОС такой подход как раз работает, и это единственный путь выполнить что-нибудь в "песочнице". Проблема в том, что это довольно дорого с любой сточки зрения, но в осмысленных случаях — он успешно используется.
Понятно, что работает. Всё работает. И виндовс работает, и линупс работает, и QNX тоже. Только вот как, сколько в коде ошибок и насколько он устойчив — вопрос риторический.
Здравствуйте, AlexRK, Вы писали:
F>> Если под процессом, понимается изолированный юзер-спейс, то — это один из наихудших вариантов, особенно для исходного примера. Код собственно говоря хочет работать с документом (state), используя stateful API, а не с набором сообщений (непосредственно или через прокси — это не так важно). ARK>Да, именно изолированный юзерспейс. В Singularity каналы предоставляют stateful API. Только вот использовать его "как попало" нельзя — для канала задаются четкие правила — что, когда и откуда идет, обойти которые нельзя (компилятор запрещает). Ошибки являются частью контракта канала.
1. Research проекты это хорошо. Я даже за, когда я его смотрел, мне нравилось. Практической же пользы, для нас, программистов наших дней — толку от него вообще никакого.
2. Как иронично, что когда мы обсуждаем error code vs exceptions — показывать ресерч платформу, где есть exceptions.
3. Коммуникационные каналы сразу станут мусором, как только перестанет быть возможным вложить туда то, что хочется.
F>> Но вообще-то в исходном примере была простая лямбда. ARK>Ну, я в контексте плагинов чуть развил тему.
Отлично. Независимые куски, процессы — они падают, а IPC отваливается. Это вовлекает необходимость обработки ошибок.
Вот сигнатура метода. Этот метод, может упасть: на сериализации сообщения, на передаче сообщения, на десериализации сообщения. При чём ошибка передачи сегодня одна — завтра другая. Сегодня мы используем WCF over pipe, а потом когда задолбались с тем, что оно нихрена не работает — изменили канал, на собственный (с верой что оно будет работать лучше). Так вот — методу SyncRequest — совершенно пофигу на 3 вещи, и даже не знает о:
1. Реализации сериализатора.
2. Реализации канала.
3. Реализации десериализатора.
При этом внешний (вызывающий) код, на котором лежит отвественность обработки ошибки — с исключениями — получает более-менее внятную диагностику, безо всякого протаскивания кодов ошибок в сигнатуры.
А вот другой метод:
void PostAsync<TMessage>(TMessage request);
Данный метод никогда не валится, потому что складывает сообщения в очереди. Но, исключения всё равно могут пораждаться при отсылке инфраструктурой. Если же я залогирую безликие коды ошибок — это существенно усложнит процесс.
Более того, никто не мешает включить дебаг/трейс (всё есстественно в релизной конфигурации), в .NET в частности, и снять стэк-трэйс при постановки сообщения в очередь, если нужно связать сообщение с местом посылки. И то, это всё ещё будет очень безлико.
И на фоне таких, богатых возможностей — вы предлагаете использовать обыкновенную лапшу с кодом возврата.
Я не давно заглянул в код Add-In COM Shim — и увидел сплошную лапшу и макрос навроде:
#define SUCCESS(x) if (!(x)) goto error;
.
Это просто ужасно. Это нормально для небольшого C/C++ кода. Это абсолютно ужасно для нового, якобы безопасного языка.
Sinclair, вот и исключениями, то не очень доволен — но лучше уж исключения, чем уг с протаскиванием кодов ошибок.
Тем более, что в 99% случаев, на исключения всем параллельно. Вы читаете файл — вам пофигу, что не так. Вы его хотели прочитать — вы его не прочитали. Нет файла, или это проблема с доступом, или вообще не дошло до этого дела — разруливать конкретные ситуации надо, но не так что бы очень уж часто. Важнее знать, что мы сделали или нет, то что хотели.
F>> Во всех существующих ОС такой подход как раз работает, и это единственный путь выполнить что-нибудь в "песочнице". Проблема в том, что это довольно дорого с любой сточки зрения, но в осмысленных случаях — он успешно используется. ARK>Понятно, что работает. Всё работает. И виндовс работает, и линупс работает, и QNX тоже. Только вот как, сколько в коде ошибок и насколько он устойчив — вопрос риторический.
Windows, Linux, OSX — имеют отличные стабильные ядра, и собственно говоря пока не предвидится, что бы их кто-нибудь превзошел.
Ошибки безусловно есть везде, но и мир на месте не стоит. А Singularity всё равно содержит какое-то (5%?) количество нативного кода. Увы. Докажете его безопасность?
Здравствуйте, fddima, Вы писали:
F> Вот сигнатура метода. Этот метод, может упасть: на сериализации сообщения, на передаче сообщения, на десериализации сообщения. При чём ошибка передачи сегодня одна — завтра другая. Сегодня мы используем WCF over pipe, а потом когда задолбались с тем, что оно нихрена не работает — изменили канал, на собственный (с верой что оно будет работать лучше). Так вот — методу SyncRequest — совершенно пофигу на 3 вещи, и даже не знает о: F> 1. Реализации сериализатора. F> 2. Реализации канала. F> 3. Реализации десериализатора. F> При этом внешний (вызывающий) код, на котором лежит отвественность обработки ошибки — с исключениями — получает более-менее внятную диагностику, безо всякого протаскивания кодов ошибок в сигнатуры. F> А вот другой метод: F> Данный метод никогда не валится, потому что складывает сообщения в очереди. Но, исключения всё равно могут пораждаться при отсылке инфраструктурой. Если же я залогирую безликие коды ошибок — это существенно усложнит процесс. F> Более того, никто не мешает включить дебаг/трейс (всё есстественно в релизной конфигурации), в .NET в частности, и снять стэк-трэйс при постановки сообщения в очередь, если нужно связать сообщение с местом посылки. И то, это всё ещё будет очень безлико.
Это все понятно, в общем-то повторение уже написанного ранее.
F> И на фоне таких, богатых возможностей — вы предлагаете использовать обыкновенную лапшу с кодом возврата.
Не согласен с коннотацией терминов (богатые возможности против лапши). Я предлагаю не лапшу, а предсказуемый код, глядя на который можно сразу сказать, что здесь может что-то пойти не так. Впрочем, ИМХО, обсуждение зашло в тупик, позиции сторон ясны, а консенсус вряд ли возможен.
F> Sinclair, вот и исключениями, то не очень доволен — но лучше уж исключения, чем уг с протаскиванием кодов ошибок.
Ну, кому как.
ARK>>Понятно, что работает. Всё работает. И виндовс работает, и линупс работает, и QNX тоже. Только вот как, сколько в коде ошибок и насколько он устойчив — вопрос риторический. F> Windows, Linux, OSX — имеют отличные стабильные ядра, и собственно говоря пока не предвидится, что бы их кто-нибудь превзошел.
Стабильные ядра, написанные без использования исключений.
(У меня там, кстати, QNX, а не OSX, как пример того, что "работают" ОС с разной степенью надежности.)
F> А Singularity всё равно содержит какое-то (5%?) количество нативного кода. Увы. Докажете его безопасность?
Это возможно, вручную (неверифицируемое ядро маленькое). Вот тут доказали для L4: http://ssrg.nicta.com.au/projects/TS/l4.verified/
А вот подобное доказательство для систем, написанных на C++ с исключениями, уже малореально.
Здравствуйте, AlexRK, Вы писали:
ARK>Это все понятно, в общем-то повторение уже написанного ранее.
Это всё к тому, что исключения, в любом виде — помогают решать практические задачи.
F>> И на фоне таких, богатых возможностей — вы предлагаете использовать обыкновенную лапшу с кодом возврата. ARK>Не согласен с коннотацией терминов (богатые возможности против лапши). Я предлагаю не лапшу, а предсказуемый код, глядя на который можно сразу сказать, что здесь может что-то пойти не так. Впрочем, ИМХО, обсуждение зашло в тупик, позиции сторон ясны, а консенсус вряд ли возможен.
Я тут в треде приводил пример, как в реальном мире нередко обрабатываются коды ошибок — они тупо душаться.
Об этом же написали и в соседних ветках.
ARK>Стабильные ядра, написанные без использования исключений.
Вообще-то, ядро современной ОС, это сплошная, беспрерывная и невидимая обработка исключений, генерируемых, скажем MMU. Т.е. сама идея исключений эксплуатируется пошире, чем нам тут пытаются рассказать.
То, что ядра пилили на C — то и выбора не было. Стоит ли их пилить на C++ с применением исключений — это уже дело тех кто занимается написанием ядер. Для меня плюсы и минусы обоих подходов, будут в этом случае не очевидны.
ARK>(У меня там, кстати, QNX, а не OSX, как пример того, что "работают" ОС с разной степенью надежности.)
Какие-либо гарантии о времени (я про QNX), — это ещё не показатель надежности, и то сильно упирается в железо.
Боюсь, что надежность QNX невозможно сравнить с линуксом, ввиду гораздо более узкого применения первых, и гораздо более широкого применения последних. Поэтому я его и убрал. Хотя, может кто-то и сравнивал. Х.з.
F>> А Singularity всё равно содержит какое-то (5%?) количество нативного кода. Увы. Докажете его безопасность? ARK>Это возможно, вручную (неверифицируемое ядро маленькое). Вот тут доказали для L4: http://ssrg.nicta.com.au/projects/TS/l4.verified/ ARK>А вот подобное доказательство для систем, написанных на C++ с исключениями, уже малореально.
Тут спору нет. Но и работающей системы нет.
Здравствуйте, MTD, Вы писали:
MTD>То что многие проекты были начаты когда поддержка исключений хромала или потому, что главный архитектор фанатик — ничего не доказывает. Достаточно один раз переписать код с кодами возврата на исключения и сравнить результат, чтобы сомнения отпали, как писать проще и безопасней.
пожалуйста, приведи пример хоть немного реального кода с кодами возврата, который можно переписать на исключения и он не будет выглядеть унылым говном.
VD>Основная проблема с кодами возврата не контроль компилятора, а куча болепрлэйт-кода засоряющего код, и необходимость тратить на него время.
да покажите же наконец эту кучу бойлерплейт кода хоть в одном реальном проекте, и заодно покажите как бы это классно выглядело с исключениями, посмеёмся всеми шрёдерами
Здравствуйте, antropolog, Вы писали:
A>Здравствуйте, MTD, Вы писали:
MTD>>То что многие проекты были начаты когда поддержка исключений хромала или потому, что главный архитектор фанатик — ничего не доказывает. Достаточно один раз переписать код с кодами возврата на исключения и сравнить результат, чтобы сомнения отпали, как писать проще и безопасней.
A>пожалуйста, приведи пример хоть немного реального кода с кодами возврата, который можно переписать на исключения и он не будет выглядеть унылым говном.
Раньше лет 5 назад все типовые конфигурации 1с были сплошные "попытка исключение конецпопытки" (в 1с исключения встроены изначально) сейчас практически все переписали на коды возврата.
Причина в том, исключение скрывает ошибку ухудшая тестирование, вроде все отработало и нормально, а результат не корректный.
Тут возможен вариант, что исключения удобно, когда ты пишешь сам код и сам его тестируешь.
Если же тестирование и разработка разнесены, то вероятно исключения начинают становиться проблемой.
Я думаю по этой причине исключения не используются и в гугл.
Здравствуйте, antropolog, Вы писали:
A>пожалуйста, приведи пример хоть немного реального кода с кодами возврата, который можно переписать на исключения и он не будет выглядеть унылым говном.
Это обсасывалось уже сто раз, но нет все равно периодически вылезает неофит услышавший от бородатого гуру, что исключения это плохо и понеслась.
На досуге предлагаю написать итератор без исключений, с помощью конструктора без исключений создать объект с гарантией, что если объект создан то он в валидном состоянии и т.д.
Адский код. Хороший пример, но тут кривое API. Непонятно, зачем возвращается код ошибки из каждого метода. Надо было его засунуть внутрь объектов sAIPanelFlyoutMenu/sAIPanel/etc., если уж у них каждый вызов может закончиться фейлом. Каждый метод такого объекта внутри проверил бы состояние, и в случае ошибки просто сделал бы return, а юзер проверил бы ошибку один раз после всех обращений к объекту.
MTD>На досуге предлагаю написать итератор без исключений, с помощью конструктора без исключений создать объект с гарантией, что если объект создан то он в валидном состоянии и т.д.
Про итератор не знаю, а с конструктором, ИМХО, должно быть так — внутри не должно быть никаких вызовов, которые могут закончиться ошибкой, в противном случае следует применить factory method (мало того, я считаю это хорошей практикой вообще, а не только для языков без исключений).
ARK>Адский код. Хороший пример, но тут кривое API. Непонятно, зачем возвращается код ошибки из каждого метода. Надо было его засунуть внутрь объектов sAIPanelFlyoutMenu/sAIPanel/etc.,
Если бы да кабы. Надо сделать хорошо, а тут криво. Ничего, что это — реальный мир, и теоретические изыскания хороши, но не работают?
VD>>Основная проблема с кодами возврата не контроль компилятора, а куча болепрлэйт-кода засоряющего код, и необходимость тратить на него время.
A>да покажите же наконец эту кучу бойлерплейт кода хоть в одном реальном проекте, и заодно покажите как бы это классно выглядело с исключениями, посмеёмся всеми шрёдерами
— Помечаем, что мы ответственны за получение исключений из дочерних процессов
— Запускаем дочерний процесс
— Ждем сообщений из дочернего процесса
— Обрабатываем приходящие сообщения (включая исключения)
Так как это — init функция, у нее в спеках прописано, что она возвращает или {ok, Pid} или {error, Reason). А могла бы выкидывать исключение.
Здравствуйте, AlexRK, Вы писали:
ARK>Адский код. Хороший пример, но тут кривое API. Непонятно, зачем возвращается код ошибки из каждого метода.
Ну так ошибка может возникнуть в любом месте.
MTD>>На досуге предлагаю написать итератор без исключений, с помощью конструктора без исключений создать объект с гарантией, что если объект создан то он в валидном состоянии и т.д.
ARK>Про итератор не знаю
То код работы с коллекциями (которого в реальном коде процентов 80) превращается в что-то типа такого:
Iter i;
if (!GetIter(i, data)) return -1;
while (i.HasNext())
{
X x;
if (!i.Get(x)) return -1;
...
if (!i.Next()) return -1;
}
Вместо:
for (Iter i : data)
X x = i.Current();
Ну круто. И что характерно никаких преимуществ перед исключениями.
Здравствуйте, MTD, Вы писали:
MTD>То код работы с коллекциями (которого в реальном коде процентов 80) превращается в что-то типа такого:
MTD>
MTD>Iter i;
MTD>if (!GetIter(i, data)) return -1;
MTD>while (i.HasNext())
MTD>{
MTD> X x;
MTD> if (!i.Get(x)) return -1;
MTD> ...
MTD> if (!i.Next()) return -1;
MTD>}
MTD>
Непонятно. Это все не нужно. GetIter не должен завершаться с ошибкой. HasNext и Next должны быть одним методом MoveNext, для которого тоже нет резона возвращать ошибку.
Get/Current — тут да, наверное ошибка может быть.
Здравствуйте, AlexRK, Вы писали:
ARK>Непонятно. Это все не нужно. GetIter не должен завершаться с ошибкой.
Это почему? А если память, например, не удалось выделить?
ARK>HasNext и Next должны быть одним методом MoveNext
На практике это неудобно, например, я не хочу сдвигать итератор, просто хочу проверить, что есть куда сдвигать.
ARK>для которого тоже нет резона возвращать ошибку.
А MoveNext невалидному итератору? Ты уверен, что стоит так замаскировать баг?
ARK>Get/Current — тут да, наверное ошибка может быть.
ARK>Мой вариант без исключений:
В идеальном мире, где ошибки бывают только там где хочет программист.