Size: a a a

Programming Offtop

2021 March 23

с#

саша сок #KotlinGang... in Programming Offtop
там сколько не ставь ? - одно и то же
источник

АХ

Алексей Худяков... in Programming Offtop
(
Речь о нуллабельном резулте
Понял. Спасибо
источник

AM

Andrew Mikhaylov in Programming Offtop
Ilmir
Пиздец будет у тебя в штанах, как только ты его попробуешь. Гарантирую!
Ты не думал на полставки девадвокатом поработать? :)
источник

I

Ilmir in Programming Offtop
Andrew Mikhaylov
Ты не думал на полставки девадвокатом поработать? :)
Не, для работы девадвокатом надо делать хорошую мину при плохой игре. Я так не умею.
источник

AM

Andrew Mikhaylov in Programming Offtop
Ilmir
Не, для работы девадвокатом надо делать хорошую мину при плохой игре. Я так не умею.
Так на полставки, только хорошие релизы рекламировать.
источник

I

Ilmir in Programming Offtop
Пришло, видимо, время для моего очередного лонгрида. Это будет 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 - это не очень, вернее даже, очень не.
источник

AM

Andrew Mikhaylov in Programming Offtop
Ilmir
ХМ. Что-то слишком всё просто было. Никаких препятствий. В среду решили разрешить. В четверг зафиксировали решение, в понедельник в мастере, и вот уже во вторник переложили в 1.5.0-RC. Что-то слишком просто: https://github.com/JetBrains/kotlin/commit/f6962dfb752c417ddb91fa69185553d1e8694139
Таки решили никак ?. не переопределять для резалта? :)
источник

I

Ilmir in Programming Offtop
Andrew Mikhaylov
Таки решили никак ?. не переопределять для резалта? :)
Решили не переопределять.
источник

I

Ilmir 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 - это не очень, вернее даже, очень не.
источник

AW

Alex Wells in Programming Offtop
Ilmir
И да, "стабильный" не означает "без багов". "Стабильный" означает "гарантия обратной совместимости".
по моему за это отвечает semver
источник

AW

Alex Wells in Programming Offtop
может быть нестабильный, но с гарантией
источник

V

Vitaly in Programming Offtop
не хватает чела с авой повернутой на 90 и на 270
источник

KD

Konstantin Dovnar in Programming Offtop
>Из-за того, что для Either приходится явно вызывать конструктор, изменение сигнатуры несовместимо.

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

AM

Andrew Mikhaylov in Programming Offtop
Alex Wells
по моему за это отвечает semver
К версионированию котлина семвер отношения особо не имеет.
источник

IP

Iaroslav Postovalov in Programming Offtop
Alexander Nozik
А есть какие-то принципиальные отличия 1.5 от 1.4.30 + IR?
Конечно
источник

IP

Iaroslav Postovalov in Programming Offtop
Моя фича
источник

IP

Iaroslav Postovalov in Programming Offtop
источник

I

Ilmir in Programming Offtop
Konstantin Dovnar
>Из-за того, что для Either приходится явно вызывать конструктор, изменение сигнатуры несовместимо.

Как по мне — это как-раз плюс.
Какого хуя где-то там должна меняться сигнатура, от чего возможно должна измениться логика, но я об этом даже не узнаю на своей принимающей стороне.
Расширение возможностей - совместимое изменение, потому что означает добавление нового без изменения старого. Так что если функция делала A, а теперь делает A | B, то для пользовательского кода, который требует только A и изменений не должно быть.
источник

KD

Konstantin Dovnar in Programming Offtop
Ilmir
Расширение возможностей - совместимое изменение, потому что означает добавление нового без изменения старого. Так что если функция делала A, а теперь делает A | B, то для пользовательского кода, который требует только A и изменений не должно быть.
Я не особо в теме, просто высказался по смущающему меня вопросу.

Но как условная функция, делающая A | B, которая поменяла свою логику и теперь, как я понимаю, может вернуть не A, а либо A, либо B, может для кого-то всегда возвращать A?
источник

I

Ilmir in Programming Offtop
Konstantin Dovnar
Я не особо в теме, просто высказался по смущающему меня вопросу.

Но как условная функция, делающая A | B, которая поменяла свою логику и теперь, как я понимаю, может вернуть не A, а либо A, либо B, может для кого-то всегда возвращать A?
Расширение возвращаемого типа - несовместимое изменение. Его сужение - уже совместимое. Я про это написал.
источник