Valentyn Kit

@valentynkit.com

Systems engineer. ~6 yrs production backends; distributed systems in C & Rust. I build the smaller, wronger version of everything I depend on, to see how the real one works. Heading toward Solana protocol.

Every feature a language adds is one more thing every future reader of your code has to know, and that cost never shows up in the benchmark. Simple and easy aren't the same word: easy is familiar, simple is one idea not tangled with three others.

Bild

The compiler is the opposite of an LLM, and I think people are starting to use it like one. An LLM guesses: same question, two answers, most confident when it's wrong. A compiler proves: same input, same answer, and it points at the exact line.

Bild

A Rust one for you: iterate a HashMap with a for loop, and inside the loop remove the exact key the loop is currently on. Does it compile? If you think it does, what happens when you run it?

Bild

You don't understand a system until you've rebuilt a worse version of it. Using it teaches you the interface. Rebuilding it teaches you the constraints, and the constraints are where understanding lives.

Bild

Rust has no null. Tony Hoare called null his billion-dollar mistake, and Rust just left it out. A value that might be missing gets a different type: Option, not String, and the compiler won't let you use one as the other.

Bild

Same program, two outputs: 255u8 + 1 panics under cargo build, prints 0 under --release. Defined wrap, not UB. overflow-checks = true if you want release to panic too. wrapping_add if the wrap is the point.

Bild

Rebuilding my Redis clone's AOF in Rust. BufWriter erases the buffering discipline C forced on me. But flush() only reaches the kernel, sync_all() is what reaches the disk, and Drop's automatic flush ignores its error. The mechanics compile away; the durability policy doesn't.

Bild

Vec::new() never touches the heap. Capacity stays 0 until the first push, then 4 for small types, doubling after. Free to create, pay on first write. I'd used it for years without checking where the first allocation actually lands.

Bild

I built a small Redis clone in C: RESP parser, command table, append-only file, the works. Now I'm rebuilding the same thing in Rust. Redoing a finished project has been the best language learning I've done.

I built a small Redis clone in C: RESP parser, command table, append-only file, the works. Now I'm rebuilding the same thing in Rust. Redoing a finished project has been the best language learning I've done.

I'm learning Rust by writing C. Backwards, I know. But every Rust feature answers a specific C pain, and you don't feel the answer until you've felt the pain. Write the manual error check 50 times in C, and ? stops being syntax and starts being relief.

I spent a week fighting "expected String, found &str" before it clicked. String owns its bytes on the heap and can grow. &str borrows a view into bytes someone else owns. The rule that ended it: take &str in args, return String when you built it.

A week of C reminded me what one character buys in Rust: the ? Every C syscall ends the same. Returned -1? Read errno, decide fatal or retry, handle it. Copy-pasted around every read and write. Rust folds that whole ritual into ?, a check you can't forget.

I froze my own TCP server for 1.51 seconds with one idle connection. No load. One client just holding the line. A second connected and waited 1.5s for a reply. That's when I actually understood why event loops exist. Not from a blog, from breaking it myself.

"Rust is hard" is mostly the first time a language makes you be honest about who owns your data. C didn't make ownership simpler. It just let you ship the bug and find out in production.

"How do you serve 10,000 clients with one program?" A 25-year-old question, the C10K problem. The answer is a ladder of I/O models. Each rung fixes the wall the last one hit. I rebuilt all seven in C this week, blocking up to epoll, to feel every wall myself.

"Rust is hard" is mostly the first time a language makes you be honest about who owns your data. C didn't make ownership simpler. It just let you ship the bug and find out in production. #rust

The Rust borrow checker clicked when I stopped reading it as a style rule and started reading it as a use-after-free detector at compile time. Borrow an element of a Vec, then push to it. The push can reallocate the buffer, so your reference would dangle. C compiles that. Rust won't.

Bild

I've started contributing to rust-lang, deliberately on the low-level I/O side. Two PRs merged in the past couple of weeks. The latest: a new io::ErrorKind::TooManyOpenFiles. Before it, running out of file descriptors (EMFILE/ENFILE) decoded to a generic Uncategorized.

Bild

one odd thing about LLMs with programming is like... okay so obviously we all construct English and other human languages and sentences, and it learns from them when it talks but seeing code patterns that it learned that i specifically had a hand in creating is like, wild