Re[2]: Обработка ошибок
От: AlexRK  
Дата: 26.09.17 17:01
Оценка: +2 -4 :))
Здравствуйте, MozgC, Вы писали:

MC>Может не надо ничего фантазировать, а надо просто научиться пользоваться исключениями и многопоточностью?


Исключения — плохая вещь, безотносительно того, умеешь ей пользоваться или нет.
Ну то есть как плохая, просто отличить плохой код с исключениями от хорошего кода с исключениями — сложно. Рассуждать о программах с исключениями — сложно.
Re[2]: Обработка ошибок
От: AlexRK  
Дата: 26.09.17 17:08
Оценка: -1
Здравствуйте, vsb, Вы писали:

vsb>любой цикл или условный оператор это "неявный goto".


Цикл и иф имеют точное место продолжения выполнения. Исключения и гото — мы не знаем, куда летим. Поэтому циклы и ифы — структурные операторы, а исключения и гото — нет.
Re: Обработка ошибок
От: AlexRK  
Дата: 26.09.17 17:28
Оценка:
Здравствуйте, MTD, Вы писали:

MTD>Давайте пофантазируем как можно было бы организовать идеальную обработку ошибок. Я пока придумал объеденить оба подхода через дополнительную сущность — ну пусть будет поток выполнения (ExecutionFlow), экземпляр которого имеет каждый поток. Данная сущность неявно присутствует в вызове каждой функции, хранит стек вызовов и флажок ошибки.


Обработке ошибок присуща природная сложность и не очень понятно, как можно было бы серьезно упростить жизнь программиста. Сейчас лично я думаю так. Часть ошибок, которые сейчас являются рантайм-ошибками, должна перейти на стадию компиляции. Пример — NRE. Часть ошибок должна стать фатальными и не обрабатываться вообще (stack overflow, недостаток памяти). Часть ошибок можно отсечь частичными функциями — не исключение при вызове "log(-1)", а ошибка компиляции. Оставшиеся обрабатывать а-ля Rust — возвращать Result<Type> вместо Type.

MTD>Как считаете имеет право на жизнь? Есть ли языки с таким подходом к обработке ошибок?


Как справедливо заметили выше, это похоже на error monad. Так что да, где-то используется.
Re[13]: Обработка ошибок
От: Terix  
Дата: 27.09.17 07:00
Оценка: :)
Здравствуйте, AlexRK, Вы писали:

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


GZ>>>>Остаток процедуры будет запущен после выполнения асинхронно функции

MTD>>>Вот это и есть синхронный код, да он притворяется асинхронным, но сущность его именно такова.
vsb>>Всё наоборот. Это асинхронный код, который притворяется синхронным.

ARK>Семантически этот код — именно синхронный. То, что компилятор где-то внутри генерит — это просто деталь реализации и не более. Если я возьму другой компилятор, который будет создавать синхронный код в этом месте, то не изменится НИЧЕГО — ни код, ни поведение программы.


Нет, это не так. Синхронный код заблочит поток и будет ничего не делать и ждать, ждать, ждать и так пока не закончится вызов something(), после чего перейдёт к следующей строке. Между something() и следующей строкой не вклинится другой код. А асинхронный код вернёт управление сразу, сразу начнёт выполняться какой-то там другой код, а то, что после вызова something(), выполнится отдельно потом.
Re[2]: Обработка ошибок
От: Terix  
Дата: 27.09.17 07:05
Оценка:
CD>Поздравляю! Вы изобрели монаду!
CD>Типа Error Monad.

CD>Языки в которых такое есть:

CD>

    CD>
  1. Haskell
    CD>
  2. F#
    CD>
  3. OCaml
    CD>
  4. Idris
    CD>

CD>Насчёт первых двух уверен на 100%, насчёт остальных — поменьше, поскольку не работаю с ними.

CD>Наверняка есть и другие языки с поддержкой монад вообще и монады ошибок в частности.

А в этих самых монадах есть неявное преобразование к инту, как в задумке в первом посте?
Re[14]: Обработка ошибок
От: AlexRK  
Дата: 27.09.17 07:09
Оценка: +2 -1
Здравствуйте, Terix, Вы писали:

ARK>>Семантически этот код — именно синхронный. То, что компилятор где-то внутри генерит — это просто деталь реализации и не более. Если я возьму другой компилятор, который будет создавать синхронный код в этом месте, то не изменится НИЧЕГО — ни код, ни поведение программы.


T>Нет, это не так. Синхронный код заблочит поток и будет ничего не делать и ждать, ждать, ждать и так пока не закончится вызов something(), после чего перейдёт к следующей строке. Между something() и следующей строкой не вклинится другой код. А асинхронный код вернёт управление сразу, сразу начнёт выполняться какой-то там другой код, а то, что после вызова something(), выполнится отдельно потом.


Это все я знаю. Я говорю про семантику кода, а не про детали конкретной реализации. Блин, вроде всё в предвдущем посте расписал — всё равно люди не понимают.

Вот этот код — "a = f() + 3;" — синхронный или асинхронный? (Важное уточнение для прибитых к контексту людей: это не C#.)
Семантически — синхронный, то есть выглядит и взаимодействует с другим кодом как синхронный.
Реализован как синхронный или асинхронный? Может быть и так, и так. На текущем уровне абстракции нам это пофигу.
Re[15]: Обработка ошибок
От: Terix  
Дата: 27.09.17 07:22
Оценка:
ARK>Это все я знаю. Я говорю про семантику кода, а не про детали конкретной реализации. Блин, вроде всё в предвдущем посте расписал — всё равно люди не понимают.

В предыдущем посте написано, что поведение программы не будет меняться в зависимости от того, какой код сгенерировал компилятор — синхронный, или асинхронный. А оно будет меняться, потому что в случае асинхронного кода, что-то может вклиниться между something и следующей строкой, а в случае синхронного кода — не может.
Re[16]: Обработка ошибок
От: AlexRK  
Дата: 27.09.17 07:32
Оценка: -1
Здравствуйте, Terix, Вы писали:

ARK>>Это все я знаю. Я говорю про семантику кода, а не про детали конкретной реализации. Блин, вроде всё в предвдущем посте расписал — всё равно люди не понимают.


T>В предыдущем посте написано, что поведение программы не будет меняться в зависимости от того, какой код сгенерировал компилятор — синхронный, или асинхронный. А оно будет меняться, потому что в случае асинхронного кода, что-то может вклиниться между something и следующей строкой, а в случае синхронного кода — не может.


Да, согласен, упустил этот момент. Если говорить только о C#.
Re: Обработка ошибок
От: Terix  
Дата: 27.09.17 09:03
Оценка:
MTD>Как считаете имеет право на жизнь? Есть ли языки с таким подходом к обработке ошибок?

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

Возвращать Option<int> .

Option<int> plus(Option<int> x) {
   return x.map(el -> el + 2);
}


Соответственно функция принимает один Option и возвращает другой. Таких операций можно сделать много, но в результате у нас будет какой-то Option.
У Option есть метод get, который кинет эксепшн, если какая-то из операций прошла плохо.

try {
   print(x.get());
catch(BadOptionException) {
   print("фигня какая-то");
}


Если мы пробуем провести операцию на уже побитом Option, она проводится не будет, а нам молча вернут ещё один дефектный Option.
Преимуществом тут является, что не нужно мучаться с эксепшнами и то, что не надо проверять ошибки на каждый чих, а проверить только там, где нужно.

Недостатком то, что примитивный тип приходится оборачивать и код получается непривычным
Re[2]: Обработка ошибок
От: night beast СССР  
Дата: 27.09.17 09:07
Оценка:
Здравствуйте, Terix, Вы писали:

T>Если мы пробуем провести операцию на уже побитом Option, она проводится не будет, а нам молча вернут ещё один дефектный Option.

T>Преимуществом тут является, что не нужно мучаться с эксепшнами и то, что не надо проверять ошибки на каждый чих, а проверить только там, где нужно.

теряется информация об ошибке и месте/условиях ее появления.
Re[3]: Обработка ошибок
От: Terix  
Дата: 27.09.17 09:36
Оценка:
Здравствуйте, night beast, Вы писали:

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


T>>Если мы пробуем провести операцию на уже побитом Option, она проводится не будет, а нам молча вернут ещё один дефектный Option.

T>>Преимуществом тут является, что не нужно мучаться с эксепшнами и то, что не надо проверять ошибки на каждый чих, а проверить только там, где нужно.

NB>теряется информация об ошибке и месте/условиях ее появления.


Сейчас в мейнстримных языках, в том месте, где произойдёт ошибка, будет сгенерирован эксепшн. Метод map его поймает и сохранит для потомков. В эксепшне будет написано где, что и как. Эксепшн BadOptionException обернёт этот эксепшн и подробности можно будет получить.
Отредактировано 27.09.2017 9:42 Terix . Предыдущая версия .
Re[4]: Обработка ошибок
От: night beast СССР  
Дата: 27.09.17 09:57
Оценка:
Здравствуйте, Terix, Вы писали:

T>>>Если мы пробуем провести операцию на уже побитом Option, она проводится не будет, а нам молча вернут ещё один дефектный Option.

T>>>Преимуществом тут является, что не нужно мучаться с эксепшнами и то, что не надо проверять ошибки на каждый чих, а проверить только там, где нужно.

NB>>теряется информация об ошибке и месте/условиях ее появления.


T>Сейчас в мейнстримных языках, в том месте, где произойдёт ошибка, будет сгенерирован эксепшн. Метод map его поймает и сохранит для потомков. В эксепшне будет написано где, что и как. Эксепшн BadOptionException обернёт этот эксепшн и подробности можно будет получить.


допустим.
как решаются проблемы с нарушением инвариантов объекта при исключении?
Re[5]: Обработка ошибок
От: Terix  
Дата: 27.09.17 10:34
Оценка:
Здравствуйте, night beast, Вы писали:

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


T>>>>Если мы пробуем провести операцию на уже побитом Option, она проводится не будет, а нам молча вернут ещё один дефектный Option.

T>>>>Преимуществом тут является, что не нужно мучаться с эксепшнами и то, что не надо проверять ошибки на каждый чих, а проверить только там, где нужно.

NB>>>теряется информация об ошибке и месте/условиях ее появления.


T>>Сейчас в мейнстримных языках, в том месте, где произойдёт ошибка, будет сгенерирован эксепшн. Метод map его поймает и сохранит для потомков. В эксепшне будет написано где, что и как. Эксепшн BadOptionException обернёт этот эксепшн и подробности можно будет получить.


NB>допустим.

NB>как решаются проблемы с нарушением инвариантов объекта при исключении?

Да, пожалуй, что никак. Надо руками, как и в случаях с исключениями.
Re[6]: Обработка ошибок
От: night beast СССР  
Дата: 27.09.17 10:38
Оценка:
Здравствуйте, Terix, Вы писали:

NB>>допустим.

NB>>как решаются проблемы с нарушением инвариантов объекта при исключении?

T>Да, пожалуй, что никак. Надо руками, как и в случаях с исключениями.


ну с исключениями хотя бы понятно где бахнуло, а при Optional нарваться на последствия можно в совершенно не связанном с этим Optional месте.
Re[7]: Обработка ошибок
От: Terix  
Дата: 27.09.17 11:15
Оценка:
NB>ну с исключениями хотя бы понятно где бахнуло, а при Optional нарваться на последствия можно в совершенно не связанном с этим Optional месте.

Ты имеешь в виду такой случай?
Option<int> a = plus(a); //тут ошибка

Option<string> b = getWeirdString(a); //Внутри getWeirdString мы делаем get у Option и ловим эксепшн
Re[8]: Обработка ошибок
От: night beast СССР  
Дата: 27.09.17 11:29
Оценка:
Здравствуйте, Terix, Вы писали:

NB>>ну с исключениями хотя бы понятно где бахнуло, а при Optional нарваться на последствия можно в совершенно не связанном с этим Optional месте.


Ты имеешь в виду такой случай?
T>
T>Option<int> a = plus(a); //тут ошибка

T>Option<string> b = getWeirdString(a); //Внутри getWeirdString мы делаем get у Option и ловим эксепшн


нет. что-то вроде такого:

Option<int> a = x.foo(); //тут ошибка

...

x.bar(); //пытаемся работать с кривым x
Re[9]: Обработка ошибок
От: Terix  
Дата: 27.09.17 12:43
Оценка:
Здравствуйте, night beast, Вы писали:

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


NB>>>ну с исключениями хотя бы понятно где бахнуло, а при Optional нарваться на последствия можно в совершенно не связанном с этим Optional месте.


NB>Ты имеешь в виду такой случай?

T>>
T>>Option<int> a = plus(a); //тут ошибка

T>>Option<string> b = getWeirdString(a); //Внутри getWeirdString мы делаем get у Option и ловим эксепшн
NB>


NB>нет. что-то вроде такого:

NB>

NB>Option<int> a = x.foo(); //тут ошибка

NB>...

NB>x.bar(); //пытаемся работать с кривым x
NB>


Это ведь то же самое, что
int a = -1;
try {
    a = x.foo();
} catch(Exception e) {
   Log.Info("нехорошо вышло, да"); //хрень какая-то с a вышла, но это нас не очень волнует
}

x.bar(); //а обработать проблему с кривым иксом в блоке catch мы забыли
Re[10]: Обработка ошибок
От: night beast СССР  
Дата: 27.09.17 13:04
Оценка:
Здравствуйте, Terix, Вы писали:

T>Это ведь то же самое, что

T>
T>int a = -1;
T>try {
T>    a = x.foo();
T>} catch(Exception e) {
T>   Log.Info("нехорошо вышло, да"); //хрень какая-то с a вышла, но это нас не очень волнует
T>}

T>x.bar(); //а обработать проблему с кривым иксом в блоке catch мы забыли
T>



да, но с исключениями это приходится писать явно.
или Optional это просто дополнение к исключениям? тогда нормально.
почему-то решил что как альтернатива предлагается.
Re: Обработка ошибок
От: WolfHound  
Дата: 27.09.17 13:55
Оценка: 12 (2) +6
Здравствуйте, MTD, Вы писали:

MTD>За время моей трудовой деятельности я участвовал как в проектах использующих исключения, так и в проектах использующих коды ошибок.

Тут всё разобрано по косточкам.
Много букв, но ничего лучше про обработку ошибок я не видел.
http://joeduffyblog.com/2016/02/07/the-error-model/
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[3]: Result<T, E>
От: Qbit86 Кипр
Дата: 27.09.17 19:28
Оценка:
Здравствуйте, night beast, Вы писали:

NB>теряется информация об ошибке и месте/условиях ее появления.


`Option<T>` (сумма `Some<T>` и `None`) просто «частный случай» типа `Either<L, R>` или `Result<T, E>` (сумма `Some<T>` и `Error<E>`). `Option<T>` используется, когда причина ошибки неважна или единственна (например, ключ в словаре не найден). Если вариантов ошибки может быть больше, то можно возвращать `Result<T, E>`, и класть туда `Error<E>`, где `E` — информация об ошибках, туда можно сохранить контекст возникновения (фаза луны, состояние программы, etc.).

Обычно это удобно в языках с паттерн-матчингом или монадами в стандартной библиотеке. Если адаптировать этот подход на какой-нибудь ООП-язык типа C#, то в `Result<T, E>` ты просто кладёшь наследника от `Exception`, например, который замыкает в себе информацию об условиях появления ошибки.
Глаза у меня добрые, но рубашка — смирительная!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.