Pavel
можно же сделать 2 версии компилятора: go1 игнорит volatile и все работает как сейчас, в go2 все кроме volatile -- const 😄
Roman
можно же сделать 2 версии компилятора: go1 игнорит volatile и все работает как сейчас, в go2 все кроме volatile -- const 😄
про обратную совместимость уже всё написано в пропосале, если чего не хватает - дай знать, добавлю
Daniel
это проблемой считать нельзя
Roman
это проблемой считать нельзя
ну вот допустим я вендор библиотеки, мне теперь Go2 и Go1 отдельно поддерживать? Или просто кидать пользователей Go1 и поддерживать только Go2 дабы не распылять своё внимание и время? а что если кто-то не может перейти на Go2 по каким либо причинам? т.е. нам понадобится несколько лет пока все смогут перейти медленно но верно на Go2 и всё это время мне придётся поддерживать 2 версии 1 библиотеки?
Bogdan (SirEdvin)
А то, что нужно вроде как следить за тем, что стоит в системе, хотя на самом деле просто entrypoint с правильной версией питона можно ставить - это считается проблемой?) Мне казалось, что проблема как раз в том, что есть новая модная версия языка, на которой хочется писать и там все круто, а есть безумное количество легаси, которое работает на языке, который стагнирует и легаси в бизнесе тянет за собой легаси в open source проектах. Ну или костыли в виде six и кучу черной магии.
Bogdan (SirEdvin)
Но six в go будет выглядить только как кодогенерия, на мой взгляд
Daniel
или одну, если старую не хочешь. кому надо - тот пусть и поддерживает
Roman
две версии поддерживать, конечно
И это хорошо? Это ужасно, я вам скажу, у меня столько времени нет
Daniel
ну а что делать авторам java библиотек с выходом go? поддерживать две версии? забить на java? забить на go?
Roman
Daniel
ну это уже немного другая ситуация, совершенно разные экосистемы
ну так давайте считать go и go2 разными экосистемами, и не париться
Sergey
ну так давайте считать go и go2 разными экосистемами, и не париться
Авторы го не хотят другой язык, если вам надо вы и делайте
Daniel
авторы go будут делать то, что сочтут нужным
Bogdan (SirEdvin)
ну так давайте считать go и go2 разными экосистемами, и не париться
Дробление сообщества - это существенная проблема для языка программирования, на самом деле.
Daniel
правда, если они будут тянуть обратную совместимость - будут проблемы рано или поздно
Roman
ну так давайте считать go и go2 разными экосистемами, и не париться
кстати, как считаешь, таки будет "реальный" Go 2 в скором или его ещё, веря словам разработчиков, не будет очень долго? потому-что если они запланировали его уже на скажем следующий год то пропосал стоит адресовать на Go 2.x если же нет, то на Go 1.x с пометкой о том, как можно бы было сделать в Go 2.x ещё лучше
Sergey
Это спор ни о чем, авторы го свое мнение озвучили, а остальное это дрочерство Ну и каждые 5 лет новую экосистему это конечно же бред
Daniel
собственно - пока он не нужен
Roman
я думаю, его не будет никогда
у меня аналогичное чувство. Поэтому таки концентрируемся на Go => 1.12
Daniel
угу
Roman
Это спор ни о чем, авторы го свое мнение озвучили, а остальное это дрочерство Ну и каждые 5 лет новую экосистему это конечно же бред
а что конкретно авторы озвучили? насколько я знаю они сказали лишь что "его не будет ещё очень долгое время, потому-что у нас Go 1 compatibility promise"
Roman
я не знаю как авторы определяют "очень долгое время", может для них год это уже очень долго... хотя с итерациями в пол-года конечно можно предположить что это наверное лет эдак 5
Roman
Насколько я помню Истории а-ля питон 2/3 не будет и го 2 это где то го 1.15-1.16
да, я вкурсе, поэтому пропосал и пишу исходя из Go => 1.12
Roman
поэтому - иммутабельности всего по умолчанию и ключевого слова mut, увы - не быть
Pawel
правда, если они будут тянуть обратную совместимость - будут проблемы рано или поздно
что значит "если"? они постоянно подчёркивают, что ничего ломать не будут точно
Daniel
это просто мое мнение, ни на что не влияющее :)
Roman
поэтому ради общего блага я пока-что решил использовать менее ограничивающий, но более громоздкий вариант, когда указатель или slice отдельно от объекта анотируется на (и)мутабельность worst case: const map[const * const Object] const * const Object иммутабельный мап, с иммутабельным указателем на иммутабельный объект в качестве ключа на иммутабельный указатель на иммутабельный объект если кому-то данная тема интересна то буду рад обсудить аргументы за упрощённый, но ограничивающий вариант
В таком случае получается: // Immutable pointer to mutable object var immut2mut const *Object = &Object{} immut2mut = &Object{} // violation! immut2mut.Field = 42 // fine immut2mut.Mutation() // fine /*--------*/ // Mutable pointer to immutable object var mut2immut * const Object = &Object{} mut2immut = &Object{} // fine mut2immut.Field = 42 // violation! mut2immut.Mutation() // violation! /*--------*/ var immut2immut const * const Object = &Object{} immut2immut = &Object{} // violation! immut2immut.Field = 42 // violation! immut2immut.Mutation() // violation! тоже самое касается контейнеров: // Immutable slice of immutable objects var immut2immut const [] * const Object immut2immut = append(immut2immut, Object{}) // violation! immut2immut[0] = Object{} // violation! p1 := immut2immut[0] p1.Mutation() // violation! /*--------*/ // Mutable slice of immutable objects var mut2immut [] * const Object mut2immut = append(mut2immut, Object{}) // fine mut2immut[0] = Object{} // fine p2 := mut2immut[0] p2.Mutation() // violation! /*--------*/ // Immutable slice of mutable objects var immut2mut const [] *Object immut2mut = append(immut2mut, Object{}) // violation! immut2mut[0] = Object{} // violation! p2 := immut2mut[0] p2.Mutation() // fine /*--------*/ // Mutable slice of mutable objects var mut2mut [] *Object mut2mut = append(mut2mut, Object{}) // fine mut2mut[0] = Object{} // fine p2 := mut2mut[0] p2.Mutation() // fine
Pawel
Поповоду const объектов. Вот допустим их таки добавят (хотя шансов нет, аналогичных предложений много висит, их игнорят). Вроде бы всё гут, но я лично вижу в этом две проблемы 1. Эстетическая. Добавится писанины, const будет по всюду, и выглядеть это будет как Rust 2. Перформанс. Появится возможность писать неэффективные функции вида "получить const-объект - вернуть модифицированный"
Pawel
Поповоду const объектов. Вот допустим их таки добавят (хотя шансов нет, аналогичных предложений много висит, их игнорят). Вроде бы всё гут, но я лично вижу в этом две проблемы 1. Эстетическая. Добавится писанины, const будет по всюду, и выглядеть это будет как Rust 2. Перформанс. Появится возможность писать неэффективные функции вида "получить const-объект - вернуть модифицированный"
в языках с ленивостью и персистентностью копии в таких случаях не создаются (теоретически, практически конечно же все структуры данных плоские и копии таки создаются). А в Го так нельзя, и придётся всё копировать. А думать о том, делать ли объект стразу же на этапе проектирования константным - лень. Рефакторить тип из константности в мутабельность или обратно - тоже лень. В итоге получим много классического говнокода
Pawel
2? Вообще-то в copy-on-write и смысл 😅 А где надо можно и не писать const.
я точно не знаю где надо и где не надо. и это завтра скорее всего изменится
Roman
Поповоду const объектов. Вот допустим их таки добавят (хотя шансов нет, аналогичных предложений много висит, их игнорят). Вроде бы всё гут, но я лично вижу в этом две проблемы 1. Эстетическая. Добавится писанины, const будет по всюду, и выглядеть это будет как Rust 2. Перформанс. Появится возможность писать неэффективные функции вида "получить const-объект - вернуть модифицированный"
1. Эстетика против безопасности… То что в код может прокрасться баг, который может стоить бизнес серьёзные деньги и на который ты потратишь часы дебажа и кучу нервов - это пустяки. Главное код красивый 🙃 2. Performance это immutabilit станет только лучше, уйдёт ненужное копирование + можно будет строить оптимизации основанные на иммутабельности. P.S. быть с точки зрения похожим на Rust это разве плохо? (не с точки зрения синтаксиса и эстетики)
Pavel
но в моей практике обычно код и горячие циклы в приложении статичны очень долго после фазы активной разработки
Pavel
ты добавляешь новый функционал, но редко делаешь большие рефакторинги
Pawel
как и завтра твой код может стать ненужным
но не весь. частично он мне скорее всего пригодится. и вот такие вещи как const серьёзно усложнят рефакторинг.
Pavel
и часто ты рефакторишь прям с руки типа много чего переписать за раз? что у тебя прям архитектура приложения меняется?
Pavel
это просто вопрос, не имеет отношения к const, мне const не нравится тоже -- слишком долго писать const const const
Roman
shared state, это, ребята, сложно. shared state, это опасно. но shared state, это часто производительнее и порой практически неизбежимо так вот чтоб сделать shared state - менее опасным, нужна compiler-enforced иммутабельность
Daniel
на счёт серёзных багов я не уверен совсем. Ни разу не сталкивался на практике. Были какие-то казусы и очепятки, но и только
это очень редкий баг, но один из самых трудных его трудно заметить его трудно идентифицировать его бывает очень трудно исправить
Pawel
один только pointer aliasing чего стоит.
но это больше к самоконтролю относится, чем к переиспользованияю кода. Безопасный код, в котором кишки изолированы, несколько сложнее писать, зато значительно проще читать - ну так это самый что ни на есть Go way. Поясню. Не все типы из пакета входят в апи модуля. Те немногие, которые входят, надо сделать безопасными, скрыть все слайсы, мапы и пйнтеры, изолировать нужные методы. Такой код читать на много проще, чем АПИ с константными объектами
Daniel
коллега
Daniel
вы с каким тезисом спорите
Pawel
Pavel
это очень редкий баг, но один из самых трудных его трудно заметить его трудно идентифицировать его бывает очень трудно исправить
а какой процент трудных багов предотвратило бы обкладывание констами в вашем опыте за последние года два?
Pavel
константы != иммутабельные символы
там не написано константы
Roman
там не написано константы
действительно, извиняюсь
Pawel
Aleksandr
Забавное из комментов: Наполовину офтоп, но раз уж речь зашла о го и оптимизациях, недавно разработчики решили выпилить ассемблерные версии алгоритма шифрования RC4 (ибо алгоритм слабый, а поддерживать ассемблер не хочется). После бенчмарков оказалось, что нынче код на го быстрее того ассемблера, что использовался в пакете. На треть.
Pavel
действительно, извиняюсь
Роман ну вы тоже можете ответить про свой опыт 🙂
Pawel
Вот кстати годный пропозал в плане добавления тру иммутабельности если кто не в курсах https://docs.google.com/document/d/1UKu_do3FRvfeN5Bb1RxLohV-zBOJWTzX0E8ZU1bkqX0/edit#heading=h.2wzvdd6vdi83
Pawel
тут я зв обеими руками
Pawel
это очень редкий баг, но один из самых трудных его трудно заметить его трудно идентифицировать его бывает очень трудно исправить
и опять пришли к делеме "настваить кодеру палок в колёса дабы не накосячил". В случае с const - самому себе
Mike
Лёгкий оффтоп на тему: с тех пор как в js появились лет и конст, га практике 90% переменных стали конст, и рука уже на автомате их так объявляет, и многие баги прям по ходу написания улавливаются так.
Mike
и опять пришли к делеме "настваить кодеру палок в колёса дабы не накосячил". В случае с const - самому себе
Ты чё, наставлять кодеру палки в колеса -- это охуенно. Чем больше ограничений, тем более предсказуем код становится
Pavel
😂😂
Mike
но использовать const или нет -- это не ограничение, это еще один выбор
Ограничение. Один раз заюзал -- и вот твоя переменная ограничена
Mike
И дальше ты уверен, что ее не поменяют => предсказуемость
Mike
(для прояснения -- из всех языков, на которых я писал, самый любимый -- кложурка)
Pawel
Ты чё, наставлять кодеру палки в колеса -- это охуенно. Чем больше ограничений, тем более предсказуем код становится
тебе бы на хаскилях и растах пописать чтобы ты понял насколько это действительно охуенно.
Pavel
Ограничение. Один раз заюзал -- и вот твоя переменная ограничена
А один раз не заюзал -- и вот снова тлен и безысходность....
Mike
Но медленно писалось, так что в прод не тащу пока
Roman
а какой процент трудных багов предотвратило бы обкладывание констами в вашем опыте за последние года два?
я не смогу спонтанно перечислить конкретные случаи за последние пару лет, надо вспоминать. Но я могу с уверенно сказать что эти проблемы были самыми грязными и стабильно портили настроение, потому-что дебажить их то ещё удовольствие! я вам дам аналогию для более простого понимания: зачем нам в Go int32 и int64? Если Go это про простоту, то зачем усложнять и просто не оставить int а там пускай компилятор решает где это 32 а где 64 bit. Причина на то имеется, и она называется integer overflow и все вы её прекрасно знаете. так вот если бы мы не смогли предсказать, где 64 а где 32, то очень легко можно бы было придти к неверным вычислениям, и сразу этого не заметить, а потом потерять из-за этого кучу бабла, реального, зелёного, когда 2,147,483,647 вдруг превратится в 4200, хотя код компилируется и работает. С pointer aliasing’ом проблема такая-же. Код компилируется, а программа выдаёт бредовые результаты и хер пойми почему, особенно когда не ты один работал над кодом да ещё и возможно со сторонними библиотеками. зачем нам типизация? да для того чтоб работать в команде было легче, чтоб кто-нибудь по невнимательности не передал слона в жирафа. А иммутабельность это всё эщё про систему типов, она просто ещё более конкретизирут типы раздeляя их на мутабельные и немутабельные, для того, чтоб кто нибидь случайно не оторвал нашему слону хобот, там, где ожидается полноценый слон
Pawel
Карч я пожытожу свою мыслю, ок? const * const: - задолбёшся писать - задолбёшся читать - рано или поздно напорешься на тормоза с копированием как в C++ - в плане бонусов и плюшек получишь в итоге пшик
Daniel
так, все, я здолбался колеги, сворачиваем дискуссию pawel может голосовать против, если пропозал доберется до голосования
Pavel
я не смогу спонтанно перечислить конкретные случаи за последние пару лет, надо вспоминать. Но я могу с уверенно сказать что эти проблемы были самыми грязными и стабильно портили настроение, потому-что дебажить их то ещё удовольствие! я вам дам аналогию для более простого понимания: зачем нам в Go int32 и int64? Если Go это про простоту, то зачем усложнять и просто не оставить int а там пускай компилятор решает где это 32 а где 64 bit. Причина на то имеется, и она называется integer overflow и все вы её прекрасно знаете. так вот если бы мы не смогли предсказать, где 64 а где 32, то очень легко можно бы было придти к неверным вычислениям, и сразу этого не заметить, а потом потерять из-за этого кучу бабла, реального, зелёного, когда 2,147,483,647 вдруг превратится в 4200, хотя код компилируется и работает. С pointer aliasing’ом проблема такая-же. Код компилируется, а программа выдаёт бредовые результаты и хер пойми почему, особенно когда не ты один работал над кодом да ещё и возможно со сторонними библиотеками. зачем нам типизация? да для того чтоб работать в команде было легче, чтоб кто-нибудь по невнимательности не передал слона в жирафа. А иммутабельность это всё эщё про систему типов, она просто ещё более конкретизирут типы раздeляя их на мутабельные и немутабельные, для того, чтоб кто нибидь случайно не оторвал нашему слону хобот, там, где ожидается полноценый слон
ну во первых компилятор может всегда делать int64, во вторых как-то скучно я живу, что у меня за два года не было ни одного такого бага 😅