TGViewer
Channel Public Channel
Go Update

Go Update

@go_update

Канал про новости связанные с языком программирования Go. Эволюция языка, стандартной библиотеки и просто интересные вещи над которыми работает Go Core Team и не только.

Админ: @lepage_d
Subscribers
3.23K
Photos
12
Videos
0
Links
85
Recent Posts 20 shown
Post #132 1.42K
Об изоляции LLM

Да, это ещё один пост про работу с Codex/Claude/GLM/Qwen/DeepSeek и прочая. В этот раз без воды, исключительно технический.

Решил я тут вкатится в разработку с помощью LLM всерьез и пойти через, уже почти ставшие стандартом, «план -> реализация -> тест -> повторить». Касаемо шагов, скиллов, плагинов и прочего говорить не буду — тут каждый сам «кузнец своего счастья» и индустрия пока только осознает необходимость общего подхода. Меня же заинтересовало другое — изоляция агентов, в процессе их работы, от деструктивных и «вредных» действий.

Проблема: «настоящая» изоляция ни у одного из агентов/харнессов не сделана на приемлемом уровне «из коробки». OpenCode запрещает чтение выше своего рабочего каталога, но спокойно пропускает команду head -10 /home/file/name. Codex и Claude, используя API песочницы ОС, спокойно пропускают ручки LLM до хомяка и других каталогов, правда только на чтение. Однако даже чтение может быть «вредным»: если агент в своём безумии решит вычитать ~/.ssh/private_key, то «по умолчанию» ему никто не помешает это сделать. И да, я знаю, что у SOTA моделей проверкой команд занимается ещё одна модель в отдельном контексте, но это вероятностная проверка, а не однозначная. А значит, если она оставляет 1% шанс на чтение моего приватного ключа, то это не вопрос «может быть?», а вопрос «когда?».

Поэтому мои поиски привели меня к следующим тулам и вариантам:
• Docker SBX — sandbox для агента поверх докера. На всех ОС (Linux/Windows/Mac) изоляция сделана с помощью виртуализации, а значит если чего-то в образе нет, то к этому «чему-то» агент доступа не получит. Плюсы: знакомый Dockerfile синтаксис и принципы, хорошая интеграция с docker’ом. Минусы: необходимость Docker ID и долгий запуск, жрёт от 500+ метров в памяти. Для разработки мультиконтейнерных решений хорошая вещь, для «пообщаться c OpenCode» не.
• Система правил для Claude и Codex — можно конфигом настроить, что агенту можно, и обе тулы зафиксируют правила через механизмы песочницы ОС. Плюсы: есть в комплекте (хотя стандартные правила слишком свободные), нулевые дополнительные траты на песочницу, (вроде) достаточно гибкий синтаксис. Минусы: у каждой тулы свой синтаксис, у кодекса сама система всё еще в экспериментальном статусе, ограничения песочницы самой ОС. Если работатете строго с одним агентом, то это может быть хорошим вариантом.
• Agent Safehouse — унифицированная песочница для агентов на MacOS. Работает через sandbox-exec (через него же работает песочница клода и кодекса). Плюсы: нулевая стоимость на этапе исполнения, унифицированный синтаксис и команды для запуска процессов в песочнице. Минусы: выглядит как сторонний проект, поддержка которого может в любой момент закончится. Все ограничения песочницы мака в силе, а само яблоко регулярно меняет API sandbox-exec, которое ещё и не документирует. Для «пообщаться с OpenCode» мне нравится, но в прод я бы такое тащить не рискнул.
• MicroSandbox, SmalVM — идея та-же, что у SBX, но реализация другая - под капотом микровирутальные машины на которые накатываются такие-же OCI миниобразы. Из-за этого запуск кратно быстрее SBX и кратно меньше потребление памяти (обещают оверхед в 30-40Мб против 500+ у докера). Плюсы: у обоих удобный синтаксис, возможность точечной настройки доступов к сети (включая варианты через MITM и резолвинга только определенных доменов) и ресурсам железа, аудит событий внутри виртуалки, адекватная работа с секретами. Минусы: оба проекта вроде выходят на коммерческие рельсы, но пока именно в процессе выхода. Запуск виртуалки, несмотря на минимализм, все же сьедает дополнительное время и память. Для прода я бы рассматривал этот вариант, тем более у smolvm есть возможность преобразовать итоговые образы в исполняшки.

Для себя пока остановился на Safehouse, плюс активно исследую MicroSandbox. Надеюсь, что всё в итоге превратится в набор стандартов, по типу OCI, ибо так дальше жить нельзя.
Docker Docker Sandboxes | Sandboxes for Coding Agents | Docker Secure sandboxes for Claude Code, Gemini, Codex, and Kiro. Run coding agents with microVM-based isolation.
  • 👍 12
  • ❤ 2
  • 👏 1
Post #131 2.02K
Go Update 🎂 Настал тот день когда мне исполнилось 33! Да, да тот самый год, в который вас поздравляют используя аналогии к одной из самых ярких личностей в истории человечества 😁️️️️️️. В (не)далеком детстве, когда мне было лет 7-8, я смотрел на взрослых, которым…
И вот эти два минуса выглядят нерешенными (на данный момент времени). Можно ли их решить вообще, я тоже не знаю — как я уже сказал выше, галлюцинации нам обещали победить еще в середине 25го. Но именно сочетание двух проблем вызывает у меня тревогу, особенно с учётом мировых ожиданий от LLM. Мне кажется, что мы находимся в очередной фазе «когда у меня в руках молоток, то всё перед мной — гвозди». Только одна сложность — у молотка «нет тормозов». Совсем. Достаточно упорный запрос заставит сий «молоток» выполнить любую функцию, или (что хуже) доложить вам о её успешном выполнении. Как говорил один интернет классик — «любой ценой, но бесплатно!».

Я очень надеюсь, что эта фаза временная, но уже сейчас вижу какой мешок проблем нам придется разгребать когда ажиотаж спадёт если нас всех к тому моменту не «оптимизируют». Ситуация безусловно не станет прежней, но и окончательные выводы о всеприменимости технологии пока ещё делать рано. Умнейшие умы человечества изобрели «двигатель». Осталось изобрести «тормоза и рулевое колесо». И ремни безопасности на сдачу.

П.С. Да это очередное брюзжание про LLM о котором вы не просили 😁. Интересное постараюсь опубликовать в течении недели. Рабочее название «Теперь я знаю, почему никто не спрашивает на собесах о том, как работают type assertion».
  • ❤ 30
  • 🔥 7
  • 👍 3
  • 🤯 1
Post #130 1.74K
Go Update 🎂 Настал тот день когда мне исполнилось 33! Да, да тот самый год, в который вас поздравляют используя аналогии к одной из самых ярких личностей в истории человечества 😁️️️️️️. В (не)далеком детстве, когда мне было лет 7-8, я смотрел на взрослых, которым…
🎂 Вечерний пост о том, что сегодня мне исполнилось 34.

Прошёл еще один год, а значит время «подводить итоги». Однако вот сижу я сейчас и думаю: это сообщение, вероятно, смог бы написать за меня OpenAI Codex (или Claude Code моей жены). И неподготовленный взгляд, опять же, вероятно, даже не заметит подмену. Однако сии строки я набираю сам, со всеми ошибками и опечатками. И вот почему.

За год LLM окончательно завершили технологическую «революцию», закрепившись в мире разработки, перестав быть экзотикой и стал очередным жестким требованием работодателей. Бессмысленно отрицать, что большие языковые модели заменили нам исследование, прототипы, поиск в Гугле и на SO. Настройку и развертку. Исследование логов. Написание ADR. У многих даже ручной кодинг отвалился. Да че уж говорить, моя команда по выводу продуктов в Open Source из маркетинговой истории «смотрите как у нас круто» превратилась в прагматичную историю «можете натравить на наш API/SDK ваших агентов и они соберут вам всё за пару вечеров». Скорость и объем итераций возросли в разы.

Однако у всего этого есть и обратная сторона. Я не буду говорить про выгорание от попыток вразумить «электронного дебила» через набор текстовых файлов. Я не буду говорить про кратно возросшую нагрузку из-за потока MR на code-review. Я не буду говорить, что новички в профессии уже не стесняются говорить о том, что «ну за меня код GLM/DeepSeek пишет, сам я тока рулетку кручу промт вставляю». И уж тем более я не буду говорить о том, насколько выросли цены на железо и что любой корпоративный сервис, вне зависимости от сложности, теперь является потенциальной жертвой 12летнего куллхацкера с локальным Heretic Qwen и неограниченным запасом времени. Про всё это уже написано огромное число статей, а реальные выводы мы сможем сделать лишь спустя годы.

Нет, моя мысль более приземленная. За три года, которые я взаимодействую с языковыми моделями, я пришёл к однозначному выводу — LLM это невероятно крутой Т9. Я понимаю, что многие из вас, кто работают с моделями (или работает над ними), сейчас оскорбились, но моя цель не принизить успех технологии. Отнюдь — как я уже говорил, реальный импакт уже есть и он уже ощущается всеми. Но и замечать очевидные минусы становится всё сложнее.

Минус первый — пустословность моделей. Именно пустословность, а не многословность, тк все мы знаем про Caveman Skill и прочие различные методики сокращения числа потребляемых токенов. Нет, речь именно про смысловую нагрузку в тексте, который генерирует модель, неком числе коэффициенте полезной информации на слово. Из-за того, что каждый второй сейчас выкладывает тексты «причесанные LLM» я обратил внимание, что не могу больше читать и осознавать такие тексты. Из-за их огромного числа, мозг перестал их воспринимать. Как рекламу — она вроде есть, но мозг научился её фильтровать настолько хорошо, что мы даже не обращаем внимание на баннеры слева и справа потребляемого контента. И из минуса следует логичный вопрос: для кого написаны эти километры «причесанного LLM» текста? Кто их будет читать?

Минус второй — мы думали (думаем?) что это заменитель, а это мультипликатор, знаний и ума. В индустрии всё еще теплится идея, что модели смогут заменить «мешков с костями» как полноценные автономные сотрудники. Не буду касаться вопроса ответственности, зайду с другой стороны: на днях общаясь с Claude Opus 5 я обратил внимание, что имена и факты не сходятся. При этом текст был лаконичный и набор утверждений были последовательным. Нигде модель не путалась, не мешала следствия и не выглядела как шизофреник. Однако одно неправильное утверждение вызвало у меня вопрос «а откуда ты взяла XY?». На что модель честно ответила — я это придумала! Как и 50% всех фактов, которые она мне до этого любезно разложила. И хуже здесь не сама галлюцинация (которые нам всё обещают победить, но никак не побеждают), а тот факт, что модель смогла вывести идеально выстроенную систему из неё. Если бы я не знал о конкретном несоответствии, я бы даже не подумал, что что-то пошло не так. Настолько был убедительный текст.
  • ❤ 27
  • 👍 15
Post #129 2.58K
📝 testing: allow examples with any signature

Небольшое «Quality of Life» предложение. Суть: давайте разрешим функциям Example*, которые мы используем для документации, принимать и возвращать любое число аргументов. Запрос связан с тем, что сейчас многие вещи не выразить в примерах. Например примеры для пакетов нацеленных на тестирование.

Те в документации станет отображаться следующий код:


func Example_Functionname(t *testing.T) {
t.Logf("foobar")
}


Единственным ограничением является то, что в отличии от безаргументных Example* функций, они не смогут содержать // Output: комментарии.


func Example_Functionname(t *testing.T) { // will not compile
t.Logf("foobar")
// Output: foobar
}



Напомню, что такие комментарии автоматически переводят примеры в тесты — их прогоняет go test и сверяет их вывод с тем, что идёт в блоке комментария после Output. Что было довольно удобно для проверки (и сохранения!) корректности этих самых примеров. Решать сие предлагают через написание тестов, которые будут вызывать эти примеры напрямую — т.е. точно так-же как мы тестируем обычные функции.

Текущий статус accepted, и будет сие вероятно частью релиза 1.28.
GitHub testing: allow examples with any signature · Issue #79808 · golang/go This is an offshoot of #64993 (comment), and an alternative to #21111 and #64993. Proposal: We make go doc display any function named Example or ExampleXxx where Xxx does not start with a lowercase...
  • 😐 8
  • 👍 7
  • 👎 1
Post #128 3.2K
📝 net/http/httptest: synctest support

Я уже писал про пакет synctest и его возможности. Это была одна из главных фишек Go 1.25, здорово облегчившая тестирование конкурентного кода. Главный минус данного пакета, на мой взгляд, это его слабая интегрированность в стандартную библиотеку. И, похоже, эту проблему наконец решено начать исправлять.

Большинство из нас работает с HTTP-серверами (включая gRPC, который является сабсетом HTTP/2) в том или ином виде. Для тестирования этих серверов у нас есть пакет net/http/httptest, который позволяет легко поднять тестовый HTTP-сервер, отвечающий на запросы, используя реальный loopback-интерфейс. Запущенный тестовый сервер также легко создаёт подключенного к себе клиента, который, в свою очередь, работает одинаково хорошо с обычным соединением и TLS-режимом без сложных махинаций с корнем сертификатов. Однако у этого подхода есть минус: так как он использует реальный сетевой интерфейс и порт (и, как следствие, сокет), пакет synctest с ним несовместим.

Проблемой озаботился Дэмиен Нил (автор самого synctest) и предложил добавить в пакет httptest новую функцию: NewTestServer. Суть заключается в том, что если на полученном сервере не вызывать метод Start, то все запросы пойдут через in-memory-шину, реализованную на каналах. Таким образом уходит IO, и процесс становится контролируемым через synctest.

При этом все запросы клиента, полученного от созданного сервера, вне зависимости от целевого адреса, будут уходить на сервер, породивший клиента (в отличие от клиентов для обычных тестовых серверов, где запросы могут уходить и на сторонние адреса). Если же на полученном сервере вызвать метод Start, он будет вести себя так же, как и раньше вёл себя тестовый сервер - поднимет сокет слушающий на loopback-интерфейсе.

Вместе с synctest такой подход позволяет создавать серверные юнит-тесты, где можно отслеживать статус сервера, хендлеров, прочих сущностей в любой момент времени без лишних костылей. И ловить утечку горутин после завершения тестов.

Текущий статус: accepted, но я не уверен, что фича попадет в 1.27 из-за скорого фича-фриза.
GitHub net/http/httptest: synctest support · Issue #76608 · golang/go Proposal Details I use the httptest package a lot, and in particular NewServer rather than ResponseRecorder, because it picks up subtle real-world issues that don't appear when not using the en...
  • 🔥 17
  • ❤ 5
  • 👍 4
  • ✍ 2
Post #127 2.78K
Я редко пишу сюда о вещах которые не относятся к Go, но тут у меня появилась хорошая статья на вечер. Которая про «архитектуру безопастности» и «самом слабом звене» и перекликается с прошлым сообщением. Только в обычном-бытовом значении.

Рекомендую.

ПС. Все совпадения реальны 😊️️️️️️.
  • 🗿 7
  • 🤮 4
  • ❤ 3
  • 😁 1
Post #126 11.6K
⚠️ CVE-2026-42501 или почему вам нужно обновиться до Go 1.26.3/go1.25.10 ⚠️

Те кто давно работают с Go (или читают меня) знают, что целостность наших модулей гарантируется не только HTTPS транспортом до самой прокси, но и отдельной базой SumDB, которая хранит в себе хеши модулей подписанные приватным ключом. При этом сама база устроена так, что невозможно внести изменения в прошлые записи, без каскада изменений в новые, тк каждый блок «подписан» предыдущим.

Но в ИБ сама безопастность это устойчивость самого слабого звена в цепочке. Достаточно одной маленькой ошибки, что-бы вся надежно выстроенная архитектура ИБ превратилась в пыль. Так и случилось в нашем случае.

Рассмотрим сценарий: при получении модуля от прокси, Go проверяет его хеш с использованием SumDB, блоки которой, как я уже говорил выше, подписаны приватным ключом. В псевдокоде это выглядит следующим образом:


for _, line := range sumdbResponse {
if line относится к нужному module@version {
if hash не совпадает {
return SECURITY ERROR
}
}
}
return nil


На первый взгляд, всё кажется логичным: если пришел ответ, проверяем хеш нужного модуля и при несовпадении валимся с ошибкой. При совпадении выходим из функции и продолжаем работу. Однако здесь кроется одна маленькая, но критичная деталь: что будет если нам вернут ответ без записей или запись про другой модуль? Скомпроментированная прокся может отдать специально подготовленный ответ, который наш клиент воспримет как правильный — достаточно выдать ответ с корректными хешами для любых модулей или даже выдать ответ без хешей. Поскольку go get пишет записи в go.sum с локально подсчитанного хеша, подмену никто не заметит, и тулинг спокойно продолжит работу, положив модуль от скомпрометированной прокси в go.mod/go.sum. Который, в свою очередь, будет использован компилятором при сборке проекта.

Т.е. перед нами классическая уязвимость которая позволяет организовать Supply Chain Attack (атака на зависимости), пример которой можно описать вот так:

1. Прокся отдаёт клиенту изменённый архив модуля, например rsc.io/foo@v1.0.0.
2. На запрос хеша возвращается валидный, криптографически корректный ответ от checksum database, но для другого модуля, например rsc.io/bar@v1.0.0.
3. go get видит: «ответ sumdb валидный, несовпадающего хэша нет» — и продолжает работу.

Т.е. вы получаете измененный модуль, у которого хеш оригинала можно узнать только после удаления go.sum и изменения прокси или использования direct в GOPROXY.

Проблема бы не была такой большой (ибо у большинства переменную GOSUMDB, отвечающую за источник правды о хешах, никто не трогает, а для загрузки тулчейна её вообще невозможно переопределить) если бы не два но:

• Директивы toolchain и go позволяют выбирать нужную версию компилятора автоматически, и при необходимости, скачивать её с той же самой прокси.
• go get всегда сначала спрашивает проксю, может ли та проксировать запросы до базы хешей GOSUMDB. Если ответ положительный, то она просто спросит её о хеше, вместо обращения непосредственно к GOSUMDB.

В этой ситуации фактически всю цепочку доставки модулей до клиента (и тулчейнов, если явно не запрещен автовыбор) контролирует один узел. Поэтому, если у вас изменена GOPROXY или вы не доверяете сертификатам TLS установленным в системе, то я очень рекомендую вам обновиться. При этом вам недостаточно обновить версию go (или toolchain) в файле go.mod, ведь изначальный тулчейн будет по-прежнему работать по старой логике. Нужно именно установить новую версию компилятора, заменив ту которая стоит «по умолчанию» в системе, а затем прогнать rm go.sum && go mod tidy в проектах которые могут быть скомпрометированы.

При всей опасности атаки, фикс у неё самый тривиальный: return nil просто заменили на


return module.VersionError(modWithoutSuffix, fmt.Errorf("verifying %s: checksum missing from sumdb response"+sumdbAbsent, noun))


П.С. Именно поэтому я рекомендую использовать приложения типа direnv для установки переменных GOPROXY или GOPRIVATE только для рабочих проектов.
Telegram Go Update Про go mod tidy | verify | download Задумывались ли вы о том, как именно Go проверяет целостность ваших скаченных модулей? Как наш тулчейн проверяет, что зависимости которые вы видите в своем проекте, соответствуют зависимостям которые видят другие разработчики?…
  • 👍 10
  • 🔥 2
Post #125 2.88K
🩳 proposal: spec: type inferred composite literals 🩳

Вы когда-нибудь задумывались, почему можно писать вот такой код:


type T struct{ V int }

a := []*T{{0}, {1}, {2}}
b := map[string]*T{"a": {0}, "b": {1}, "c": {2}}
c := [3]T{{0}, {1}, {2}}


Но нельзя вот такой:


var x []string = {"a", "b", "c"}
var y []*T = {{0}, {1}, {2}}
var z T = {0}


Всё дело в довольно сложных правилах вывода типов для сложных типов. Ещё в первых версиях создатели языка резонно решили, что одного объявления при инициализации достаточно и нет смысла дублировать идентификатор типа для каждого элемента отдельно. Что, в свою очередь, очень помогло в табличных тестах. Но вот сделать ещё один шаг им не хватило смелости уверенности в том, что код сохранит свою читаемость. А это было и остаётся критически важно для языка.

Однако всё течёт, всё меняется, и запрос на tuples (кортежи) или их аналог регулярно всплывал в issue-трекере языка. Причину для этого запроса лучше всего описать следующим кодом:


ch := make(chan struct {
value string
err error
})

//...

ch <- struct {
value string
err error
}{value: "result"}


Расписывать описание анонимной структуры и в момент декларации, и в момент использования очень неудобно, что нередко приводило к ситуациям, когда люди создавали локальный тип (или использовали алиас), чтобы не писать описание повторно.

И вот теперь, наконец мы стали TypeScript появится (скорее всего) обратный вывод типов для всех вариантов присваивания. Т. е. станет корректным следующий код:


ch <- {value: "result"}

fnT({0})

var s []*T = {{0}, {1}, {2}}

return {}, err


Последнее меня особенно радует, так как во многих кодобазах люди специально использовали возврат указателей из функции, так как не хотели писать длинное имя типа с пакетом.

А из дополнительных плюсов, данное изменение приведёт к упрощению (!!!) спеки языка, а значит разработчикам компиляторов Go станет чуть легче жить.

Текущий статус: likely accept accepted! и потенциальный кандидат на часть релиза 1.28.
go.dev The Go Programming Language Specification - The Go Programming Language
  • 👍 24
  • 🔥 3
Post #124 2.15K
✍️ go fix: apply fixes from modernizers ✍️

Есть такая утилита в тулчейне Go — go fix. В задачу которой входила модернизация кода под новые конструкции — как в языке, так и в стандартной библиотеке. Эдакий аналог go fmt который вместо единого стиля, выравнивал использования языковых конструкций по кодобазе. И вроде отличная идея, но с одной проблемой: почти десять лет никто её не поддерживал и не модернизировал. Те сама утилита осталась в далеких временах Go 1.8. Причина подобного довольно тривиальна: нет необходимости в обобщенной модернизации кода, а значит нет и свободных ресурсов под это. Тем более сам go fix был написан с использованием большого числа костылей, которые усложняли любую попытку модернизации.

Однако всё изменилось с приходом LLM: модели OpenAI, Anthropic, Alibaba и прочих обучаются на огромных массивах данных в свободном доступе и код генерируют исходя из увиденного. И тут стало понятно: если модели всегда будут учится на старом коде, то и предлагать они будут всегда старые паттерны. Поэтому, недавно вернувшийся в Google, Алан Донован (да-да, тот самый от кого у вас та самая голубая книжка) всерьез озаботился вопросом модернизации кода.

Первый шаг — пускаем старый кода под нож. Полностью.
Второй шаг — это полная переделка команды на основе различных анализаторов из gopls. Которые, в свою очередь, используют фреймворк analysis.

Результат: у нас есть «модернизатор» кода который заменяет «устаревшие» паттерны их современными аналогами.

Приведу несколько примеров. Начиная с 1.26 подъехал новый синтаксис new который умеет в значения. А модернизатор умеет распознавать где он нужен:


data, err := json.Marshal(&RequestJSON{
URL: url,
Attempts: newInt(10),
})

func newInt(x int) *int { return &x }


Становится


data, err := json.Marshal(&RequestJSON{
URL: url,
Attempts: new(10),
})


Тоже самое касаемо использования конкатенации строк внутри циклов:


s := ""
for _, b := range bytes {
s += fmt.Sprintf("%02x", b)
}
use(s)


Становится


var s strings.Builder
for _, b := range bytes {
s.WriteString(fmt.Sprintf("%02x", b))
}
use(s.String())


Те из коробки мы получаем и более краткий и более производительный код. Еще одна фича, которая доступна ещё и «обычным смертным»: новая аннотация //go:fix inline которая позволяет проводить inlining функций. Те если go fix встроен в ваш пайплайн, все перестановки произойдут автоматически, что удобно когда у вас был большой рефакторинг и внешних пользователей надо уведомить о новом расположении (или сигнатуре) функций.

Сама команда Go Core опубликовала отличные статьи которые показывают паттерны использования нового функционала и внутрянку того, как это работает. Рекомендую к прочтению.
go.dev Introducing Gofix - The Go Programming Language How to use go fix to update your code with each new Go release.
  • 👍 10
  • 🔥 7
  • ❤ 4
Post #123 2.76K
А ещё внезапно узнал, что у меня новая фамилия.
  • 😁 22
  • 🗿 6
Post #121 2.66K
Запись нашего февральского с Эдгаром подкаста о том как мы дошли до жизни такой.
  • ❤ 3
Post #120 2.45K

Forwarded from Алло, Ада

Новый выпуск трека Golang в партнерстве с GolangConf! 💪

Как применять будут Go в будущем? Чтобы это понять, надо понять то, как его применяли в прошлом, и самое важное, понять, а почему Go таков, какой он есть?

В новом выпуске с Дмитрием Матреничевым мы поговорили на тему того, как родился, развивался и развивается Go? Почему наш язык такой бедный в сравнении с Java? Как его развивали, а также кто? И всегда нужно помнить самое важное - какое он место займет в агенто-центричной разработке?

Получился очень насыщенный и самое важное - интересный выпуск про то, как же развивался Go и куда он может идти дальше?

Смотрим подкаст и заряжаемся гошной энергией:
🎥 YouTube
🎥 VK
  • 👍 3
  • 🔥 3
Post #119 3.72K
Код и Капуста AI или не AI Весьма интересное обсуждение - стоит ли использовать AI для разработки Go? Рас Кокс очень обстоятельно отвечает всем интересующимся: засуньте уже себе в ...! На саммо деле, нет конечно, все очень прилично, но суть примерно как я описал выше.…
На этот пост в почтовой рассылке Golang Nuts уже немало народу обратило внимание, и про него (в том числе) я рассказывал на подкасте у Эдгара Сипки (скоро в эфире).

Если коротко: у LLM нет прав, значит нет ответственности. Если вы приносите код в Open Source проекты, то вы отвечаете за него, вне зависимости от того с помощью каких инструментов он был сделан. Под этим подразумевается что а) вы старались над корректностью-читаемостью-производительностью кода б) вы понимаете, что он делает с) вы понимаете как отвечать на вопросы по этому коду. Все эти пункты критичны, тк именно код, а не ваши спецификации для Opus/Codex/Gemini, будут поддерживать в дальнейшем.

Нет спора о том, что LLM хороши для прототипирования и one-off проектов, где понятие «долгосрочная поддержка» не существует и/или не имеет смысла. Но если вы хотите «навайбкодить то самое изменение» в большой и сложный Open Source проект, но не готовы разбираться и прикладывать усилий для понимания его проблематики, то лучше воздержитесь от этой идеи. Сэкономите и своё время и время тех кто ведёт сий проект и его код.

П.С. Проблематикой обучения LLM на устаревших данных озаботилась и команда Golang, о чём напишу в следующем посте.
Telegram Эдгар Сипки Про AI, DevTools и разработку: как строить продукты и инженерные workflow. Связь: @zergsLaw Сайт: https://sipki.online/
  • 👍 17
  • ❤ 1
Post #118 2.85K

Forwarded from Код и Капуста

AI или не AI

Весьма интересное обсуждение - стоит ли использовать AI для разработки Go? Рас Кокс очень обстоятельно отвечает всем интересующимся: засуньте уже себе в ...!

На саммо деле, нет конечно, все очень прилично, но суть примерно как я описал выше. Он подчёркивает, что, несмотря на все изменения в индустрии, фундаментальные принципы разработки ПО остаются неизменными. Самое важное - сохранять существующие процессы код-ревью и стандарты качества: код, созданный с помощью AI, должен проходить ту же тщательную проверку, что и написанный вручную, а ответственность за качество, поддержку и отсутствие нарушений авторских прав по-прежнему лежит на контрибьюторе. Хотя Google разрешает использование таких инструментов, участники проекта не должны делегировать им критическое мышление или отправлять код, который они сами предварительно не проанализировали и не доработали

#golang #ai

https://kodikapusta.ru/news/838-ai-ili-ne-ai

Поддержать проект на boosty: https://boosty.to/kodikapusta
  • 👍 16
  • 💩 6
  • 🤡 1
  • 🗿 1
Post #117 9.9K
🎉 Вышел Go 1.26! 🎉

Не получилось написать об этом день в день, поэтому пишу на следующий день.

Ключевое из релиза:

• Функция new теперь принимает не только типы, но и обычные аргументы. Т.е. раньше можно было писать new(int), а теперь станет возможным ещё и new(42). Использовать в качестве замены &MyStruct{…} (т.е. new(MyStruct{…}) не рекомендую, тк генерирует менее производительный код. Подробно про новую поведение функции я писал тут.

• Type-parameters в типах теперь могут ссылаться сами на себя:

type Adder[A Adder[A]] interface {
Add(A) A
}


Это довольно техническое изменение, которое позволит авторам библиотек со всякими коллекциями лучше выражать требования к типам от пользователя. Если вы не сталкивались с этой проблемой, значит вы счастливый человек и для вас ничего не поменяется.

• go fix полностью переделали: теперь он модернизирует код, заменяя устаревшие конструкции более современными. Перед тем как применять можно глянуть diff через go fix -diff. Из интересного: с помощью управляющего комментария //go:fix inline над функцией можно заменить её вызов на её тело по коду в автоматическом режиме. Обещают в ближайших постах в блоге рассказать больше о новом go fix и как оно работает внутри.

• go mod init при создании нового модуля теперь выставляет версию Go 1.N-1 где N это версия, бинарь которой вы вызываете. Т.е. при вызове на компиляторе go 1.26.0 в go.mod будет выставлено go 1.25.0. Говорят, что сделано для улучшения обратной совместимости внутри экосистемы: чтобы больше людей писало код который будет работать на всех поддерживаемых версиях компилятора.

• Green Tea сборщик мусора теперь является основным. Обещают снижение затрат на сборщик мусора от 10 до 40 процентов, и еще 10 сверху если используете новые amd64 процессоры типо Ice Lake и Amd Zen 4. Я так и не назрел написать статью про новый сборщик, тк пока я размышлял об этом, ребята сами написали отличный пост в блоге с картинками и видео. Рекомендую, там много интересных деталей.

• Оверхед на вызов функций через CGO теперь меньше на 30 процентов. В практических терминах это значит, что sqlite стал ещё быстрее.

• Адрес начала хипа теперь случайный на 64 битных платформах. Если вам это не о чем не говорит, даже не заморачивайтесь 😄.

• Экспериментальный профилировщик для «утекших» горутин. Мега крутая фича которую завезли ребята из Uber (параллельно написав научную статью). Поиграться можно вот тут. Фича полностью production ready хотя и активируется с помощью флага GOEXPERIMENT=goroutineleakprofile во время сборки. Причина: хотят собрать фидбэк перед финализацией API.

• Новый пакет simd/archsimd для тех кто работает с большими массивами числовых данных. Спрятан за флагом GOEXPERIMENT=simd.

• Новый пакет runtime/secret для тех кому есть, что скрывать кто работает с криптографией. Подробнее писал тут. Скрыт за флагом GOEXPERIMENT=runtimesecret.

• Новая дженерик функция errors.AsType на замену errors.As. Теперь можно писать

pathError, ok := errors.AsType[*fs.PathError](err)


Подробнее писал тут.

• fmt.Errorf("x") теперь аллоцирует столько же, сколько и errors.New("x"), поэтому у вас меньше поводов делать этот рефакторинг.

• Новый флаг -artifacts для go test позволяет настроить каталог для хранения артефактов (файлов которые должны пережить конец тестирования). Сам каталог доступен через T.ArtifactDir и компанию.

• Разные оптимизации подъехали.

Из трендов: язык явно ускоряется в своей эволюции, поэтому на помощь программистам подтягивают тулинг (go fix) который позволит оставаться «в контексте». Но шестимесячного цикла, ребятам отвечающим за компилятор и библиотеку, явно не хватает и поэтому много вещей находятся за экспериментальными флагами. Получается классическая дилемма регулярных релизов: либо тащить условно готовые вещи, либо регулярно срывать сроки. И судя по другим предложениям которые находятся в статусе likely accept следующий релиз вероятно будет не меньше.
go.dev Go 1.26 Release Notes - The Go Programming Language
  • 🔥 33
  • 👍 7
  • ❤ 6
Post #116 12.3K
😳😳 proposal: spec: generic methods for Go 😳😳

Я не так часто пишу тексты в выходные, но тут случилось исключение, которое я не ожидал увидеть от слова «совсем»: Go Team (а именно Роберт Гризмер, один их трех «столпов» Go) предлагает добавить в язык дженерик методы.

Тут надо сделать отступление: просьбы об этом от сообщества шли давно. Невозможность иметь дженерик методы существенно усложняла часть кода и делала невозможными «поточные» типы. Но сами просьбы разбивались о взаимодействие интерфейсов и дженерик методов у типов: настолько часты были эти просьбы и ответное разъяснение, что в Go FAQ есть специальный пункт про это, который я очень рекомендую прочитать что-бы осознать суть (и глубину) проблемы.

We do not anticipate that Go will ever add generic methods


Так что-же поменялось? Ну во первых «запрос о добавлении дженерик методов в Go» один из самых популярных. 49085 набрало больше 900 положительных emoji, а вопрос «как сделать дженерик методы в Go» остается одним из самых популярных на профильных ресурсах. Во вторых сам Роберт предполагает, что изначальная постановка о дуализме «методы <-> интерфейсы» может быть неверна.

В чем суть нового предложения? По сути предлагается разрешить следующую запись:

type S struct { ... }
func (*S) m[P any](x P) { ... }

type G[P any] struct{ ... }
func (*G[P]) m[Q any](x Q) { ... }


Да-да, теперь можно написать те самые Type[In any].Map[Out any] методы к которым привыкли программисты из С++/Java|C#.

При этом эти методы обладают двумя значимыми ограничениями:

Они не реализуют интерфейс даже при совпадении имени и сигнатуры.

type I interface {
m(int)
}

type H struct{ … }
func (H) m[P any](P) { … }

var h H
var _ I = h // ошибка: сигнатура H.m где m[P any](P) не удовлетворяет m(int) типа I


Пример который более приближен к реальности

type Reader struct{ … }
func (*Reader) Read[E any]([]E) (int, error) { … }


Не удовлетворяет io.Reader даже если в коде есть вызовы (*Reader).Read[byte].

Их нельзя «увидеть» с помощью пакета reflection.
Так как инстанцирование методов происходит во время компиляции, рантайм банально не знает как «увидеть» этот метод динамически. И вызвать его тоже не может.

Сам proposal прописывает довольно много технических подробностей и необходимую работу внутри компилятора (которой, на удивление, относительно немного). Но главное тут другое: основная мотивация это удобство записи: x.a().b().c() писать легче чем c(b(a(x)) и отсутствие дженерик методов существенно усложняет процесс портирования streaming типов из других языков. Насколько хороша эта мотивация покажет время, но тот факт, что автором предложения является один из оригинальных авторов языков, а так-же то, что предложение (на данный момент) позитивно принято сообщество (400+ позитивных emoji) наводит на мысль, что проблема действительно актуальна.

P.S: оригинальный proposal про дженерики содержал такой параграф.

Or, we could decide that parameterized methods do not, in fact, implement interfaces, but then it's much less clear why we need methods at all. If we disregard interfaces, any parameterized method can be implemented as a parameterized function.


Те авторы уже изначально закладывали вариант, что могут и передумать. Ну вот и передумали. 😁️️️️️️
go.dev Frequently Asked Questions (FAQ) - The Go Programming Language
  • 🔥 18
  • ❤ 7
  • 👍 3
Post #115 3.46K
🚀️️️️️️ proposal: spec: direct reference to embedded fields in struct literals 🚀️️️️️️

Embedding структур часто используется как некая «замена наследованию», для того что-бы объединить общий код для нескольких типов внутри одного встраиваемого типа. Это довольно удобно, тк вместе с полями мы получаем еще и методы структуры, при этом обращаться к ним можно как через имя встроенной структуры, так и напрямую. Например


type E struct {
A int
}

type T struct {
E
}

var v T
v.E.A = 100
println(v.A)


Однако «символьная» инициализация подобной структуры всегда требовала полный синтаксис:


v := T{E: E{A: 1}}


Читается сие, на мой взгляд, довольно сложно. Есть и другая проблема: такую методику «выноса» нельзя использовать как рефакторинг, ведь мы ломаем инициализацию у пользователей нашего кода. Этим озаботились и сами разработчики компилятора Go, и предложили разрешить обращаться к полям встроенной структуры, как к родным в момент инициализации. Т.е. В будущем можно будет писать и так:


v := T{A: 1}


Правда есть одно но: а что делать если встроена не структура, а указатель? Кидать панику? Делать «неявную» аллокацию для встроенного указателя? А если таких «встроек» несколько?

Из-за потенциальной (и множественной) сложности выводов, на данный момент, принято решение разрешить новый синтаксис инициализации только для полей-значений. Т.е. код


type F struct {
*E
}

v := F{A: 100}


как и раньше, не скомпилируется. На мой взгляд, это хорошее решение.

Статус issue: likely accept accepted!, а значит есть все шансы увидеть новый синтаксис в Go 1.27.

П.С. Само предложение датируется аж 2015ым. Похоже Go Team основательно взяла курс на разгребание старых проблем.
GitHub spec: direct reference to embedded fields in struct literals · Issue #9859 · golang/go (Status: referred from LanguageChange to Proposal. --adonovan) Consider type E struct { A int } type T struct { E } This works: T{E: E{A: 1}} This does not: T{A: 1} Makes some struct literals more ...
  • 👍 20
  • ❤ 2
Post #114 2.82K
Антон традиционно публикует список нововведений которые приедут к нам с Go 1.26. Самое интересное это new(…expr…), pprof для ловли утечки горутин и обновленный go fix. Рекомендую ознакомится, тем более всё представлено в интерактивном виде.
Telegram Thank Go! Здравый взгляд на язык программирования Go. Злой админ @nalgeon. Добрый админ @mikeberezin. Рекламы нет.
  • 🔥 5
Post #113 2.62K

Forwarded from Thank Go! (Anton Zhiyanov)

Интерактивный тур по Go 1.26

Опубликовал традиционный тур по будущему релизу (на англ). Часть фич мы с вами уже разобрали, а часть еще разберем, но если хотите прочитать все вместе уже сейчас — добро пожаловать.

Вот что вошло:

— new(expr)
— Безопасная проверка ошибок
— Новый «чайный» GC
— Ускоренный cgo и выделение памяти
— SIMD для amd64
— Секретный режим
— Криптография без ридеров
— Профиль для ловли утекающих горутин
— Метрики состояния горутин
— Итераторы в reflect
— Подсматривание в байтовый буфер
— Дескриптор процесса ОС
— Сигнал как причина в контексте
— Сравнение IP-подсетей
— Dialer с контекстом
— Фальшивый example.com
— Оптимизированные fmt.Errorf и io.ReadAll
— Множественные хендлеры в логах
— Артефакты тестов
— Обновленный go fix

Это жесть сколько всего они в релиз запихнули 😅

https://antonz.org/go-1-26
  • 🔥 19
  • ❤ 4
  • ✍ 2
Post #112 3.42K
Про go mod tidy | verify | download (Part 2)

Получается, что на практике подделать запись (или случайно закараптить модуль) довольно сложно, тк проверка идет из нескольких мест. Однако потенциальная атака существует:

• Атакующий может переписать модуль, его архив и ziphash файлы.
• Затем атакующий переписывает хеш внутри go.sum ваших проектов.
• Тогда, даже если вы перед сборкой делаете go mod download и go mod verify, то компилятор не заподозрит подмену.

Проблема этой атаки заключается в том, что стоит вам вычистить ziphash файлы из кеша и вся эта схема разваливается. Одна сложность — отдельной команды я под это не нашел, но в качестве замены можно взять следующую команду


find $GOPATH/pkg/mod/cache/ -type f -name "*.ziphash" | xargs -rn1 rm
  • ❤ 4
  • 🔥 4
  • 👍 2
  • 🗿 1
Older posts →

About this channel

How can I read @go_update without a Telegram account?
TGViewer shows the public web preview Telegram publishes for Go Update: recent posts, photos, videos and the subscriber count, with no app, login or account.
How many subscribers does Go Update have?
Go Update (@go_update) has 3.23K subscribers on Telegram, refreshed roughly every 30 minutes.
Does Go Update know I viewed it here?
No. Public channel previews carry no viewer identity, and TGViewer has no accounts or tracking of what you look up.
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →