<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: kprotty</title><link>https://news.ycombinator.com/user?id=kprotty</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Tue, 28 Apr 2026 17:52:52 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=kprotty" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by kprotty in "Type resolution redesign, with language changes to taste"]]></title><description><![CDATA[
<p>Zig gives things we really dont have yet: C + generics + good const eval + good build system + easy cross compilation + modern niceties (optionals, errors, sum types, slices, vectors, arbitrary bit packing, expression freedom).<p>Are there any other languages that provide this? Would genuinely consider the switch for some stuff if so.</p>
]]></description><pubDate>Wed, 11 Mar 2026 14:06:58 +0000</pubDate><link>https://news.ycombinator.com/item?id=47335748</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=47335748</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47335748</guid></item><item><title><![CDATA[New comment by kprotty in "Type resolution redesign, with language changes to taste"]]></title><description><![CDATA[
<p>There are places a language could be a better fit, but which haven't adopted it. E.g. most languages over typescript on the backend, most systems programming languages over Java for games.</p>
]]></description><pubDate>Wed, 11 Mar 2026 14:02:28 +0000</pubDate><link>https://news.ycombinator.com/item?id=47335699</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=47335699</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47335699</guid></item><item><title><![CDATA[New comment by kprotty in "Type resolution redesign, with language changes to taste"]]></title><description><![CDATA[
<p>Yes, I've written a few unsafe-focused crates [0], some of which have been modified & merged into the stdlib [1] [2] exposing them to the fringe edge-cases of Rust like strict provenance.<p>IMO, Rust is good for modeling static constraints - ideal when there's multiple teams of varying skill trying to work on the same codebase, as the contracts for components are a lot clearer. Zig is good for expressing system-level constructs efficiently: doing stuff like self-referential/intrusive data structures, cross-platform simd, and memory transformations is a lot easier in Zig than Rust.<p>Personally, I like Zig more.<p>[0] <a href="https://crates.io/users/kprotty" rel="nofollow">https://crates.io/users/kprotty</a><p>[1] <a href="https://github.com/rust-lang/rust/pull/95801" rel="nofollow">https://github.com/rust-lang/rust/pull/95801</a><p>[2] <a href="https://github.com/rust-lang/rust/blob/a63150b9cb14896fc22f9275c32682423de94d48/library/std/src/sys/sync/rwlock/queue.rs#L37" rel="nofollow">https://github.com/rust-lang/rust/blob/a63150b9cb14896fc22f9...</a></p>
]]></description><pubDate>Wed, 11 Mar 2026 13:32:17 +0000</pubDate><link>https://news.ycombinator.com/item?id=47335352</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=47335352</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47335352</guid></item><item><title><![CDATA[New comment by kprotty in "Type resolution redesign, with language changes to taste"]]></title><description><![CDATA[
<p>I've worked on two "production" zig codebases: tigerbeetle [0] and sig [1].<p>These larger zig projects will stick to a tagged release (which doesn't change), and upgrade to newly tagged releases, usually a few days or months after they come out. The upgrade itself takes like a week, depending on the amount of changes to be done. These projects also tend to not use other zig dependencies.<p>[0]: <a href="https://github.com/tigerbeetle/tigerbeetle/pulls?q=is%3Apr+author%3Akprotty+is%3Aclosed" rel="nofollow">https://github.com/tigerbeetle/tigerbeetle/pulls?q=is%3Apr+a...</a><p>[1]: <a href="https://github.com/Syndica/sig/pulls?q=is%3Apr+author%3Akprotty+is%3Aclosed" rel="nofollow">https://github.com/Syndica/sig/pulls?q=is%3Apr+author%3Akpro...</a></p>
]]></description><pubDate>Wed, 11 Mar 2026 07:40:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=47332680</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=47332680</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47332680</guid></item><item><title><![CDATA[New comment by kprotty in "Inside Rust's std and parking_lot mutexes – who wins?"]]></title><description><![CDATA[
<p>> so you have no clue if the shared data might be incompletely modified or otherwise logically corrupted.<p>One can make a panic wrapper type if they cared: It's what the stdlib Mutex currently does:<p>MutexGuard checks if its panicking during drop using `std::thread::panicking()`, and if so, sets a bool on the Mutex. The next acquirer checks for that bool & knows state may be corrupted. No need to bake this into the Mutex itself.</p>
]]></description><pubDate>Mon, 24 Nov 2025 19:07:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=46037840</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=46037840</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46037840</guid></item><item><title><![CDATA[New comment by kprotty in "Low-Level Optimization with Zig"]]></title><description><![CDATA[
<p>C++'s `::` vs Zig's `.`<p>C++'s `__builtin_` (or arguably `_`/`__`) vs Zig's `@`</p>
]]></description><pubDate>Sat, 07 Jun 2025 18:02:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=44211354</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=44211354</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44211354</guid></item><item><title><![CDATA[New comment by kprotty in "Zig; what I think after months of using it"]]></title><description><![CDATA[
<p>There's compiler-level traits like `Iterator` and `Future` which enforce references. If wanting to do intrusive pointers into them, one risks creating overlapping references: <a href="https://github.com/tokio-rs/tokio/issues/3399">https://github.com/tokio-rs/tokio/issues/3399</a></p>
]]></description><pubDate>Thu, 06 Feb 2025 15:21:32 +0000</pubDate><link>https://news.ycombinator.com/item?id=42963199</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=42963199</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42963199</guid></item><item><title><![CDATA[New comment by kprotty in "Disruptor-rs: better latency and throughput than crossbeam"]]></title><description><![CDATA[
<p>Tokio's focus is on low <i>tail</i>-latencies for networking applications (as mentioned). But it doesn't employs yield_now for waiting on a concurrent condition to occur, even as a backoff strategy, as that fundamentally kills tail-latency under the average OS scheduler.</p>
]]></description><pubDate>Sat, 13 Jul 2024 17:34:58 +0000</pubDate><link>https://news.ycombinator.com/item?id=40955475</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=40955475</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=40955475</guid></item><item><title><![CDATA[New comment by kprotty in "Hashmaps in Factor are faster than in Zig"]]></title><description><![CDATA[
<p>Thanks, seems like most are from LLVM or packed structs.</p>
]]></description><pubDate>Sun, 12 Nov 2023 20:03:05 +0000</pubDate><link>https://news.ycombinator.com/item?id=38243604</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=38243604</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=38243604</guid></item><item><title><![CDATA[New comment by kprotty in "Hashmaps in Factor are faster than in Zig"]]></title><description><![CDATA[
<p>Are there any links / examples for the miscompilations?</p>
]]></description><pubDate>Sat, 11 Nov 2023 10:28:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=38229049</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=38229049</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=38229049</guid></item><item><title><![CDATA[New comment by kprotty in "Was Rust Worth It?"]]></title><description><![CDATA[
<p>> Green threads give you all the advantages of async<p>They require more memory over stackless coroutines as it stores the callstack instead of changing a single state. They also allow for recursion, but its undelimited meaning you either 1) overrun the guard page and potentially write to another Green thread's stack by just declaring a large local variable 2) enable some form of stack-probing to address that (?) or 3) Support growable stacks which requires a GC to fixup pointes (isn't available in a systems lang).<p>> green threads should run faster, as storing state on a stack is generally faster than malloc.<p>Stackless coroutines explicit don't malloc on each call. You only allocate the intial state machine (stack in GreenThread terms).<p>> The primary objection seems to be speed<p>It's compatibility. No way to properly set the stack-size at compile time for various platforms. No way to setup guard pages in a construct that's language-level so should support being used without an OS (i.e. embedded, wasm, kernel). The current async using stackless coroutines 1) knows the size upfront due to being a compiler-generated StateMachine 2) disallows recursion (as that's a recursive StateMachine type, so users must dynamically allocate those however appropriate) which works for all targets.</p>
]]></description><pubDate>Fri, 27 Oct 2023 14:55:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=38039294</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=38039294</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=38039294</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>This would imply a single/global runtime along with an unrealistic API surface;<p>For 1) It's common enough to have multiple runtimes in the same process, each setup possibly differently and running independently of each other. Often known as a "thread-per-core" architecture, this is the scheme used in apps focused on high IO perf like nginx, glommio, actix, etc.<p>For 2) runtime (libasync.so) implementations would have to cover a lot of aspects they may not need (async compute-focused runtimes like bevy don't need timers, priorities, or even IO) and expose a restrictive API (what's a good generic model for a runtime IO interface? something like io_uring, dpdk, or epoll? what about userspace networking as seen in seastar?). A pluggable runtime mainly works when the language has a smaller scope than "systems programming" like Ponylang or Golang.<p>As a side note; Rust tries to decouple the scheduling of Futures/tasks using its concept of Waker. This enables async implementations which only concern themselves with scheduling like synchronization primitives or basic sequencers/orchestration to be runtime-agnostic.</p>
]]></description><pubDate>Sat, 09 Sep 2023 23:08:21 +0000</pubDate><link>https://news.ycombinator.com/item?id=37451204</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37451204</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37451204</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>Preemption simulates localized concurrency (running multiple distinct things <i>logically</i> at the same time) not parallelism (running them <i>physically</i> at the same time). You can have concurrency outside continuations. OS threads for example are not continuations, but still express concurrency to the kernel so that it can (not guaranteed) express concurrency to the physical CPU cores which hopefully execute the concurrent code in parallel (not guaranteed again, due to hyperthreading).</p>
]]></description><pubDate>Sat, 09 Sep 2023 17:30:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447834</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447834</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447834</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>getaddrinfo() is a synchronous function that can do network requests to resolve DNS. The network property isn't reflected in its function signature becoming async. You can have an async_getaddrinfo() which does, but the former is just a practical example of network calls in particular being unrelated to function coloring.</p>
]]></description><pubDate>Sat, 09 Sep 2023 17:22:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447757</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447757</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447757</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>no, .Wait in C# or block_on in Rust keep the caller sync while evaluating the async callee, preventing the "bubble up".</p>
]]></description><pubDate>Sat, 09 Sep 2023 17:19:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447731</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447731</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447731</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>> The main problem is that tokio futures are 'static<p>An important distinction to make is that tokio Futures aren't 'static, you can instead only spawn (take advantage of the runtime's concurrency) 'static Futures.<p>> This implies that you can't statically guarantee that a future is cleaned up properly.<p>Futures need to be Pin'd to be poll()'d. Any `T: !Unpin` that's pinned must eventually call Drop on it [0]. A type is `!Unpin` if it transitively contains a `PhantomPinned`. Futures generated by the compiler's `async` feature are such, and you can stick this in your own manually defined Futures. This lets you assume `mem::forget` shenanigans are UB once poll()'d and is what allows for intrusive/self-referential Future libraries [1]. The future can still be leaked from being kept alive by an Arc/Rc, but as a library developer I don't think you can/would-care-to reasonably distinguish that from normal use.<p>[0]: <a href="https://doc.rust-lang.org/std/pin/#drop-guarantee" rel="nofollow noreferrer">https://doc.rust-lang.org/std/pin/#drop-guarantee</a><p>[1]: <a href="https://docs.rs/futures-intrusive/latest/futures_intrusive/" rel="nofollow noreferrer">https://docs.rs/futures-intrusive/latest/futures_intrusive/</a></p>
]]></description><pubDate>Sat, 09 Sep 2023 17:17:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447710</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447710</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447710</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>Replacing Pin with Rc is what they refer to as "Arc shit up". Pin avoids the need for a heap allocation like Rc/Arc entirely.</p>
]]></description><pubDate>Sat, 09 Sep 2023 17:03:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447540</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447540</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447540</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>Tokio and glommio using interrupts is ironically another misconception. They're cooperatively scheduled so yes, a misbehaving blocking task can stall the scheduler. They can't really interrupt an arbitrary stackless coroutine like a Future due to having nowhere to store the OS thread context in a way that can be resumed (Each thread has its own stack, but now it's stackful with all the concerns of sizing and growing. Or you copy the stack to the task but now have somehow to fixup stack pointers in places the runtime is unaware).<p><a href="https://tokio.rs/blog/2020-04-preemption#a-note-on-blocking" rel="nofollow noreferrer">https://tokio.rs/blog/2020-04-preemption#a-note-on-blocking</a><p>> Tokio does not, and will not attempt to detect blocking tasks and automatically compensate</p>
]]></description><pubDate>Sat, 09 Sep 2023 16:55:53 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447441</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447441</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447441</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>The cost of switching goroutines, rust Futures, Zig async Frames, or fibers/userspace-tasks in general is on the other of a few nano-seconds whereas it's in the micro-second range for OS threads. This allows you to spawn tons of tasks and have them all communicate with each other very quickly (write to queue; push receiver to scheduler runqueue; switch out sender; switch to receiver) whereas doing so with OS threads would never scale (write to queue; syscall to wake receiver; syscall to switch out sender). Any highly concurrent application (think games, simulations, net services) uses userspace/custom task scheduling for similar reasons.</p>
]]></description><pubDate>Sat, 09 Sep 2023 16:42:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447310</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447310</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447310</guid></item><item><title><![CDATA[New comment by kprotty in "Maybe Rust isn’t a good tool for massively concurrent, userspace software"]]></title><description><![CDATA[
<p>Both qualify for writing tiny web servers, cli/byte-manipulation scripts, server automation jobs, in-house GUI applications, and other small stuff. Could technically argue that these are a "relatively little overlap" depending on what you do though..</p>
]]></description><pubDate>Sat, 09 Sep 2023 16:32:31 +0000</pubDate><link>https://news.ycombinator.com/item?id=37447197</link><dc:creator>kprotty</dc:creator><comments>https://news.ycombinator.com/item?id=37447197</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37447197</guid></item></channel></rss>