И снова про итераторы…
Если прошлое предложение от Расса показывало как будут выглядеть итераторы, то новое предложение показывает как мы будем ими пользоваться и готовит для этого огромный фундамент.
✅ У нас появятся новый пакет
✅ У нас будет четкий стандарт именования функций которые возвращают итераторы.
❗ Если итерация может провалится, правильным и идиоматичным типом итератора будет
❗ Нам дадут функцию для преобразования наших pull итераторов в push:
‼️ И главное: нам сразу подвезут кучу обновлений пакетов: strings, bytes, regexp а так-же обновления недавних slices и maps. Самих новых функций там очень много, судя по всему Расс учел опыт добавления дженериков, когда новую фичу привезли, а вот изменений в стандартную библиотеку под нее не привезли. Так же нас ждет пакет xiter (правда пока в exp модуле) которые даст большое число операций над этими самыми итераторами. Да-да ваши любимые
Сам proposal состоит из нескольких частей, там довольно много и подробно описано, поэтому если хотите вникнуть - рекомендую ознакомится с оригиналом. А сам релиз Go 1.22 похоже обещает быть не менее интересным чем релиз Go 1.18. Ждем…
Если прошлое предложение от Расса показывало как будут выглядеть итераторы, то новое предложение показывает как мы будем ими пользоваться и готовит для этого огромный фундамент.
✅ У нас появятся новый пакет
iter и два новых типа: Seq[V any] и Seq2[K, V any] которые будут описывать итераторы. Общий тип просили в первом обсуждении итераторов.✅ У нас будет четкий стандарт именования функций которые возвращают итераторы.
❗ Если итерация может провалится, правильным и идиоматичным типом итератора будет
iter.Seq2[MyType, error]. Соответсвенно каждый шаг сможет сам проверить себя на ошибку.❗ Нам дадут функцию для преобразования наших pull итераторов в push:
func iter.Pull(seq iter.Seq[K,V]) (func() (K, V), stop func()) которая возвращает функцию для получения следующего элемента из итератора и функцию для его остановки. Здесь Расс еще раз напоминает, что писать push итераторы проще, процесс подготовки к работе и очистки у них делается в рамках одного потока управления, а не в разных функциях. А чем проще, тем меньше шанс совершить ошибку.‼️ И главное: нам сразу подвезут кучу обновлений пакетов: strings, bytes, regexp а так-же обновления недавних slices и maps. Самих новых функций там очень много, судя по всему Расс учел опыт добавления дженериков, когда новую фичу привезли, а вот изменений в стандартную библиотеку под нее не привезли. Так же нас ждет пакет xiter (правда пока в exp модуле) которые даст большое число операций над этими самыми итераторами. Да-да ваши любимые
Map, Filter, Concat, Merge, Zip — все это там будет.Сам proposal состоит из нескольких частей, там довольно много и подробно описано, поэтому если хотите вникнуть - рекомендую ознакомится с оригиналом. А сам релиз Go 1.22 похоже обещает быть не менее интересным чем релиз Go 1.18. Ждем…
GitHub
iter: new package for iterators · Issue #61897 · golang/go
We propose to add a new package iter that defines helpful types for iterating over sequences. We expect these types will be used by other APIs to signal that they return iterable functions. This is...
🔥17❤1
Персональная запись: сегодня мне исполнился 31 год.
Сегодня, как и в каждом году, в этот день и месяц, число прожитых мной лет снова сделало инкремент на единицу. Это будет небольшая персональная заметка о том, что было и возможно будет.
Идея вести такой список заметок по Go родилась спонтанно. Я довольно часто скидывал в чатики инфу про новые фичи или интересные, на мой взгляд, обсуждения в сообществе. Предложения от разработчиков языка, предложения от сообщества, тренд общей эволюции языка и свои, не редко критичные, мысли по этому поводу. Обьяснения зачем эти нововведения вообще нужны. После одного из таких сообщений, Коля Тузов (@justskiv) предложил мне начать вести блог, куда я буду структурированно это все писать. Структурированно требует сил и времени, это не напишешь в двух словах ибо нужно попытаться развить и обьяснить свою мысль. По этой причине я изначально отказывался.
Но потом, после очередного настойчивого предложения от Коли 😄, мне стало понятно, что число и смысл обсуждений, за которыми я слежу, начинает выпадать из моей памяти. А главное выпадают мысли по поводу этих обсуждений и нововведений. И стало понятно, что ценность такого блога будет не только в том, что увидят другие, но и в том, что спустя время смогу увидеть я и вспомнить свои собственные мысли. Такие заметки на полях имеют ценность сами по себе. И я наконец решился…
Из других изменений: я недавно побывал в Чили. Про этот опыт мы скорее всего будем делать подкаст с Колей, вместе с обуждением работы над опенсорс проектом в распределенной команде — там есть о чем рассказать и подумать, как для тех кто думает о релокации, так и для тех кто считает что Латинская Америка это «апельсины, анаконда и амазонка».
Вообще отслеживание изменений это очень интересная штука. Когда я создавал этот канал, я думал тут будет максимум 100 подписчиков, так как тема довольно специфична. Как мне казалось большинству разработчиков вообще все равно, что там под капотом и куда движется сам язык (моя личная боль на собеседованиях). Однако нас уже больше 800 и восходящий тренд, судя по всему, не собирается останавливаться. За что отдельное спасибо всем и каждому из вас: если кто-то из вас узнал что-то новое для себя из моих записок, значит это все было не зря.
О будущем: в ноябре, если все пойдет нормально, я буду выступать на GolangConf 2023 с докладом про эволюцию языка, где я попытаюсь структурировать все те изменение которые мы видели за последние годы и так-же те изменения которые нам только предстоит увидеть. Попытаюсьповодить руками над прозрачным шаром вывести тренд. Язык действительно теряет частичку своей простоты, но я уверен, что мы по прежнему сможем найти тот баланс между простотой и удобством, которые находили все эти годы. Мы уже проходили все это с каналами и контекстами, сможем и тут.
А в заключении вот что: такая запись это исключение. Моей изначальной идеей был и остается строго технический канал который охватывает ядро языка и небольшую часть экосистемы вокруг. Уже существует достаточно каналов которые рассказывают про новые библиотеки или крутые истории от пользователей языка. А вести блог про свои мысли о реальности в целом я бы наверное не стал: уже и так есть большое число людей, которые транслируют поток своего мозга в интернет 24/7.
Но все же, как мне кажется, один раз в году можно сделать такое допущение. В конце концов, будет о чем подумать ровно через год, в этот день и месяц.
И конечно же: Show must go on…
Сегодня, как и в каждом году, в этот день и месяц, число прожитых мной лет снова сделало инкремент на единицу. Это будет небольшая персональная заметка о том, что было и возможно будет.
Идея вести такой список заметок по Go родилась спонтанно. Я довольно часто скидывал в чатики инфу про новые фичи или интересные, на мой взгляд, обсуждения в сообществе. Предложения от разработчиков языка, предложения от сообщества, тренд общей эволюции языка и свои, не редко критичные, мысли по этому поводу. Обьяснения зачем эти нововведения вообще нужны. После одного из таких сообщений, Коля Тузов (@justskiv) предложил мне начать вести блог, куда я буду структурированно это все писать. Структурированно требует сил и времени, это не напишешь в двух словах ибо нужно попытаться развить и обьяснить свою мысль. По этой причине я изначально отказывался.
Но потом, после очередного настойчивого предложения от Коли 😄, мне стало понятно, что число и смысл обсуждений, за которыми я слежу, начинает выпадать из моей памяти. А главное выпадают мысли по поводу этих обсуждений и нововведений. И стало понятно, что ценность такого блога будет не только в том, что увидят другие, но и в том, что спустя время смогу увидеть я и вспомнить свои собственные мысли. Такие заметки на полях имеют ценность сами по себе. И я наконец решился…
Из других изменений: я недавно побывал в Чили. Про этот опыт мы скорее всего будем делать подкаст с Колей, вместе с обуждением работы над опенсорс проектом в распределенной команде — там есть о чем рассказать и подумать, как для тех кто думает о релокации, так и для тех кто считает что Латинская Америка это «апельсины, анаконда и амазонка».
Вообще отслеживание изменений это очень интересная штука. Когда я создавал этот канал, я думал тут будет максимум 100 подписчиков, так как тема довольно специфична. Как мне казалось большинству разработчиков вообще все равно, что там под капотом и куда движется сам язык (моя личная боль на собеседованиях). Однако нас уже больше 800 и восходящий тренд, судя по всему, не собирается останавливаться. За что отдельное спасибо всем и каждому из вас: если кто-то из вас узнал что-то новое для себя из моих записок, значит это все было не зря.
О будущем: в ноябре, если все пойдет нормально, я буду выступать на GolangConf 2023 с докладом про эволюцию языка, где я попытаюсь структурировать все те изменение которые мы видели за последние годы и так-же те изменения которые нам только предстоит увидеть. Попытаюсь
А в заключении вот что: такая запись это исключение. Моей изначальной идеей был и остается строго технический канал который охватывает ядро языка и небольшую часть экосистемы вокруг. Уже существует достаточно каналов которые рассказывают про новые библиотеки или крутые истории от пользователей языка. А вести блог про свои мысли о реальности в целом я бы наверное не стал: уже и так есть большое число людей, которые транслируют поток своего мозга в интернет 24/7.
Но все же, как мне кажется, один раз в году можно сделать такое допущение. В конце концов, будет о чем подумать ровно через год, в этот день и месяц.
И конечно же: Show must go on…
🔥76👏12👍10❤9
📝 Изменение формата имени версий Go начиная с Go 1.21
Начиная с Go 1.21 любая версия Go теперь всегда именуется как Go
Проще всего понять на примерах:
→ Ранее Go 1.20 был и именем версии языка и именем первого релиза в ней. Т.е. для первого релиза
→ Начиная с Go 1.21 это только имя версии языка. Первый релиз в этой версии называется
Т.е. первый релиз в версии теперь всегда содержит в конце ноль.
А важно это по одной простой причине:
- Для первого релиза Go 1.20 была ссылка на скачивание https://storage.googleapis.com/golang/go1.20.linux-amd64.tar.gz
- ❗Для первого релиза Go 1.21 ссылка на скачивание стала https://storage.googleapis.com/golang/go1.21.0.linux-amd64.tar.gz а старый формат ссылки выдаст 404.
Не пропустите это когда будете обновлять ваши CI скрипты.
Начиная с Go 1.21 любая версия Go теперь всегда именуется как Go
x.yy.zz взамен старого формата x.yy[.zz] где .zz не применялось для первого релиза внутри версии. Проще всего понять на примерах:
→ Ранее Go 1.20 был и именем версии языка и именем первого релиза в ней. Т.е. для первого релиза
go version возвращал go version go1.20 linux/amd64 для второго релиза go version go1.20.1 linux/amd64 и так далее.→ Начиная с Go 1.21 это только имя версии языка. Первый релиз в этой версии называется
1.21.0. Т.е. для первого релиза go version возвращает go version go1.21.0 linux/amd64 для второго релиза go version go1.21.1 linux/amd64 и так далее.Т.е. первый релиз в версии теперь всегда содержит в конце ноль.
А важно это по одной простой причине:
- Для первого релиза Go 1.20 была ссылка на скачивание https://storage.googleapis.com/golang/go1.20.linux-amd64.tar.gz
- ❗Для первого релиза Go 1.21 ссылка на скачивание стала https://storage.googleapis.com/golang/go1.21.0.linux-amd64.tar.gz а старый формат ссылки выдаст 404.
Не пропустите это когда будете обновлять ваши CI скрипты.
👍20❤1
… Оказывается Телеграм считает ветку комментариев к каждому сообщению в канале отдельно, а просто сообщения в общий чат идут отдельно, но сам общий чат содержит в себе все комментарии. Из-за этого часть моих ответов, которые были без цитирования, походу никто не увидел вообще, хах.
Ссылка на общий чат.
Ссылка на общий чат.
🗿5👍3
🟢 Быстрая установка нужной версии компилятора Go без замены текущей.
Раз пошло обсуждение о том, как установить Go 1.21 не удаляя старую (и без менеджеров пакетов) — на самом деле все довольно просто:
Для текущего мастера:
Полный список https://pkg.go.dev/golang.org/dl - там есть версии Go до 1.5 включительно.
Вот так легко можно поиграться с фичами Go которые еще находятся в разработке.
Раз пошло обсуждение о том, как установить Go 1.21 не удаляя старую (и без менеджеров пакетов) — на самом деле все довольно просто:
$ go install golang.org/dl/go1.21.0@latest
$ go1.21.0 download$ go1.21.0 run main.goДля текущего мастера:
$ go install golang.org/dl/gotip@latest
$ gotip download$ gotip run main.go
Полный список https://pkg.go.dev/golang.org/dl - там есть версии Go до 1.5 включительно.
gotip кстати умный - ему можно скормить бранч через gotip download BRANCHNAME или конкретный CL (PR) через gotip download CL-NUMBER. Номер всегда видно в конкретном ревью - например для https://go-review.googlesource.com/c/tools/+/518376/ комманда будет gotip download 518376.Вот так легко можно поиграться с фичами Go которые еще находятся в разработке.
🔥26👍8
Улучшенный эскейп анализ для слайсов байт полученных из строк.
Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #2205 read-only escape analysis and avoiding string -> []byte copies.
Допустим у вас есть код:
Сейчас вызов
По копии на каждую итерацию. А все из-за того, что при преобразовании из строки в слайс байт, эскейп анализ предполагает, что мы будем этот слайс байт по всякому редактировать. А раз строки у нас неизменяемые, то значит надо бы скопировать всю строку в новый слайс перед передачей его дальше в функцию. Это, в свою очередь, приводит к полной копии строки, что в чутких к производительности местах может быть довольно неприятно.
Однако уже в Go 1.22 эксейп анализ научится пробегать дерево вызываемых функций и пытаться доказать, что слайс байт мы все же не меняем (или эта строка нигде более не используется). И как следствие, копию можно уже не делать.
На
Никаких больше копий при конвертации из строки в слайс, если мы будем только читать из слайса.
Из маленького, но приятного: наконец решили и закрыли одну из четырехзначных задач (сие значит очень старая задача, скорее всего еще из старого трекера) - #2205 read-only escape analysis and avoiding string -> []byte copies.
Допустим у вас есть код:
package main
import (
"strings"
"testing"
)
var Index int
func BenchmarkStrToSlice(b *testing.B) {
someStr := strings.Repeat("HELLO WORLD", 6)
for i := 0; i < b.N; i++ {
Index = indexByte([]byte(someStr), 'D')
}
}
func indexByte(s []byte, c byte) int {
// Я про bytes.IndexByte(s, c) которая быстрее.
// Эта функция здесь находится для демонстрации.
for i, b := range s {
if b == c {
return i
}
}
return -1
}
Сейчас вызов
go test -benchmem -bench . выдаст примерно такие результаты:BenchmarkStrToSlice-10 46341886 22.75 ns/op 80 B/op 1 allocs/opПо копии на каждую итерацию. А все из-за того, что при преобразовании из строки в слайс байт, эскейп анализ предполагает, что мы будем этот слайс байт по всякому редактировать. А раз строки у нас неизменяемые, то значит надо бы скопировать всю строку в новый слайс перед передачей его дальше в функцию. Это, в свою очередь, приводит к полной копии строки, что в чутких к производительности местах может быть довольно неприятно.
Однако уже в Go 1.22 эксейп анализ научится пробегать дерево вызываемых функций и пытаться доказать, что слайс байт мы все же не меняем (или эта строка нигде более не используется). И как следствие, копию можно уже не делать.
На
gotip test -benchmem -bench . результаты обнадеживают:BenchmarkStrToSlice-10 248279863. 4.707 ns/op 0 B/op 0 allocs/opНикаких больше копий при конвертации из строки в слайс, если мы будем только читать из слайса.
GitHub
cmd/compile: read-only escape analysis and avoiding string -> []byte copies · Issue #2205 · golang/go
Many functions take a []byte but only read from it. If the escape analysis code could flag parameters of a function as read-only, then code which passes in a []byte(string) conversion could be chea...
👍42🔥11❤2
cmp: add Or
Недавно принятый небольшой proposal, не от авторов языка (что не такая уж и редкость), суть которого в очень простой функции — получение первого не пустого элемента из произвольного набора. Несмотря на то, что предложение кажется странным, подобная функция встречается достаточно часто на практике. Изначальный proposal был про получение первой не пустой строки из набора строк, но в итоге было решено сделать обобщенную функцию которая подходит для любых типов. И тут начались проблемы…
Я уже говорил о том, что proposal о
Ссылка для желающих поиграться на практике.
Недавно принятый небольшой proposal, не от авторов языка (что не такая уж и редкость), суть которого в очень простой функции — получение первого не пустого элемента из произвольного набора. Несмотря на то, что предложение кажется странным, подобная функция встречается достаточно часто на практике. Изначальный proposal был про получение первой не пустой строки из набора строк, но в итоге было решено сделать обобщенную функцию которая подходит для любых типов. И тут начались проблемы…
Я уже говорил о том, что proposal о
zero ждут авторы кода с дженериками? Так вот это тот самый случай: сейчас cmp.Or нельзя реализовать без использования констрейнта comparable на дженериках. Который, в свою очередь, не работает с любыми типами внутри которых есть несравниваемые поля - например слайсы. А разгадка проста: для сравнения с нулем/пустой переменной сейчас авторы дженерик кода вынуждены создавать пустую переменную и проводить сравнивание с ней. Что довольно сильно ограничивает список типов с которыми такой код может работать.Ссылка для желающих поиграться на практике.
GitHub
cmp: add Or · Issue #60204 · golang/go
An extremely common string operation is testing if a string is blank and if so replacing it with a default value. I propose adding First(...strings) string to package strings (and probably an equiv...
👍5😐3👀2
🐞reflect: Value.IsZero should report true for negative zero
Довольно интересный баг в реализации
В Go 1.20 и 1.21 ответ будет true false
Реализация обработки чисел с плавающей точкой внутри
Баг уже исправлен и фикс будет включен в Go 1.22. Так как этот фикс приводит к изменению поведения его скорее всего не будет в багфиксах существующих релизов.
П.С: Про интересное скоро будет, мне пока чудовищно не хватает времени.
Довольно интересный баг в реализации
reflect.Value.IsZero который происходит из попытки ответить на вопрос: а что выведет вот такой код?val := math.Copysign(0, -1) // Создаем float64(-0.0)
println(val == 0, reflect.ValueOf(val).IsZero())
Реализация обработки чисел с плавающей точкой внутри
IsZero в версиях 1.21 и ниже вызывает функцию math.Float64bits и затем сравнивает результат с 0. Это верно для общего случая, но вот для числа -0 результат вызова этой функции будет совсем не 0. При этом Go компилятор корректно обрабатывает такое сравнение в обычном коде, что и приводит к разным результатам.Баг уже исправлен и фикс будет включен в Go 1.22. Так как этот фикс приводит к изменению поведения его скорее всего не будет в багфиксах существующих релизов.
П.С: Про интересное скоро будет, мне пока чудовищно не хватает времени.
GitHub
reflect: Value.IsZero should report true for negative zero · Issue #61827 · golang/go
I discovered this while exploring #61372 (comment). In that comment, I asked whether v == zero is identical to reflect.ValueOf(&v).Elem().IsZero(). And the answer is unfortunately, "no&quo...
😨17🔥2👍1
Про интересное: intern package proposal
Практически все разработчики сталкиваются с проблемой уникальности данных на уровне приложения. Чаще всего это вопрос удаления повтора строк, т.к. именно этот тип данных является самым «ходовым» в случае работы с хранилищами. А где хранилища, там и кеши и вопрос о затратах памяти. И рано или поздно, в любой достаточно сложной системе кеширования встает вопрос дедупликации - хранить повторяющиеся строки уж очень дорого на больших обьемах данных.
Неофиты спросят: «а в чем проблема? Почему нельзя использовать обычный словарь под мьютексом?». И ведь правда, мы можем использовать тип
В языках со сборщиком мусора, типо Java и C#, для решения этой проблемы есть специализированные типы (
Однако если чему-то сопротивляться, это не значит, что в этом чем-то пропадет потребность. Модуль go4.org/intern содержит в себе реализацию такой системы дедупликации значений. Авторами этого пакета являются разработчики Tailscale, часть из которых либо являлись частью Go Core Team в прошлом, либо активно работали над Go компилятором извне. Сам модуль используется внутри inet.af/netaddr который, в свою очередь, тянут в том числе и большие проекты.
Недостаток у go4.org/intern один: написан он с очень большим процентом черной магии, часть из которой еще и сильно ненадежна. Настолько ненадежна, что создателям модуля пришлось сделать (и регулярно обновлять) дополнительный модуль go4.org/unsafe/assume-no-moving-gc единственная цель которого, это убедиться, что сборщик мусора в Go все еще не двигает объекты в памяти хипа.
Проблема стала настолько явной, что Михаэль Кнызэк (один из ключевых разработчиков рантайма Go) предложил решить проблему уже на уровне стандартной библиотеки. Дескать не дело это, что модуль от которого зависит примерно 0,1% всей экосистемы (что достаточно много), может работать только в текущей внутрянке Go. Да и на дженерики бы уже неплохо все перенести. Предложенное API достаточно простое: есть одна глобальная функция которая возвращает враппер вокруг переменной и гарантирует ее уникальность в памяти. Враппер же нужен для быстрого сравнения уникальных значений между собой. А вся магия будет скрыта внутри райнтайма, который самостоятельно будет удалять переменные на которых больше никто не ссылается.
На мой взгляд, это попытка в очередной раз отложить внедрение слабых ссылок, потребность в которых назрела и перезрела уже давно. Однако меня устроит и такой вариант развития событий, ибо уже лучше чем ничего или магия которая может в любой момент развалиться.
Практически все разработчики сталкиваются с проблемой уникальности данных на уровне приложения. Чаще всего это вопрос удаления повтора строк, т.к. именно этот тип данных является самым «ходовым» в случае работы с хранилищами. А где хранилища, там и кеши и вопрос о затратах памяти. И рано или поздно, в любой достаточно сложной системе кеширования встает вопрос дедупликации - хранить повторяющиеся строки уж очень дорого на больших обьемах данных.
Неофиты спросят: «а в чем проблема? Почему нельзя использовать обычный словарь под мьютексом?». И ведь правда, мы можем использовать тип
map для хранения уникальных значений любых сравниваемых типов. По скорости, словарь из стандартной библиотеки, превзойдут только уж совсем специализированные словари, которые большинство писать никогда не будет. Однако у этого подхода есть один существенный, но критический вопрос: как удалять ключи которых больше нет в нашей системе?В языках со сборщиком мусора, типо Java и C#, для решения этой проблемы есть специализированные типы (
WeakHashMap, WeakSet) которые автоматически удаляют ключи, на которые никто больше не ссылается. Под капотом практически все они используют weak reference (слабая ссылка, если только она ссылается на переменную, то сборщик мусора имеет право собрать переменную). Однако разработчики компилятора Go активно сопротивляются внедрению слабых ссылок в язык. Причины тому разные, но основная мысль кроется в нежелании усложнять рантайм и сборщик мусора без «лишней» необходимости.Однако если чему-то сопротивляться, это не значит, что в этом чем-то пропадет потребность. Модуль go4.org/intern содержит в себе реализацию такой системы дедупликации значений. Авторами этого пакета являются разработчики Tailscale, часть из которых либо являлись частью Go Core Team в прошлом, либо активно работали над Go компилятором извне. Сам модуль используется внутри inet.af/netaddr который, в свою очередь, тянут в том числе и большие проекты.
Недостаток у go4.org/intern один: написан он с очень большим процентом черной магии, часть из которой еще и сильно ненадежна. Настолько ненадежна, что создателям модуля пришлось сделать (и регулярно обновлять) дополнительный модуль go4.org/unsafe/assume-no-moving-gc единственная цель которого, это убедиться, что сборщик мусора в Go все еще не двигает объекты в памяти хипа.
Проблема стала настолько явной, что Михаэль Кнызэк (один из ключевых разработчиков рантайма Go) предложил решить проблему уже на уровне стандартной библиотеки. Дескать не дело это, что модуль от которого зависит примерно 0,1% всей экосистемы (что достаточно много), может работать только в текущей внутрянке Go. Да и на дженерики бы уже неплохо все перенести. Предложенное API достаточно простое: есть одна глобальная функция которая возвращает враппер вокруг переменной и гарантирует ее уникальность в памяти. Враппер же нужен для быстрого сравнения уникальных значений между собой. А вся магия будет скрыта внутри райнтайма, который самостоятельно будет удалять переменные на которых больше никто не ссылается.
На мой взгляд, это попытка в очередной раз отложить внедрение слабых ссылок, потребность в которых назрела и перезрела уже давно. Однако меня устроит и такой вариант развития событий, ибо уже лучше чем ничего или магия которая может в любой момент развалиться.
GitHub
unique: new package with unique.Handle · Issue #62483 · golang/go
Proposal: unique package Updated: 10 April 2024 Oct 4th EDIT: Changed package name from "intern" to "unique" and renamed "Symbol" to "Handle" based on feedba...
👍22
Go Update
Update: proposal: spec: add untyped builtin zero Собрав фидбек Расс предлагает немного изменить правила использования для zero: новый идентификатор можно будет использовать для присваивания и сравнения только там где недоступны другие «короткие» идентификаторы…
proposal: spec: add untyped builtin zero (closed)
Случилось неожиданное. Предложение было принято. А затем собрав фидбэк (среди которого высказался и Роб «наше все» Пайк) Расс принял решение отозвать предложенное изменение. И хотя с самим отзывом я в корне не согласен, я могу понять причины: «срач» в ветке не утихал ни на день, породил два контр-предложения и вызывал новые проблемы в объяснении Go механик новичкам.
Однако сам факт отзыва расстроил меня под двум причинам:
- После принятия предложения и нескольких страниц срача, Расс обьявил, что в отсутствии новой информации, решение о принятии изменено не будет. А затем спустя несколько дней, в течении которых срач все равно продолжился, предложение было отозвано без каких либо комментариев. Что подводит к неприятной мысли о том, что любое предложение можно заставить отозвать просто через продолжение спора в обсуждении.
- Go Core Team явно имело внутренние разговоры по этому вопросу, однако поделится ими они не посчитали нужным. На мой взгляд, сие идет против духа открытого ПО. Но так как по факту Go полностью владеет Google, то и Open Source у нас очень условный.
Итог: на одно изменение меньше в Go 1.22. Возможно это и к лучшему…
Случилось неожиданное. Предложение было принято. А затем собрав фидбэк (среди которого высказался и Роб «наше все» Пайк) Расс принял решение отозвать предложенное изменение. И хотя с самим отзывом я в корне не согласен, я могу понять причины: «срач» в ветке не утихал ни на день, породил два контр-предложения и вызывал новые проблемы в объяснении Go механик новичкам.
Однако сам факт отзыва расстроил меня под двум причинам:
- После принятия предложения и нескольких страниц срача, Расс обьявил, что в отсутствии новой информации, решение о принятии изменено не будет. А затем спустя несколько дней, в течении которых срач все равно продолжился, предложение было отозвано без каких либо комментариев. Что подводит к неприятной мысли о том, что любое предложение можно заставить отозвать просто через продолжение спора в обсуждении.
- Go Core Team явно имело внутренние разговоры по этому вопросу, однако поделится ими они не посчитали нужным. На мой взгляд, сие идет против духа открытого ПО. Но так как по факту Go полностью владеет Google, то и Open Source у нас очень условный.
Итог: на одно изменение меньше в Go 1.22. Возможно это и к лучшему…
✍8❤3😨3👍2
✅ И немного позитива: sync: add Map.Clear method
Там верно заметили, что раз у нас теперь есть встроенная функция
Там верно заметили, что раз у нас теперь есть встроенная функция
clear для очистки словарей и слайсов, то хорошо бы такое иметь для sync.Map. Разработчики Go согласились и предложение было принято без лишних слов. Ждем реализации в Go 1.22.GitHub
sync: add Map.Clear method · Issue #61696 · golang/go
Since we have landed #56351 for clear builtin map, but we seems forget the sync variant sync.Map, let's do it!
👍16❤2
📝 Где посмотреть список изменений в будущем релизе.
Список изменений на следующий релиз всегда доступен на https://tip.golang.org
Для Go 1.21 это был https://tip.golang.org/doc/go1.21
Для Go 1.22 это есть https://tip.golang.org/doc/go1.22
Для Go 1.23 это будет https://tip.golang.org/doc/go1.23
Однако сама страничка появляется примерно на второй-третий месяц разработки версии, а настоящая актуализация данных начинается за месяц-два до самого релиза. Т.е. сейчас на страничке 1.22 еще многого нет из того, что точно попадет в релиз.
Список изменений на следующий релиз всегда доступен на https://tip.golang.org
Для Go 1.21 это был https://tip.golang.org/doc/go1.21
Для Go 1.22 это есть https://tip.golang.org/doc/go1.22
Для Go 1.23 это будет https://tip.golang.org/doc/go1.23
Однако сама страничка появляется примерно на второй-третий месяц разработки версии, а настоящая актуализация данных начинается за месяц-два до самого релиза. Т.е. сейчас на страничке 1.22 еще многого нет из того, что точно попадет в релиз.
tip.golang.org
The Go Programming Language
Go is an open source programming language that makes it simple to build secure, scalable systems.
❤6👍5🔥2
🤔 О темпе выхода новостей на канале.
Наверное многие обратили внимание, что новости на канале стали выходить существенно реже (последняя новость была аж 19го сентября). На это есть три причины:
- 😫Пока мне не хватает сил. Сочетание жизненных обстоятельств, работы и общей накопившейся усталости привело к тому, что канал на время сильно упал в списке приоритетов. Я по прежнему слежу за разработкой Go, но вот конвертировать это все в конечную развернутую мысль у меня какое-то время не получалось. Возможно дальше станет лучше, возможно немного хуже.
- 😕Обсуждении
- 📁Последние три недели особых предложений по языку или стандартной библиотеке никто не высказывал. Вероятно все силы команды брошены на реализацию предложенных к 1.22 вещей. Плюс недавно прошел GopherCon 2023 на который команда на время переключилась.
По итогу я очень надеюсь продолжить выкладывать свои мысли по поводу эволюции языка, благо у меня еще есть список изменений которые стоит осветить. Весь вопрос лишь в силах на это всё…
Наверное многие обратили внимание, что новости на канале стали выходить существенно реже (последняя новость была аж 19го сентября). На это есть три причины:
- 😫Пока мне не хватает сил. Сочетание жизненных обстоятельств, работы и общей накопившейся усталости привело к тому, что канал на время сильно упал в списке приоритетов. Я по прежнему слежу за разработкой Go, но вот конвертировать это все в конечную развернутую мысль у меня какое-то время не получалось. Возможно дальше станет лучше, возможно немного хуже.
- 😕Обсуждении
zero было довольно довольно долгим и по итогу контр-продуктивным. А затем предложение было закрыто без каких либо комментариев. Не скрою - на какое-то время это здорово пошатнуло мотивацию.- 📁Последние три недели особых предложений по языку или стандартной библиотеке никто не высказывал. Вероятно все силы команды брошены на реализацию предложенных к 1.22 вещей. Плюс недавно прошел GopherCon 2023 на который команда на время переключилась.
По итогу я очень надеюсь продолжить выкладывать свои мысли по поводу эволюции языка, благо у меня еще есть список изменений которые стоит осветить. Весь вопрос лишь в силах на это всё…
❤90👍26👏1
🤗 Благодарность за поддержку прошлого сообщения.
Спасибо всем кто отписался и проставил позитивные emoji. Это ценно.
Спасибо всем кто отписался и проставил позитивные emoji. Это ценно.
❤34👍6
🤨 proposal: spec: memoization (likely decline)
Тут предлагают добавить новое ключевое слово в язык -
Однако необходимость подобного на уровне ключевого слова для языка вызывает у меня серьезные сомнения. Во первых, в Go нельзя указать, что функция или метод являются чистыми (другое название — без побочных эффектов. Т.е. результат функции зависит только от входящих данных и ни от каких вещей вроде глобальных переменных или чтения/записи с диска). Во вторых, никто не мешает внутри функции использовать
Go Core Team высказала те же опасения. Плюс добавили, что вопрос можно решить через сторонний пакет и дженерик тип, который позволит обобщить все работу по мемоизации (по аналогии как сейчас работает
Отсюда и вывод: предложение предлагают отклонить. Дали три недели на случай, если у кого-то найдутся серьезные аргументы в пользу принятия данного предложения.
Тут предлагают добавить новое ключевое слово в язык -
memo - которое скажет компилятору, что для каждого варианта аргументов функции нужно запомнить результат. Сама техника (называется мемоизация) довольно популярна для оптимизации рекурсивных вычислений - нам не нужно пересчитывать то, что мы уже высчитали до этого. Простейший пример это вычисление чисел фибоначи.Однако необходимость подобного на уровне ключевого слова для языка вызывает у меня серьезные сомнения. Во первых, в Go нельзя указать, что функция или метод являются чистыми (другое название — без побочных эффектов. Т.е. результат функции зависит только от входящих данных и ни от каких вещей вроде глобальных переменных или чтения/записи с диска). Во вторых, никто не мешает внутри функции использовать
map для хранения связи между входящими аргументами и возвращаемыми данными, и скрыть все в деталях реализации (в отличии от предложенного, где информация о мемоизации появится в сигнатуре функции).Go Core Team высказала те же опасения. Плюс добавили, что вопрос можно решить через сторонний пакет и дженерик тип, который позволит обобщить все работу по мемоизации (по аналогии как сейчас работает
sync.Once и sync.OnceFunc).Отсюда и вывод: предложение предлагают отклонить. Дали три недели на случай, если у кого-то найдутся серьезные аргументы в пользу принятия данного предложения.
GitHub
proposal: spec: memoization · Issue #62637 · golang/go
Author background Would you consider yourself a novice, intermediate, or experienced Go programmer? Experienced (working professionally with Go). What other languages do you have experience with? R...
👍19
⚙️ proposal: cmd/go: add support for dealing with flaky tests или работа с «капризными» тестами.
Нестабильные тесты – настоящий бич мира разработки ПО. Для тех немногих счастливчиков, кто не в курсе: "flaky tests" – это тесты, которые проходят или не проходят в зависимости от фазы луны. При повторном запуске такой тест, как правило, успешно проходит (как и при всех последующих попытках). В идеальном мире таких тестов в проекте быть не должно по определению. Однако реальность такова: такие тесты есть почти везде. Они есть у вас в проекте, они есть в Tailscale (где даже написали специальный враппер для работы с ними), они есть и в компиляторе Go.
Брэд Фитцпатрик предлагает решить эту проблему на уровне туллинга для языка. Вы помечаете тест как
Нестабильные тесты – настоящий бич мира разработки ПО. Для тех немногих счастливчиков, кто не в курсе: "flaky tests" – это тесты, которые проходят или не проходят в зависимости от фазы луны. При повторном запуске такой тест, как правило, успешно проходит (как и при всех последующих попытках). В идеальном мире таких тестов в проекте быть не должно по определению. Однако реальность такова: такие тесты есть почти везде. Они есть у вас в проекте, они есть в Tailscale (где даже написали специальный враппер для работы с ними), они есть и в компиляторе Go.
Брэд Фитцпатрик предлагает решить эту проблему на уровне туллинга для языка. Вы помечаете тест как
flaky, и go test автоматически понимает, что его нужно повторить (возможно, несколько раз) в случае ошибки. Предложение еще находится на ранних этапах обсуждения, поэтому у вас есть возможность поучаствовать и предложить свои идеи.GitHub
cmd/go: add support for dealing with flaky tests · Issue #62244 · golang/go
Background First off, flaky tests (a test that usually passes but sometimes fails) are the worst and you should not write them and fix them immediately. That said, the larger teams & projects &...
👍30❤3👎2🔥1
🙄 go4.org/unsafe-assume-no-moving-gc: когда все равны, но некоторые равнее.
В модуле go4.org/unsafe/assume-no-moving-gc есть интересное место. В нём вызывается функция из рантайма Go с помощью
Прикол в том, что эта функция появилась специально в Go 1.21 именно для этого модуля. А причина проста: без неё модуль
И всё же приятно, когда твои бывшие коллеги работают над компилятором, который ты используешь в разработке своего продукта 😆.
В модуле go4.org/unsafe/assume-no-moving-gc есть интересное место. В нём вызывается функция из рантайма Go с помощью
go:linkname (управляющая директива в комментариях, которая позволяет вызывать приватные функции и методы из других пакетов) - heapObjectsCanMove. Функция крайне простая - пока GC не двигает объекты в хипе, она возвращает false. Если (когда) начнёт, то будет возвращать true.Прикол в том, что эта функция появилась специально в Go 1.21 именно для этого модуля. А причина проста: без неё модуль
assume-no-moving-gc надо было обновлять с каждой новой версией компилятора Go. Именно этим ребята и оправдывают включение этой приватной функции в пакет runtime.И всё же приятно, когда твои бывшие коллеги работают над компилятором, который ты используешь в разработке своего продукта 😆.
pkg.go.dev
assume_no_moving_gc package - go4.org/unsafe/assume-no-moving-gc - Go Packages
Package go4.org/unsafe/assume-no-moving-gc exists so you can depend on it from unsafe code that wants to declare that it assumes that the Go runtime does not use a moving garbage collector.
👍7🗿6🤯1
Go Update
🙄 go4.org/unsafe-assume-no-moving-gc: когда все равны, но некоторые равнее. В модуле go4.org/unsafe/assume-no-moving-gc есть интересное место. В нём вызывается функция из рантайма Go с помощью go:linkname (управляющая директива в комментариях, которая позволяет…
😂 Вся сиутация как тот мем:
Рядовой разработчик: мне нужна функция которая позволит получить id горутины. Предоставьте такой функционал, пожалуйста.
Go Core Team: 🤨 тебе это не нужно. И вообще во внутрянку лезть не надо.
Разработчики Tailscale: мы тут намутили модуль полностью состоящий из черной магии который понимают десять человек в мире. Сделайте функцию в рантайме быренько, что-бы это все не развалилось на следующем релизе.
Go Core Team: 🫡 Сейчас все будет.
Рядовой разработчик: мне нужна функция которая позволит получить id горутины. Предоставьте такой функционал, пожалуйста.
Go Core Team: 🤨 тебе это не нужно. И вообще во внутрянку лезть не надо.
Разработчики Tailscale: мы тут намутили модуль полностью состоящий из черной магии который понимают десять человек в мире. Сделайте функцию в рантайме быренько, что-бы это все не развалилось на следующем релизе.
Go Core Team: 🫡 Сейчас все будет.
😁30
🦎 proposal: slices: have Delete clear the tail
В своем докладе на GolangConf 2023 я буду рассказывать про эволюцию Go, в том числе и про новые пакеты в стандартной библиотеке. Изучая один из этих пакетов мне стало интересно, как там реализована функция
И вроде бы все верно, так? Даже те из вас, кто давно работают с Go скорее всего не смогут сходу сказать, что тут не так. Признаюсь, я к пониманию глубины проблемы пришел только в рамках подготовки самих слайдов.
Допустим у нас есть такой код:
Первичный анализ подсказывает, что после вызова GC у нас должен остаться в памяти слайс на 10 миллионов указателей и на один int. Ну т.е. программа в памяти будет занимать от 80 до 90 МБ на amd64.
Пробуем запустить и получаем вывод:
Наш анализ некорректен: в Go сборщик мусора не собирает память на которую есть указатели в активной памяти, даже если эти указатели находятся за пределами длинны слайса. Причина простая: никто не мешает вам сделать от слайса выше новый слайс с длинной 3 и тем самым восстановить указатель на 3ий элемент.
Интересно то, что этой проблемой озаботились не в Go Core Team, а простой Go разработчик-город-Тверь из Франции. Такую же проблему содержат и другие функции:
При этом сам issue есть эталон того как это правильно делать: там и лаконичная мысль, разбитая на параграфы, и картинки которые круто визуализируют проблему, и разные варианты решений. В общем понравилось не только мне - Расс тоже оценил. А решение выбрал максимально простое: будем занулять элементы которые выкинули, благо у нас теперь есть встроенная функция
Текущий статус: likely accept. А это значит, что пока есть все шансы, что мы увидим сие в 1.22.
В своем докладе на GolangConf 2023 я буду рассказывать про эволюцию Go, в том числе и про новые пакеты в стандартной библиотеке. Изучая один из этих пакетов мне стало интересно, как там реализована функция
Delete. А реализация там крайне простая:func Delete[S ~[]E, E any](s S, i, j int) S {
_ = s[i:j] // bounds check
return append(s[:i], s[j:]...)
}
И вроде бы все верно, так? Даже те из вас, кто давно работают с Go скорее всего не смогут сходу сказать, что тут не так. Признаюсь, я к пониманию глубины проблемы пришел только в рамках подготовки самих слайдов.
Допустим у нас есть такой код:
var slc []*int64
for i := 0; i < 10_000_000; i++ {
val := i
slc = append(slc, &val)
}
slc = slices.Delete(slc, 1, 10_000_000)
runtime.GC()
// Report memory metrics
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("Alloc = %v MiB\n", m.Alloc / 1024 / 1024)
Первичный анализ подсказывает, что после вызова GC у нас должен остаться в памяти слайс на 10 миллионов указателей и на один int. Ну т.е. программа в памяти будет занимать от 80 до 90 МБ на amd64.
Пробуем запустить и получаем вывод:
Alloc = 170 MiB
Наш анализ некорректен: в Go сборщик мусора не собирает память на которую есть указатели в активной памяти, даже если эти указатели находятся за пределами длинны слайса. Причина простая: никто не мешает вам сделать от слайса выше новый слайс с длинной 3 и тем самым восстановить указатель на 3ий элемент.
Интересно то, что этой проблемой озаботились не в Go Core Team, а простой Go разработчик
DeleteFunc, Compact, CompactFunc и Replace. При этом сам issue есть эталон того как это правильно делать: там и лаконичная мысль, разбитая на параграфы, и картинки которые круто визуализируют проблему, и разные варианты решений. В общем понравилось не только мне - Расс тоже оценил. А решение выбрал максимально простое: будем занулять элементы которые выкинули, благо у нас теперь есть встроенная функция
clear. Текущий статус: likely accept. А это значит, что пока есть все шансы, что мы увидим сие в 1.22.
GitHub
slices: have Delete and others clear the tail · Issue #63393 · golang/go
Proposal a = slices.Delete(a, i, j) should zero the (j - i) elements after the length of the returned slice TL;DR zeroing the elements is error-prone, it should be taken care of by the stdlib funct...
👍32🔥11❤1