Alexey
не совсем понял о чём ты предлагаешь написать
какой план со стандартной либой. потому что если плана нет, то выглядит все тухло.
Alexey
тухло не с точки зрения возможностей языка, а с точки зрения адопшена
Daniel
а не похер ли нам на стандартную либу?
Roman
единственный реалистичный сценарий - это сделать линтер и сделать его популярным. а уж потом и разрабы go подтянутся
я уже об этом мозгую с твоим предложием о постфиксах типов. Ещё не дошёл до этого момента. Так-же сложно оценить сколько времени уйдёт на подобный линтер
Roman
какой план со стандартной либой. потому что если плана нет, то выглядит все тухло.
ну в принципе можно повыискивать парочку примеров из стд либы которые являются subject'ом для иммутабельности
Alexey
а не похер ли нам на стандартную либу?
нет. если все слайсы из всех либ будут мутабельны, то как мне использовать иммутабельные в своей песочнице? конвертировать все? тут даже я забью на иммутабельность
Roman
Только вот делать никто не хочет) А потеоретизировать это с удовольствием
у меня в принципе есть время на линтер сейчас, учитывая что я не женат 😆
Roman
однако не так чтоб прям 8 часов в день
snip
Ну вот два разработчика уже есть) в принципе можно начинать)
snip
А там люди потянутся
Daniel
нет. если все слайсы из всех либ будут мутабельны, то как мне использовать иммутабельные в своей песочнице? конвертировать все? тут даже я забью на иммутабельность
конверсия при передаче параметра произойдет автоматически, так что, скорее всего, больше ничего и не потребуется
Alexey
типичный пример апи которое никак не дружит - Unmarshal в json.
Roman
конверсия при передаче параметра произойдет автоматически, так что, скорее всего, больше ничего и не потребуется
кстати этот вопрос до сих пор открыт. стоит ли implicitly конвертировать non-const в const
Alexey
оно не идиоматично. оно вынуждает меня иметь мутабельный объект
Alexey
Невозможно иметь только иммутабельные структуры и сделать Unmarshall. Сейчас он принимает ссылку на структуру и изменяет ее содержимое. Это не дает вызывающей стороне иметь только иммутабельные структуры. Идиоматичным было бы вернуть новый объект (как передать при этом тип этого объекта остается вопросом)
Daniel
оно не идиоматично. оно вынуждает меня иметь мутабельный объект
конечно, вынуждает. если бы можно было передать тип как тип, а не вместе с указателем - не вынуждало бы. в некоторых местах в java сделано так - передаем объект, но он не модифицируется метод конструирует новые объекты того же типа
Daniel
иногда - инстанс.
Daniel
но мы же не собираемся превращать go в язык с чистыми функциями
Alexey
иногда - инстанс.
я уверен где-то такая конечно есть
Alexey
но мы же не собираемся превращать go в язык с чистыми функциями
от нас слава богу в этом плане мало что зависит
Daniel
поэтому - линтер будет предупреждать о передаче указателя на const объект кудато, где мы не имеем контроля.
Daniel
и можно будет отключить эти ворнинги или все разом, или специальным комментом
Daniel
не, это все еще можно делать без генериков
Daniel
просто result := MyType{} был бы внутри Unmarshal, а не снаружи
Roman
и можно будет отключить эти ворнинги или все разом, или специальным комментом
проблема только то что он будет реально вербозным. Нужно будет reference типы обарачивать в alias типы, уфф..
Alexey
поэтому - линтер будет предупреждать о передаче указателя на const объект кудато, где мы не имеем контроля.
Так тоже не сработает. Можно почитать про опыт котлин и их построения интеропа с джавой. Они отказались от явных проверок на границе в пользу оптимистичного сценария. Можно почитать тут - https://kotlinlang.org/docs/reference/java-interop.html#null-safety-and-platform-types
Roman
просто result := MyType{} был бы внутри Unmarshal, а не снаружи
ну это уже тогда на тему runtime cost (extra memory + CPU time) vs compile-time cost (of generics)
Daniel
проблема только то что он будет реально вербозным. Нужно будет reference типы обарачивать в alias типы, уфф..
ну вот похоже идея с типами так себе. это же и правда надо будет на каждый свой тип создать ему алиас константный. получится масса синтаксического мусора
Roman
просто result := MyType{} был бы внутри Unmarshal, а не снаружи
сейчас таким-же образом устроен assert.IsType(t, ExpectedType{}, actual) в testify, но в тестах конечно пофиг лишний инстанс зафигарить
Daniel
идея с комментом нравится мне больше
Roman
идея с комментом нравится мне больше
а идея с коментом возможно окажется очень некрасивой... хотя..
Daniel
ну вот да, надо таки написать пропозал
Roman
идея с комментом нравится мне больше
func(ref /*const*/ * /*const*/ Object) уфф... тогда уж лучше так: type ObjectConst Object type ObjectPtrConst *ObjectConst func(refConst ObjectPtrConst)
Roman
"шо то хня, шо это хня"))))
Daniel
не надо такого никому
Daniel
const ref - это вообще непонятно, зачем. это же по любому копия, навнешний мир не повлияет, хоть объизменяйся
Alexey
большой минус с комментами в том, что любая опечатка молчаливо съедается, а не вызывает ошибку компиляции
Daniel
большой плюс - их можно сделать уже сейчас
Roman
не надо такого никому
это мы ещё не выяснили на самом деле: https://github.com/romshark/Go-2-Proposal---Immutability#38-whats-the-difference-between-immutable-references-and-references-to-immutables Я пишу абзац "Discussion", там упомяну про облегчённый но ограниченный const pointer но увы, так просто взять и отрезать возможность создания мутабельного слайса немутабельных объектов и наоборот - просто не могу
Daniel
а зачем может быть нужен мутабельный слайс иммутабельных объектов?
Roman
const ref - это вообще непонятно, зачем. это же по любому копия, навнешний мир не повлияет, хоть объизменяйся
constRef не позволит саму переменную аргумента в данном контексте мутировать
Roman
а зачем может быть нужен мутабельный слайс иммутабельных объектов?
ну блин, я не могу решать за всех, это эгоистично))
Daniel
а зачем это нам? какой смысл переменую аргумента защищать?
Daniel
ну блин, я не могу решать за всех, это эгоистично))
реши за себя. это вполне go way, как мы знаем
Roman
теоретически же могут быть такие ситуации, поэтому я не могу их взять и отрезать только ради упрощения синтаксиса
Daniel
почему не можешь?
Roman
большой минус с комментами в том, что любая опечатка молчаливо съедается, а не вызывает ошибку компиляции
это В ПРИНЦИПЕ проблема иммутабельности засчёт линтера. Линтер не компилятор, у него нет прав по рукам бить, лицензию не выдали.
Daniel
ну можно ввести параноидальный режим, когда комментом надо отметить как раз мутабельные параметры
Daniel
или даже и параметры, и переменные :)
Daniel
вот будет счастие :)
Roman
а зачем это нам? какой смысл переменую аргумента защищать?
такой же какой и в иммутабельных переменных по сути. Аргумент тоже переменная из scope'а функции
Alexey
а зачем это нам? какой смысл переменую аргумента защищать?
тут смысл не том, что ты что-то сломаешь, а в том, что если ты ее меняешь, то скорее всего, ты ожидаешь чего-то другого
Daniel
я, коллеги, хочу, чтобы вы придумали код, для которого это важно
Daniel
например - изобрели ошибку, от которой такая конструкция защитит
Roman
например - изобрели ошибку, от которой такая конструкция защитит
ну относительная большая функция, в которой мы случайно мутируем копию аргумента и получаем неправильный state в конце. Это-ж проблема принципиальная. Мы же хотим "при декларации чего-либо - знай, мутабельно ли оно али нет"
Alexey
я, коллеги, хочу, чтобы вы придумали код, для которого это важно
я могу порекомендовать почитать вот это - http://www.lihaoyi.com/post/WhatsFunctionalProgrammingAllAbout.html И эту часть в частности. http://www.lihaoyi.com/post/WhatsFunctionalProgrammingAllAbout.html#preventing-errors-with-functional-programming
Alexey
там как раз пример. надеюсь не го не смутит сильных духом
Roman
https://github.com/qbeon/webwire-go/blob/master/serveHttp.go вот например конкретно мой случай: меня все кодоанализаторы уже своим варнингом о том, что функция превышает макс. уровень когнитивной сложности (branching) и размер (LOC) но когда я пытался её рефакторнуть дабы разбить на более малые функции возникали проблемы и я психовал и просто бросал её оставив как есть. В таких случаях иметь иммутабельные переменные довольно удобно, потому-что со временем можешь поменять то что менять изначально не стоитло.. а так тебя компилятор/линтер за лапу цап! Ап, низзя X в этом контексте менять и ты начинаешь вспоминать "а зачем я тогда делал её иммутабельной..... ааа!"
Alexey
Daniel
хорошо
Roman
func(ref /*const*/ * /*const*/ Object) уфф... тогда уж лучше так: type ObjectConst Object type ObjectPtrConst *ObjectConst func(refConst ObjectPtrConst)
поэтому собственно и иммутабельные переменные и иммутабельные аргументы
Daniel
а теперь изобретите, зачем нужна иммутабельная ссылка на мутабельный объект
Roman
а теперь изобретите, зачем нужна иммутабельная ссылка на мутабельный объект
я это буквально сегодня добавил в документ: When we need a pointer to be immutable to prevent it from pointing to anything other than a certain object, which should be mutable though т.е. сама по себе сущность может меняться внутри, а вот другой объект заместо неё вставить уже нельзя
Alexey
а теперь изобретите, зачем нужна иммутабельная ссылка на мутабельный объект
чтобы описать глобальный мутабельный стейт? Например, кеш