1.92K subscribers
3.78K photos
144 videos
15 files
3.97K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
🌚15😁11💯2💩1
#prog #typescript

В Microsoft решили из-за проблем с производительностью переписать компилятор Typescript с Typescript на... #Go. Выбор языка аргументируют сочетанием контроля над раскладкой структур в памяти вкупе со сборщиком мусора и лёгкостью портирования уже имеющегося кода. На мой взгляд, очень странный выбор.
Производительность, впрочем, действительно улучшилась — прототип уже в состоянии компилировать реальные проекты на порядок быстрее.
😁17👍15❤‍🔥3🤡2🤔1
Блог*
#prog #go #article Статья о внутреннем устройстве map в Go. К сожалению, в статье длиннющая преамбула о различных вариантах реализации хэш-таблиц в разных языках и крайне мало о собственно реализации в Go. Ключевая фишка реализации — фактически нетипизированная…
#prog #go

В феврале выпустили версию Go 1.24, в которой, помимо всего прочего, поменяли реализацию встроенного типа map. Теперь там используется дизайн Swisstable. Ожидаемо перформанс операций на мапах ощутимо подрос:

In microbenchmarks, map operations are up to 60% faster than in Go 1.23. Exact performance improvement varies quite a bit due to the wide variety of operations and uses of maps, and some edge cases do regress compared to Go 1.23. Overall, in full application benchmarks, we found a geometric mean CPU time improvement of around 1.5%.


Тем не менее, реализация всё равно теряет перф из-за гарантий на поведение итерации по мапе, изменяемой в процессе итерации.
👍8🌚1
#prog #rust... #menacingopensource? #go?

🦀 go_visibility_macro 🦀
Because Rust's pub keyword was just too explicit 🔥
Finally, a revolutionary crate that brings Go's brilliant visibility conventions to Rust — because who needs explicit keywords when you can just Capitalize Everything?


use go_visibility_macro::go_visibility;

#[go_visibility]
struct MyStruct { // Automagically `pub`!
PublicField: i32, // Also `pub`!
private_field: i32, // Not `pub` (how sad)
}

#[go_visibility]
impl MyStruct {
fn New() -> Self { // `pub` because it's uppercase!
Self { PublicField: 42, private_field: 69 }
}

fn get_secret(&self) -> i32 { // Still private (loser)
self.private_field
}
}
🤮25🤣23😁4🤯1
😁24👍5🔥4😢4🤡4👎2💯2🤮1
#prog #go #article

[ On | No ] syntactic support for error handling (перевод)

this_is_fine.jpg

For the foreseeable future, the Go team will stop pursuing syntactic language changes for error handling. We will also close all open and incoming proposals that concern themselves primarily with the syntax of error handling, without further investigation.


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

1. Один аргумент говорит о том, что IDE и LLM могут помочь с написанием бойлерплейта, а в IDE можно этот бойлерплейт потом скрывать.
2. Второй аргумент говорит о пользе печати отладкой и возможности поставить точки останова и о том, как специфичный синтаксис этому мешает — дескать, надо на if переписывать, а это затрудняет отладку (???) и может внести тонкие ошибки.

Автор тактично умалчивает о том, что инструменты, описанные в первом аргументе, могут помочь с проблемами во втором. Особенно дико это смотрится с учётом того, что в оригинальном тексте эти два аргумента идут подряд.
😁11🤡9👎2🤔2😭2
— У вас стандартная библиотека работает неправильно.
— Используйте железо, на котором работает правильно.

#prog #go #suckassstory

Source
🍌13🤡7
#prog #go #article

How we found a bug in Go's arm64 compiler

TL;DR: для горутин с большим стеком (больше, чем может быть закодировано в литерале в одной инструкции на ARM) в эпилоге функций изменение sp, регистра, указывающего на верхушку стека, происходило через две операции ADD, обе из которых оперировали на sp непосредственно. Если переключение (preemption) между горутинами происходило между этими двумя операциями, любые операции, которые разворачивали стек — в частности, сборщик мусора — следовали вверх по стеку вызовов по частично обновлённому и потому невалидному значению из sp, и в результате предсказуемо крашились.

Может, ввести отдельный хештег для историй дебага? 🤔
🤡6👍51😱1🌚1
😁49😢20🤔8
#prog #go #article

The Green Tea Garbage Collector

Статья о дизайне нового сборщика мусора для Go, который идейно является всё тем же mark and sweep, но сканирует память страницами вместо того, чтобы отслеживать в очереди каждую индивидуальную аллокацию.

Разумеется, выигрыш по производительности сильно зависит от формы графа объектов (и в некоторых случаях может быть хуже предыдущего), но на практике даже сканирование страниц памяти по 2 процента за раз уже даёт выигрыш.
👍8🤡3
#prog #go #article #suckassstory

В стандартной библиотеке Go есть тип http.Client — HTTP-клиент. Одно из полей этого типа — Transport. Это поле хранит значение, которое занимается обработкой единичных запросов. Разумеется, для поля Transport есть значение по умолчанию — DefaultTransport. Но есть одна загвоздка.

Поле Transport — и, соответственно, DefaultTransport — имеют тип RoundTripper. Это интерфейс с единственным методом:

RoundTrip(*Request) (*Response, error)


DefaultTransport при этом на самом деле является значением типа Transport, у которого бОльшая часть полей является конфигурацией. На практике часто требуется скорректировать конфигурацию по умолчанию под нужды приложения (например, поменять таймауты). Но как это сделать?

Так как в Go нет констант (кроме чисел и строк), DefaultTransport является глобальной переменной пакета http. Соответственно, чтобы не поменять глобальную конфигурацию для всего, что использует http.Client (включая, возможно, код в зависимостях), нужно сначала сделать копию этой конфигурации. Более того, так как DefaultTransport имеет тип интерфейса RoundTripper, сначала нужно привести его к конкретному типу Transport. В итоге на практике во многих проектах на Go есть код наподобие этого:

t := http.DefaultTransport.(*http.Transport).Clone()
// Change properties
t.TLSHandshakeTimeout = time.Second
t.DisableKeepAlives = true


Элемент синтаксиса .(*http.Transport) является кастом интерфейса к конкретному типу, и так как синтаксически это не форма каста, которая возвращает два значения, это "небезопасный" каст, который паникует, если тип отличается от указанного.

Какая по итогу ситуация? Во множестве реально используемых программ на Go есть код, который трогает глобальную переменную (и, так как это Go, без синхронизации), полагается на неявное обещание другого кода эту глобальную переменную не трогать и платят за проверки типов при касте, не смотря на то, что тип так-то известен статически. В теории тот факт, что DefaultTransport является интерфейсом, позволяет поменять реализацию в будущем. На практике из-за существующего кода этого никогда не произойдёт, потому что сломает кучу работающего кода. Поменять тип DefaultTransport также нельзя, потому что это будет ломающим обратную совместимость изменение.

Очевидным выходом из этой ситуации является добавить функцию, которая будет возвращать значение DefaultTransport, как конкретный тип Transport. Соответствующее предложение поступило в мае 2020 года, однако воз и ныне там.
👍15😁91🤯1
😁25🤡6
#prog

В #go тесты работают таким образом: программист делает файлы, имя которых оканчивается на _test.go, и внутри пишет функции вида:

func TestXxx(*testing.T)


(префикс Test обязателен), а команда go test автоматически эти тесты подхватывает и исполняет. Тип testing.T позволяет организовывать тесты: логгировать, запускать подтесты и досрочно прерывать тесты, как ошибочные.

К чему я это? В последней версии GoGo 1.26.0, вышедшей 10 февраля — есть несколько изменений. Одно из них — у кучи функций из подпакетов пакета crypto описаны изменения в духе "функция для генерации ключей теперь игнорирует аргумент, переданный для генерации случайности, и использует криптографически безопасный источник случайности". Разумеется, для тестов желательна воспроизводимость. Но как этого добиться, если источник случайности игнорируется?

Для решения этого вопроса Go предлагает два решения.

Первое — это GODEBUG, костыль способ заставить программы на Go (скомпилированные!) использовать поведение из более старой версии. В данном случае предлагают добавить настройку cryptocustomrand=1. Настройки через GODEBUG не вечные и могут быть убраны в одном из будущих релизов. По этой причине этот способ выглядит не особо привлекательным.

Второе — это использовать новую функцию testing/cryptotest.SetGlobalRandom. Она устанавливает сид для источника случайности, который будет использоваться для всех криптографических функций из пакета crypto, полагающихся на случайные данные. Эти изменения действуют в пределах одного теста, запускаемого testing.T. Соответственно, для каждого теста, который желает воспроизводимости, эту функцию нужно вызывать явно в начале. Разумеется, как справедливо отмечено в документации,

Because SetGlobalRandom affects the whole process, it cannot be used in parallel tests or tests with parallel ancestors.


Воистину concurrent programming language!
🤮25😁10🤩3
#prog #article

BTW PVS-Studio развивают версию своего анализатора для #go, и хотя для широкой публики анализатор ещё не доступен (в апреле будет бета-версия), он уже находит множество ошибок, которые не находит go vet. Все найденные ошибки при этом на Go не завязаны, так что, возможно, в будущем анализатор станет ещё полезнее конкретно для Go.
👍91
Пропозал для обобщённых методов в #go: принимают

Гоферы:
🤡17😁72
Блог*
#prog #go #article Слайсы в Go — это очень просто. medium.com/@gotzmann/so-you-think-you-know-go-c5164b0d0511
#prog #go #article

Go и искусство ставить подножку разработчику: разоблачение

Язык проектировался простым, лёгким в освоении, готовым для написания веб-сервисов с первого дня. Он мог бы таким и остаться, если бы не одна проблема. Проблема отбора.

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

Явно ставилась задача — сделать язык достаточно простым, но не настолько, чтобы собеседование мог пройти любой новичок.

Язык статьи, конечно, полон сарказма, но все указанные неочевидности поведения действительно присутствуют
😁11
Блог*
Photo
#prog #go #article

Go fuzzing was missing half the toolkit. We forked the toolchain to fix it.

With gosentry, go test -fuzz uses LibAFL by default. It can fuzz structs natively, run grammar-based fuzzing with Nautilus, detect bug classes that it couldn’t detect before, and create a fuzzing campaign coverage report in one command.
🔥6
#prog #go

Обширный комментарий на HackerNews о недостатках принятого в Go подхода к управлению зависимостями
😁1🤔1
#prog #go

The Status Quo of Go Custom Generics

Текущие ограничения дженериков в Go. Актуально на версию 1.25
🤣6🤔1😢1
🤣9😁1