@Fsharp_chat

Страница 692 из 772
Google
Vasily
03.09.2018
09:33:59
Ну, можешь про свое реальное программирование рассуждать в @fsharp_flood.
Ты не выспался, что ли? Я честно пытался прикрутить Wpf.elmish к своему проекту. У меня не получилось. Сценарий соответственно был самый обычный для wpf приложений

Evgeniy
03.09.2018
09:34:05
Это уже про другое
Ну, так разница только в том, как у тебя это исключение передается наверх: явно или неявно.

Roman
03.09.2018
09:34:57
Ты не выспался, что ли? Я честно пытался прикрутить Wpf.elmish к своему проекту. У меня не получилось. Сценарий соответственно был самый обычный для wpf приложений
Давайте без перехода на личности. Я тут недавно говорил, что мы виртуальная семья, без ругани конечно не бывает, но ругайтесь в личке

Vasily
03.09.2018
09:35:54
Если кому интересно, могу развернуть аргументы про elmish.wpf

Evgeniy
03.09.2018
09:37:52
Ты не выспался, что ли? Я честно пытался прикрутить Wpf.elmish к своему проекту. У меня не получилось. Сценарий соответственно был самый обычный для wpf приложений
Ну, не получилось — не обобщай. Если ты приходишь и что-то называешь говном — готовься, что и послать могут.

Roman
03.09.2018
09:38:02
Ну, так разница только в том, как у тебя это исключение передается наверх: явно или неявно.
Чем раньше отловишь исключение, тем меньше у тебя будет круг поиска

Vasily
03.09.2018
09:38:25
Ок, аргументирую, почему это г-нопример.

1. Типичным сценарием построения UI в WPF является написание модели и назначение ей шаблона отображени

*отображения

Соответственно, в главном окне(или где-то еще) у нас есть ContentPresenter, который в DataContext принимает модель плюс DataTemplateSelector, который на основании модели принимает решение о том, какой шаблон подставить

Данные же примеры заточены на генерацию конкретного UI под конкретные модели - нормалный такой html-like подход. Т.е. есть модель, я генерю ей отображение, и типа все ок

Проблема начинается, когда надо разделить модель и отображение

Google
Vasily
03.09.2018
09:42:14
Плюс желательно, чтобы генератор моделей (в нашем случае update, как я понимаю) ничего не знал об отображении

Vladimir
03.09.2018
09:42:24
Чем раньше отловишь исключение, тем меньше у тебя будет круг поиска
Если ты просто не будешь хэндлить непонятные эксепшны и они пойдут наверх, то там будет стектрейс и круг поиска такой же)

Vasily
03.09.2018
09:42:56
А скорее мог подставить некий ключ в сгенерированную модель, по которому UI сможет выбрать нужный способ отображения

Так вот

Текущая реализация Elmish.wpf на динамиках этого сделать, к сожалению, не очень позволет

Evgeniy
03.09.2018
09:43:50
@vshapenko То, что модель не подходит под твои влажные фантазии — не значи, что она говно. Есть куча приложений, которые можно без проблем написать в форма SPA и TEA.

Vasily
03.09.2018
09:44:21
Объясняю еще раз. Это не фантазии

Evgeniy
03.09.2018
09:44:21
Я, конечно, понимаю, что ты любишь из себя эксперта по всему строить. Но не надо так.

Vasily
03.09.2018
09:44:47
Просто подход, который ок в вебе, здесь не совсем применим

Roman
03.09.2018
09:45:01
Если ты просто не будешь хэндлить непонятные эксепшны и они пойдут наверх, то там будет стектрейс и круг поиска такой же)
А тут ты ловишь все исключения и пишешь их в Result<'a,Exceptions>, где в Exceptions есть | Bug. Это важно, чтоб всегда быть в одном контролфлоу

Vasily
03.09.2018
09:45:23
В силу разного подхода к генерации UI

В html страница содержит данные

Vladimir
03.09.2018
09:45:55
Проблема начинается, когда надо разделить модель и отображение
Как раз неделю назад очень похожую тему обсуждали с DustinMorris из жирафа) Он хотел один к одному мапить вьюху на модель, и не хотел добавлять ViewModel куда можно произвольные данные независимо от модели пихать, но я его смог убедить что это бывает полезно

Vladimir
03.09.2018
09:47:13
https://github.com/giraffe-fsharp/Giraffe.Razor/issues/5

Vasily
03.09.2018
09:47:24
И на десктопе этот сценарий значительно более частый, чем на вебе

Соответственно, если фреймворк пишется без поддержки этого сценария, он довольно-таки сильно ограничивает доступные оптимальные пути разработки

Vladimir
03.09.2018
09:50:31
А тут ты ловишь все исключения и пишешь их в Result<'a,Exceptions>, где в Exceptions есть | Bug. Это важно, чтоб всегда быть в одном контролфлоу
и ты загрязняешь этим код. Во-первых потому что будешь везде вставлять трайкетчи для надобности и ненадобности. Во-вторых, потому что надо пытаться разобрать эксепшн в паттерн-матчинге непонятно какой, как только кто-то захочет проанализировать эрроры. А в-третьих все равно ты глобальный обработчик эксепшнов сделаешь просто на всякий случай.

Google
Roman
03.09.2018
09:56:50
Так что минимальное зло есть, да, но зато получаешь управляемость

Bonart
03.09.2018
09:57:20
Теряешь контролфлоу - получаешь неопределенность
У исключений флоу простой и предсказуемый. А еще и бесплатный, если их не бросать.

Roman
03.09.2018
09:58:31
Bonart
03.09.2018
10:11:57
Roman
03.09.2018
10:12:25
Bonart
03.09.2018
10:13:15
И мы превращаем его в закрытое
Не превращаем - или сохраняем Exception (сам объект), который вполне себе открытый или усекаем до того или иного закрытого множества.

Bonart
03.09.2018
10:14:57
Усекаем, ок.
И в процессе теряем информацию об ошибке, что практически не есть гуд. Поэтому я ничего не имею против Result, но вторым параметром у меня в нем Exception

Vasily
03.09.2018
10:15:28
Вопрос один - на каком уровне иерархии нам полезна информация об исключении?

Точнее, полная информация

Bonart
03.09.2018
10:16:42
Вопрос один - на каком уровне иерархии нам полезна информация об исключении?
На всех. Нам нужно преобразование известных ошибок на границах уровней абстракции, но терять информацию снизу (которая InnerException) низзя.

Нет. Bug of Exception сохраняет информацию
Для Bug of Exception закрытое внезапно протекает

Vasily
03.09.2018
10:17:46
Я на это смотрю с той точки зрения, что, если у меня случилась такая фигня, то должна быть возможность понять, что:1. фигня произошла 2. что с ней делать

То, что фигня произошла - это просто текст ошибки, по идее

Что делать - полный текст эксепшна в логах

Иначе произойдет встраивание эксепшна в логику работы, что, имхо, не есть гуд

Bonart
03.09.2018
10:20:22
Иначе произойдет встраивание эксепшна в логику работы, что, имхо, не есть гуд
Почему? Ты можешь отщипнуть от эксепшена известное тебе подмножество и повесить на него логику обработки. Его собственно за этим и придумали

Vasily
03.09.2018
10:23:35
Почему? Ты можешь отщипнуть от эксепшена известное тебе подмножество и повесить на него логику обработки. Его собственно за этим и придумали
Данный подход подталкивает меня протаскивать полный эксепшн наверх. Хотя у меня есть исключения ожидаемые, которые должны ложиться в доменную область как известные ошибки, и исключения неизвестные, с которыми не очень понятно, что делать

Google
Vasily
03.09.2018
10:24:05
Для известных исключений проще вывести типы ошибок плюс запись в лог

С неизвестными, в целом , то же самое

UnknownError msg

Зависит от контекста сильно

Bonart
03.09.2018
10:26:10
Данный подход подталкивает меня протаскивать полный эксепшн наверх. Хотя у меня есть исключения ожидаемые, которые должны ложиться в доменную область как известные ошибки, и исключения неизвестные, с которыми не очень понятно, что делать
Смотри - про известные исключения ты знаешь, что надо сделать: заглушить, залогировать, обернуть и пробросить - это все легитимные варианты. Неизвестные же можно только оставить как есть.

Vasily
03.09.2018
10:26:34
Скорее залогировать

И наверх кинуть Unknown

Bonart
03.09.2018
10:26:49
С неизвестными, в целом , то же самое
Не то же самое - неизвестные всегда открытое множество.

Vasily
03.09.2018
10:27:30
Просто если я начинаю оперировать в логике исключениями, для меня это скорее знак, что что-то пошло не так

Roman
03.09.2018
10:27:32
Bonart
03.09.2018
10:27:36
И наверх кинуть Unknown
А зачем? Шансов обработать корректно больше не станет, а информация пропадет.

Vasily
03.09.2018
10:27:54
Ну у тебя будет дефолтный обработчик на Unknown

Например, рестарт дерева акторов

Bonart
03.09.2018
10:28:28
Например, рестарт дерева акторов
В ответ на StackOverflow? Сомнительно

Roman
03.09.2018
10:28:53
И наверх кинуть Unknown
А вот кидать зачем я хз. Если у тебя в Result уже и так состояние есть, что приложение знает что оно в состоянии ошибки. И ты с ним работаешь как с обычным Result

Vasily
03.09.2018
10:29:05
В ответ на StackOverflow? Сомнительно
Так, давай определимся. Мы о каком классе ошибок говорим?

Roman
03.09.2018
10:29:18
Например, рестарт дерева акторов
Авторы это немного не о том.

Vasily
03.09.2018
10:29:31
Ну я для примера

Roman
03.09.2018
10:30:10
Так, давай определимся. Мы о каком классе ошибок говорим?
Об общем подходе в F#, не углубляясь в специфику фреймворков где кидать ошибки это нормально

Google
Roman
03.09.2018
10:31:24
Хотя там тоже РОП подходит, но там встроенный обработчик. Это специфичный случай кмк

Vasily
03.09.2018
10:53:51
Ну я бы все же в общем случае предложил бинарный подход

То, что можем, обрабатываем

С остальным разбираемся

Попутно увеличивая количество известных нештатных ситуаций

И заворачиваем их в нашу доменную область

Ну и пишем тесты на всякое

Roman
03.09.2018
11:01:34
Ну и пишем тесты на всякое
Конечно, подстраховаться никогда не бывает плохо. Но надо двигаться от бинарной ситуации к полностью управляемому состоянию приложения.

Vladimir
03.09.2018
11:15:34
Зачем везде вставлять трай-кетчи? Делается ровно одна обертка и вуаля.
Потому что разговор был, нужен ли Bug of Exception. Баг может быть в любой функции => надо любую функцию надо оборачивать в трайкетч

Ayrat
03.09.2018
11:26:01
Я за то что если факап ожидаемый, то это и не факап вовсе, а просто другой результат работы функции. Т.е. это нормально ожидать от хттп транспорта таймаута или ещё чо. Чтобы не заебаться, все возможные случаи можно поделить на - ретраибл и неретраибл. Ретраибл после N ретраев становится неретрабил. Реакция на неретраибл тоже ожидаемая должна быть. И это нормально менять флоу в зависимости от исхода, очень конечно спасают DU. Но вот ожидать там стаковерфлоу или аутофмемори точно не стоит, но узнать о нём post mortem надо. Поэтому лазейка для ВНЕЗАПНЫХ крашей нужна, чтобы на верхнем уровне залогировать и умереть.

Roman
03.09.2018
11:33:47
Я за то что если факап ожидаемый, то это и не факап вовсе, а просто другой результат работы функции. Т.е. это нормально ожидать от хттп транспорта таймаута или ещё чо. Чтобы не заебаться, все возможные случаи можно поделить на - ретраибл и неретраибл. Ретраибл после N ретраев становится неретрабил. Реакция на неретраибл тоже ожидаемая должна быть. И это нормально менять флоу в зависимости от исхода, очень конечно спасают DU. Но вот ожидать там стаковерфлоу или аутофмемори точно не стоит, но узнать о нём post mortem надо. Поэтому лазейка для ВНЕЗАПНЫХ крашей нужна, чтобы на верхнем уровне залогировать и умереть.
вот в том-то и прикол что все что ты говоришь "на верхнем уровне" надо опять же обернуть в тот DU Типа type Exceptions = ... | WTFISIT of exception и тогда программа дальше будет работать с Result< 'a , Exceptions> а не ломая все на своем пути исключение будет всплывать в верх по стеку.

Ayrat
03.09.2018
11:34:42
throw пользуюсь только если я попадаю в ситуацию где ну совсем пиздец и надо чтобы отработал тот самый верхний блок, без всяких option

т.е. throw в моём коде - это гарантированная смерть аппликейшна

Ivan
03.09.2018
11:36:19
То есть panic

Страница 692 из 772