@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) низзя.

Bonart
03.09.2018
10:17:19
Нет. 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
Скорее залогировать

Admin
ERROR: S client not available

Vasily
03.09.2018
10:26:44
И наверх кинуть 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:30:23
Хотя там тоже РОП подходит, но там встроенный обработчик. Это специфичный случай кмк

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