Size: a a a

Programming Offtop

2021 March 23

АT

Андрей Tama in Programming Offtop
Iaroslav Postovalov
Chrome Stable - не падает
У меня падает.
источник

I

Ilmir in Programming Offtop
Алексей Худяков
А как определить как Err надо обрабатывать Err или a?
Так же, как например, в typed/racket или ceylon. if (is Err t) { /* t: Err */ } else { /* t: a */ }
источник

IP

Iaroslav Postovalov in Programming Offtop
Андрей Tama
У меня падает.
Ну вот бракованный :(
источник

VP

Vladimir Petrakovich in Programming Offtop
Рассказ интересный, но Result в прикладном коде днище хотя бы потому, что все функции и так могут кидать исключения
источник

ch

central hardware in Programming Offtop
Iaroslav Postovalov
В контексте Котлина - да
что упало на code verification считается софтом познавшим дзен?
источник

AM

Andrew Mikhaylov in Programming Offtop
Konstantin Dovnar
Та шобы я тут ещё разбирался в этих ваших хаскеля-подобных штуках!
A | B — это A или B, A & B — это A и B одновременно. То есть:
Замена A на A | B — это расширение типа, ты позволяешь использовать новые значения кроме тех, которые были позволены ранее.
Замена A на A & B — это сужение типа, ты запрещаешь использовать некоторые значения, которые раньше были позволены.
Ну а дальше расширение входного параметра и сужение выходного параметра — это операции, не ломающие обратную совместимость на вызывающей стороне.
Точно так же, как, если взять List и Collection, можно заменить
fun <T> f(a: List<T>): Any на fun <T> f(a: Collection<T>): Any
или
fun <T> f(): Collection<T> на fun <T> f(): List<T>
источник

IP

Iaroslav Postovalov in Programming Offtop
Vladimir Petrakovich
Рассказ интересный, но Result в прикладном коде днище хотя бы потому, что все функции и так могут кидать исключения
И еще много причин
источник

KD

Konstantin Dovnar in Programming Offtop
Andrew Mikhaylov
A | B — это A или B, A & B — это A и B одновременно. То есть:
Замена A на A | B — это расширение типа, ты позволяешь использовать новые значения кроме тех, которые были позволены ранее.
Замена A на A & B — это сужение типа, ты запрещаешь использовать некоторые значения, которые раньше были позволены.
Ну а дальше расширение входного параметра и сужение выходного параметра — это операции, не ломающие обратную совместимость на вызывающей стороне.
Точно так же, как, если взять List и Collection, можно заменить
fun <T> f(a: List<T>): Any на fun <T> f(a: Collection<T>): Any
или
fun <T> f(): Collection<T> на fun <T> f(): List<T>
Да, я уже понял. Проблема была лишь в том, что я не понял где там у @ilmirus  были входные данные, а где возвращающийся тип.
источник

KD

Konstantin Dovnar in Programming Offtop
Спасибо
источник

VP

Vladimir Petrakovich in Programming Offtop
Konstantin Dovnar
Та шобы я тут ещё разбирался в этих ваших хаскеля-подобных штуках!
Какой хаскель, дядя, включи логику просто
источник

I

Igor in Programming Offtop
Ilmir
Пришло, видимо, время для моего очередного лонгрида. Это будет rant и бугуртить я буду, как обычно, по поводу статус-кво в функциональных языках. Задену ещё заодно ООП языки и платформы, в том числе JVM. Статус-кво, о котором я буду говорить, опять идёт через хаскель от ML - это ADT.

Ещё до нового года я задался вопросом - что лучше, union типы или ADT с точки зрения дизайна языка. Тогда я не нашёл однозначного ответа. У обоих подходов есть свои плюсы и минусы. Но я уже тогда склонялся в сторону union типов, ибо неявное приведение A к A | B позволяет сократить код и не требует явного вызова конструкторов Left и Right монады Either.

Теперь я знаю точный ответ - ADT - это тупиковый путь развития и должны уступить место union типам. Дело в обратной совместимости. Допустим у нас есть функция f: A -> R и мы хотим добавить новый тип в параметры. В случае union типов функция примет вид f: A | B -> R, в случае же ADT она примет вид f: Either A B -> R. Вроде бы всё одно, отличие только синтаксическое. Тогда в чём же проблема? Проблема в вызывающей стороне. Из-за того, что для Either приходится явно вызывать конструктор, изменение сигнатуры несовместимо. Придётся менять весь пользовательский код. В случае же union типов такой проблемы нет.

Кстати, изменение возвращаемого типа тоже можно сделать обратно-совместимым, если язык поддерживает intersection типы, то есть замена f: A -> R на f: A -> R & T не ломает пользовательский код. Поэтому, кстати, я приветствую обеими руками Dotty. Там хотя бы source совместимость будет сохранена.

К сожалению, сделать изменение ещё и бинарно-совместимым на JVM не выйдет. Только если все типы в сигнатурах функций генерировать как java.lang.Object. Для intersection типов проблем особых нет - можно не менять генерируемый возвращаемый тип. Но для union типов так не выйдет, что ломает всю красоту и весь, мать его, пойнт!

Возвращаясь в нашим баранам, то есть к нулябельности и Result. Добавление нулябельности параметру и убирание нулябельности в возвращаемом значении - бинарно-совместимое изменение, если не использовать инлайн классы. Там из-за манглинга ещё @JvmName надо будет повесить. Вообще, такая проблема присутсвует и для примитивов, поэтому такое поведение соответствует нашему видению, что инлайн классы подобны примитивам. Убирание же Result и замена на сырой тип не бинарно-совместимое изменение, в отличие от некидания исключения. Конечно, исключения всё равно не видны в сигнатуре, а так хотя бы можно сказать, чтобы принимающая сторона проверила на существование значения. Но Result не решает проблему checked exceptions полностью. Из-за как раз проблем обратной совместимости. Идеальное решение должно её принимать во внимание.

TL;DR: Result - это не очень, вернее даже, очень не.
Кстати Result/Either/Maybe/Option это очень частный случай применил DU

Что допустим делать, когда важна семантика которая хранится в теге?
источник

KD

Konstantin Dovnar in Programming Offtop
Vladimir Petrakovich
Какой хаскель, дядя, включи логику просто
К дедуле который никогда код в глаза не видел тоже будешь за его незнания доёбываться?
Ну а чо, логика.
источник

VP

Vladimir Petrakovich in Programming Offtop
Konstantin Dovnar
К дедуле который никогда код в глаза не видел тоже будешь за его незнания доёбываться?
Ну а чо, логика.
Ну кстати чтобы это понять, и код писать необязательно. Но тогда надо знать математику хоть как-то, а требовать такое - уже перебор.
источник

с#

саша сок #KotlinGang... in Programming Offtop
Konstantin Dovnar
Да. Мне казалось речь как-раз об обратном, что A заменится на A | B, что выглядит несовместимым.
в случае ретюрна он привел intersection типы, т.е. замену A -> R на A -> B & R, т.е. когда возвращается не только объект типа B, но и одновременно с этим типа R
источник

I

Ilmir in Programming Offtop
Igor
Кстати Result/Either/Maybe/Option это очень частный случай применил DU

Что допустим делать, когда важна семантика которая хранится в теге?
Что такое DU?
источник

I

Igor in Programming Offtop
Ilmir
Что такое DU?
discriminated union
источник

I

Igor in Programming Offtop
Хотя ладно, в принципе там можно позаворачивания все обертки, добавить alias и получится тот же DU
источник

АХ

Алексей Худяков... in Programming Offtop
Igor
Кстати Result/Either/Maybe/Option это очень частный случай применил DU

Что допустим делать, когда важна семантика которая хранится в теге?
Наворачивать обертки newtype Left a = Left a
источник

АХ

Алексей Худяков... in Programming Offtop
Ilmir
Так же, как например, в typed/racket или ceylon. if (is Err t) { /* t: Err */ } else { /* t: a */ }
Сжечь! Быстро, решительно
источник

АХ

Алексей Худяков... in Programming Offtop
Ilmir
Не вижу пока, как тайпклассы сломаются. Если функция требует, к примеру, Ord, а ей передали, ну не знаю, комплексные числа, будет ошибка компиляции.
Как теперь написать инстанс монады для Either?
источник