metaclass: (Default)
[personal profile] metaclass
Мы тут как-то с [livejournal.com profile] theiced спорили за исключения vs коды ошибок (или null), когда он на дотнете кромешный ад писал.

Вот тут по ссылке http://ivan-gandhi.livejournal.com/1867305.html все расписано самоочевидным образом, чем печальны null, чем хороши исключения, и почему вообще положено использовать Option (Maybe T) в качестве типа для возвращения результата.

У исключений есть еще ценное свойство, которое в Maybe особо не эмулируешь, а в Either будет закат солнца вручную - стеки вызовов. Ну и разные типы ошибок в Maybe тоже не засунешь, Nothing он и есть Nothing. В Either их тоже особо не засунешь, без заворачивания в алгебраический тип по одному конструктору на каждый вид исключения(oh shit, в жабе же все равно исключения checked, это примерно оно и есть).

Date: 2012-02-05 10:16 am (UTC)
From: [identity profile] gds.livejournal.com
меня спрашивают, почему я не использую в коде монаду maybe/option. А вот по примерно таким же причинам. Тип собственно значений -- type option 'a = [ None | Some of 'a ]. И вот, типичны случаи:
1. Всё равно, что там, разбора типа не будет, он не нужен.
2. None и Some x -- оба валидные (для конкретного применения) значения, разбор нужен, обе "ветки" представлены разными кусками кода. "match opt_a with [ None -> proc_none | Some a -> proc_some a ]" выглядит лучше, чем "catch (opt_a >>= proc_some) (fun _ -> proc_none)", тем более, обрабатывается конкретно None, а не "ошибка монады maybe", которая может быть и в proc_some.
3. Some x -- валидное, None -- ошибочное. В этом случае мне всегда нужно выдать что-то внятное (специально следил за подобными случаями, всегда нужно). Хоть тот же "assert False" (который в исключении содержит имя файла + строку + столбец данного assert'а). Либо более подробное сообщение. Либо кинуть более специфическое исключение, "raise (No_phone person_name)". Вариант с монадами потребует как минимум catch, хоть и будет более осмысленно, чем в п.2. А везде, на каждый разбор option 'a лепить как bind, так и catch -- это извращение. Кроме того, можем поймать ошибку разбора более глубокого option 'a.
Итого: монада maybe полезна там, где не суть важно, в каком именно option 'a содержится None. То есть, в стране эльфов.
(функции наподобие container (option 'a) -> option (container 'a) пишутся один раз и под описанное не попадают.)

Date: 2012-02-05 11:39 am (UTC)
From: [identity profile] volodymir-k.livejournal.com
> в жабе же все равно исключения checked

Канделябром за брехню! за невежество!
В жабе и чекед есть, и рантайм, и конструктор с произвольной строкой, и вообще эррор, и полный изрыгабль.

А по смыслу полностью согласен.
Edited Date: 2012-02-05 11:39 am (UTC)

Date: 2012-02-05 11:52 am (UTC)
From: [identity profile] metaclass.livejournal.com
Ну часть иерархии checked, часть unchecked, да.

Date: 2012-02-05 12:46 pm (UTC)
From: [identity profile] sergiej.livejournal.com
Кстати да, null в жабе это адское изобретение. Если бы у функции можно было давать в сигнатуре "обязательность" параметров вместо проверки на налл внутри это сэкономило бы тысячи индусских человеколет. Дошло до того, что пишем автоматические тулы делают проверку есть ли в коде проверка на налл всего и вся. И это уродское isEmpty, брррррр, нанавижу жабу за это.

Date: 2012-02-05 05:02 pm (UTC)
From: [identity profile] blackyblack.livejournal.com
Это всё проблемы от бедности... Статья и выводы выглядят как Poor Man's Pattern Matching. Ну не умеет язык делать красиво и как надо, че ж теперь - правильно писать в таком случае как можно проще и самоочевиднее. То есть для явы максимально правильно возвращать null. В правильных языках возвращать следует монаду или тупл.

Date: 2012-02-05 07:11 pm (UTC)
From: [identity profile] gds.livejournal.com
ход мыслей нравится, а детали подправим.
Возвращать монаду -- нет, только значение, имеющее монадный тип.
(да и то, по сути, если куча вычислений выполняется в MonadError или аналогах, это начинает напоминать старые сраные известные исключения, только часто с оверхедом ниибацо каким.)
Возвращать тупл -- нет, надо возвращать не произведение, а сумму, [ Ok of 'a | Error of 'e ], ну или Either, в котором Left/Right не несут смысловой нагрузки при обработке ошибок.

Date: 2012-02-05 07:31 pm (UTC)
From: [identity profile] blackyblack.livejournal.com
Немного сумбурно - сложновато вас читать. :) Чем плох тупл в обычном виде? Я использовал в эрланге - очень доволен.

Date: 2012-02-05 07:51 pm (UTC)
From: [identity profile] metaclass.livejournal.com
Туплу нужны оба значения пары, а вариантному типу - один из. В случае результата или ошибки, двух значений одновременно быть не может, поэтому тупл тут негоден.

Date: 2012-02-05 07:55 pm (UTC)
From: [identity profile] blackyblack.livejournal.com
Я под туплом имею в виду другую пару. В случае ошибки возвращается тупл {error, Reason}, в случае успеха тупл {ok, Value}. При этом, благодаря тому, что единственное значение можно понимать как тупл с пустым вторым значением, можно честно вернуть ok в случае успеха. Очень удобно.

Date: 2012-02-05 09:47 pm (UTC)
From: [identity profile] gds.livejournal.com
ага, если в эрланге, то всё понятно. Там таким способом представляют sum types. И, действительно, способ удобен для эрланга, в json мне он тоже очень нравится.
А в типизированной функциональщине (в среднем её случае) проявляется такой момент: если функция возвращает тупл, то оба компонента имеют фиксированный тип, то есть, если первый компонент будет представлять "тег" (ok/error), то второй компонент будет обязан иметь какой-то один тип. Если представить ошибку, например, строкой, то и успешный результат будет должен иметь тип строки.
Оттуда и необходимость в индуктивных типах данных -- чтобы разнотипные значения, которые могут включаться в значения данного типа, можно было разделить по тегу, а затем и протипизировать по содержимому (это если грубо передавать "машинерию" процесса).

Date: 2012-02-05 09:56 pm (UTC)
From: [identity profile] gds.livejournal.com
криво сформулировал. предпосылка про первый компонент тупла всегда верна, поэтому текст

"если первый компонент будет представлять "тег" (ok/error), то"

проще исключить из комментария для простоты восприятия.

Date: 2012-02-05 08:21 pm (UTC)
From: [identity profile] kurilka.livejournal.com
Ну в Эрланге нельзя определять свои типы (рекорды тоже лишь сахарок), поэтому вот и получаются тэги типов "ручками"

Date: 2012-02-07 10:01 pm (UTC)
From: [identity profile] thesz.livejournal.com
>В Either их тоже особо не засунешь, без заворачивания в алгебраический тип по одному конструктору на каждый вид исключения(oh shit, в жабе же все равно исключения checked, это примерно оно и есть).

data SomeException where SomeExceptin :: Typeable a => a -> SomeException

Далее Error SomeException и Either SomeException a.

Date: 2012-02-08 05:06 pm (UTC)
From: [identity profile] ilya-portnov.livejournal.com
http://hackage.haskell.org/package/control-monad-exception же!

Profile

metaclass: (Default)
metaclass

April 2017

S M T W T F S
      1
2345678
9101112 131415
16171819202122
23242526272829
30      

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Sep. 24th, 2025 07:52 am
Powered by Dreamwidth Studios