1.93K subscribers
3.56K photos
136 videos
15 files
3.77K links
Блог со звёздочкой.

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

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
#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😁9🤯1
#prog #article

On the purported benefits of effect systems

Don’t get me wrong, I think effect systems are cool because of the ability to define custom control flow operations in libraries.

However, the wide variety of purported benefits do not seem to stand up to close scrutiny.
👎3👍2
#prog #article

Advent of compiler optimizations — сборник декабрьских статей, по одной в день (в обратном хронологическом порядке), демонстрирующих на отдельных небольших примерах различные оптимизации компиляторов. Написано Мэттом Годболтом (да-да, тот самый, который godbolt.org).
🔥82
#prog #rust #c #article

Eurydice: a Rust to C compiler (yes)

Eurydice is a compiler from Rust to C that aims to produce readable C code.


Сделано для интеграции кода на Rust в существующие проекты на C без того, чтобы требовать наличие двух параллельных реализаций.

Присутствует чуть-чуть джеркования:

Having a backwards-compat scenario where Rust can be compiled to C serves several purposes.
<...>
3. It allows for a census of problematic scenarios. By making the Rust version the default (and putting the fallback C behind a --write-us-an-email flag), there is finally a way to enumerate those mythical users who cannot switch to Rust just yet.
4❤‍🔥3
#prog #article

There is no memory safety without thread safety

Memory safety is all the rage these days. But what does the term even mean? <...> Typically, people use this term to refer to languages that make sure that there are no use-after-free or out-of-bounds memory accesses in the program. This is then often seen as distinct from other notions of safety such as thread safety, which refers to programs that do not have certain kinds of concurrency bugs. However, in this post I will argue that this distinction isn’t all that useful, and that the actual property we want our programs to have is absence of Undefined Behavior.
👍10🤔3
#prog #rust #article

What's "new" in Miri (and also, there's a Miri paper!)

It is time for another “what is happening in Miri” post. In fact this is way overdue, with the previous update being from more than 3 years ago <...>
5
#prog #article

On 'function coloring'

Exposing asynchrony in our programming model does create a distinction between two different kinds of functions. But that distinction always existed, it just wasn’t visible. It was just always handled on our behalf.
👍51🤔1
#prog #article

How uv got so fast

uv is fast because of what it doesn’t do, not because of what language it’s written in. The standards work of PEP 518, 517, 621, and 658 made fast package management possible. Dropping eggs, pip.conf, and permissive parsing made it achievable. Rust makes it a bit faster still.

pip could implement parallel downloads, global caching, and metadata-only resolution tomorrow. It doesn’t, largely because backwards compatibility with fifteen years of edge cases takes precedence. But it means pip will always be slower than a tool that starts fresh with modern assumptions.
👍17
#prog #rust #article

OnceMap: Rust Pattern for Running Concurrent Work Exactly Once

When multiple tasks need the same resource, how do you ensure the work happens exactly once? uv’s solution is OnceMap - a lightweight concurrent memoization primitive that powers deduplication across the resolver and installer.
Не смотря на то, что код приведён для Rust, подход, судя по всему, можно адаптировать и под другие языки.
🤔32
#prog #article

snuffle / salsa / chacha

Небольшой текст про анатомию ChaCha20, крутое свойство этого шифра (которым обладают далеко не все поточные шифры) и про то, как это шифр был рождён из-за, внезапно, #politota соображений.
👍8
#prog #article

GSoC 2025: Usability Improvements for the Undefined Behavior Sanitizer

clang поддерживает несколько санитайзеров, в том числе UBSan для отловки неопределённого поведения (с оговорками). Запускать их при этом можно в двух разных режимах. Первый — с добавлением рантайма, который при детектировании UB перед завершением работы программы печатает, что конкретно пошло не так. Второй вариант — без рантайма, в котором при детектировании UB просто исполняется trap-инструкция процессора.

Второй вариант больше годится для случаев, когда важны оверхед на производительность и размер компилированного кода (в embedded, например). Проблема в том, что UX у такого решения ужасный: получай аварийное завершение программы, а что именно пошло не так — гадай сам. И даже дебаггер в этих случаях не особо помогает, потому что он максимум укажет на инструкцию рядом с trap и на соответствующую строку исходного кода, но не более.

Anthony Tran задался целью исправить этот недостаток. С этой целью он модифицировал кодогенерацию так, чтобы к trap-инструкции прицеплялась отладочная информация, в которую уже включалось человекочитаемое сообщение об ошибке. Этот подход хорош тем, что сразу же подхватывается существующими отладчиками. Разумеется, дополнительная отладочная информация требует места, но оверхед на размер кода на практике пренебрежимо мал.

Не обошлось без костылей из-за ограниченности DWARF:

To accomplish this, we needed to find a place to “stuff” the string in the DWARF DIE tree. Using a
DW_TAG_subprogram was deemed the most straightforward and space-efficient location. This means we create a synthetic DISubprogram which is not a real function in the compiled program; it exists only in the debug info as a container.
<...>
When a trap is hit in the debugger, the debugger retrieves this string from the debug info and shows it as the reason for trapping.
👍8
#prog #rust #article

What does it take to ship Rust in safety-critical?

Статья про очень конкретные препятствия к использованию Rust в safety-critical системах.

Это именно препятствия, а не блоки — в этих областях Rust уже используется в проде.
🤔2
#prog #rust #article

Офигенно!

Rust's standard library on the GPU

GPU code can now use Rust's standard library. We share the implementation approach and what this unlocks for GPU programming.


This works because of our custom hostcall framework. A hostcall is analogous to a syscall. A hostcall is a structured request from GPU code to the host CPU to perform something it cannot execute itself. You can think of it like a remote procedure call from the GPU to the host to achieve syscall-like functionality.

To end users, Rust's std APIs appear unchanged and act as one would expect.
12👍7
#prog #c #article

You (probably) don’t need to learn C

I’m all for learning C if it will be useful for the job at hand, but you can write lots of great software without knowing C. [выделение моё]

A few people repeated the idea that C teaches you how code “really” executes. But C is an abstract model of a computer, and modern CPUs do all kinds of things that C doesn’t show you or explain. Pipelining, cache misses, branch prediction, speculative execution, multiple cores, even virtual memory are all completely invisible to C programs.

C is an abstraction of how a computer works, and chip makers work hard to implement that abstraction, but they do it on top of much more complicated machinery.
5👍3💩3😁2
#math #article

Hobby’s algorithm for aesthetic Bézier splines

Разновидность сплайнов для "гладкой" интерполяции точек, которая быстро работает (пропорционально числу точек) и зачастую даёт эстетически приятные результаты. Из недостатков: передвижение опорных точек меняет форму всей кривой, и малое передвижение опорной точки может привести к радикальной смене формы кривой в районе этой точки.

В самом начале есть интерактивная демонстрация.
🤔2
#prog #article

A Tale Of Four Fuzzers

Восхитительная статья от matklad-а, в частности, хорошая демонстрация того, как писать фаззеры.

Some time ago we overhauled TigerBeetle’s routing algorithm to better handle varying network topologies in a cluster. That turned out to be an interesting case study of practical generative testing (or fuzzing) for non-trivial, real-world code. We ended up adding not one, not even two, but four very different new fuzzers to the system! Let’s talk about why just one fuzzer is not enough.
👍6