<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: withoutboats3</title><link>https://news.ycombinator.com/user?id=withoutboats3</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Tue, 14 Apr 2026 13:44:22 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=withoutboats3" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by withoutboats3 in "Tony Hoare has died"]]></title><description><![CDATA[
<p>This is indeed a great quote (one of many gems from Sir Tony) but I think the context that follows it is also an essential insight:<p>> The first method is far more difficult. It demands the same skill,
devotion, insight, and even inspiration as the discovery of the simple
physical laws which underlie the complex phenomena of nature. It
also requires a willingness to accept objectives which are limited
by physical, logical, and technological constraints, and to accept a
compromise when conflicting objectives cannot be met. No committee
will ever do this until it is too late.<p>(All from his Turing Award lecture, "The Emperor's Old Clothes": <a href="https://www.labouseur.com/projects/codeReckon/papers/The-Emperors-Old-Clothes.pdf" rel="nofollow">https://www.labouseur.com/projects/codeReckon/papers/The-Emp...</a>)</p>
]]></description><pubDate>Tue, 10 Mar 2026 16:31:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=47325498</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=47325498</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47325498</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Creator of Claude Code: "Coding is solved""]]></title><description><![CDATA[
<p>We can tell you think that when we use your app.</p>
]]></description><pubDate>Sat, 21 Feb 2026 09:43:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=47099091</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=47099091</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47099091</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Binary fuse filters: Fast and smaller than xor filters (2022)"]]></title><description><![CDATA[
<p>Cuckoo filters outperform bloom filters and allow dynamic insertion and deletion (unlike bloom filters, which only allow insertion). The trade off is that insertion can fail if the table is too full and then would need to expand or store those entries some other way to avoid a false negative.</p>
]]></description><pubDate>Thu, 22 Jan 2026 15:28:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=46720514</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=46720514</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46720514</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Memory Safety for Skeptics"]]></title><description><![CDATA[
<p>The problem in this conversation is that you are equivocating between "fixing memory safety bugs" and "preventing memory safety bugs statically." When this blog post refers to "memory safety skeptics," it refers to people who think the second is not a good way to expend engineering resources, not your imagined flagrantly irresponsible engineer who is satisfied to deliver a known nonfunctional product.</p>
]]></description><pubDate>Tue, 11 Nov 2025 05:00:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=45884275</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=45884275</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45884275</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Io_uring, kTLS and Rust for zero syscall HTTPS server"]]></title><description><![CDATA[
<p>genuinely so sad to me that you are still grinding this axe. if your fantasy design works so much better - go build it then!</p>
]]></description><pubDate>Fri, 22 Aug 2025 14:07:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=44984882</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=44984882</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44984882</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Constrained languages are easier to optimize"]]></title><description><![CDATA[
<p>Initial comments as I write this are all negative, and also responding to something the blog post didn't claim. The only time it says <i>faster</i> than C is when talking about a language targeting the GPU; it is not controversial that GPUs perform better than CPUs for many workloads.<p>On the other hand, the results of this true fact are already seen in practice in real systems. Rust's iterator adapters, for example, allow high level "functional style" with closures to be compiled to code that is exactly the same as hand rolled C loops without unamortized bounds checks - despite guaranteeing the absence of out of bound accesses even in the face of programmer error - because the constraints of these interfaces and the design of the language enable tons of optimizations by LLVM. This has been true since Rust 1.0 more than a decade ago, it's not a promise of the future.</p>
]]></description><pubDate>Sun, 27 Jul 2025 13:14:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=44701111</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=44701111</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44701111</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Atomics and Concurrency"]]></title><description><![CDATA[
<p>The alternative to C++ that I meant was Rust, which statically prevents data races.</p>
]]></description><pubDate>Fri, 30 May 2025 20:14:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=44139522</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=44139522</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44139522</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Atomics and Concurrency"]]></title><description><![CDATA[
<p>The occurrence of data races depends on the specific non-deterministic sequence of execution of concurrent codepaths. Just because you have 100% code coverage does not mean you've covered every potential execution sequence, and its almost never practical to actually execute every possibility to ensure the absence of data races. Depending on the probability that your data race will occur, it could indeed be something you have to make stars align for TSAN to catch.<p>Not to talk my own book, but there is a well-known alternative to C++ that can actually guarantee the absence of data races.</p>
]]></description><pubDate>Fri, 30 May 2025 16:50:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=44137990</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=44137990</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44137990</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Four Years of Jai (2024)"]]></title><description><![CDATA[
<p>This is exactly the attitude this blog post spends its first section pretty passionately railing against.</p>
]]></description><pubDate>Fri, 18 Apr 2025 10:28:35 +0000</pubDate><link>https://news.ycombinator.com/item?id=43726679</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=43726679</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43726679</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Misty: A secure distributed actor language"]]></title><description><![CDATA[
<p>The IO aspect is not a surprising flaw but it's disappointing to learn that Erlang lets any process enumerate all the other ones.</p>
]]></description><pubDate>Tue, 14 Jan 2025 18:39:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=42701769</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42701769</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42701769</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Misty: A secure distributed actor language"]]></title><description><![CDATA[
<p>Joe Armstrong goes to lengths to describe the benefits of "privately addressable" actors in his thesis (though he uses different terminology). As far as I'm aware, Erlang actors are also privately addressable. cf:<p>> System security is intimately connected with the idea of knowing the name of a process. If we do not know the name of a process we cannot interact with it in any way, thus the system is secure. Once the names of processes become widely know the system becomes less secure. We call the process of revealing names to other processes in a controlled manner the name distribution problem— the key to security lies in the name distribution problem. When we reveal a Pid to another process we will say that we have published the name of the process. If a name is never published there are no security problems.<p>> Thus knowing the name of a process is the key element of security. Since names are unforgeable the system is secure only if we can limit the knowledge of the names of the processes to trusted processes.<p><a href="https://erlang.org/download/armstrong_thesis_2003.pdf" rel="nofollow">https://erlang.org/download/armstrong_thesis_2003.pdf</a> (page 24-25)</p>
]]></description><pubDate>Tue, 14 Jan 2025 18:19:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=42701446</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42701446</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42701446</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Zig's comptime is bonkers good"]]></title><description><![CDATA[
<p>100%. So tiring that the discourse around this is based on 15 minute demos and not actual understandings of the trade offs. Varun Gandhi's post that you link to is great.<p>Based on my experience with Rust, a lot of what people want to do with its "constant generics" probably would be easier to do with a feature like comptime. Letting you do math on constant generics while maintaining parametricity is hard to implement, and when all you really want is "a trait for a hash function with an output size of N," probably giving up parametricity for that purpose and generating the trait from N as an earlier codegen step is fine for you, but Rust's macros are too flexible and annoying for doing it that way. But as soon as you replace parametric polymorphism with a naive code generation feature, you're in for a world of hurt.</p>
]]></description><pubDate>Tue, 07 Jan 2025 09:05:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=42620688</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42620688</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42620688</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Traits are a local maximum"]]></title><description><![CDATA[
<p>Better newtypes are the answer.<p>Consider Java for example. In Java, interfaces are even more restrictive than traits: only the package which defines the class can implement them for that class, not even the package which defines the interface. But this is fine, because if you want to implement an interface for a foreign class, you create a new class which inherits from it, and it can be used like an instance of the foreign class except it also implements this interface.<p>In Rust, to the extent this is possible with the new type pattern it’s a lot of cruft. Making this more ergonomic would ease the burden of the orphan rule without giving up on the benefits the orphan rule provides.</p>
]]></description><pubDate>Fri, 22 Nov 2024 16:23:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=42215104</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42215104</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42215104</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Traits are a local maximum"]]></title><description><![CDATA[
<p>Implementations are not imported <i>at all</i> because they are not named. Like I wrote, named implementations (ala ML modules) is a valid alternative, but one with a much greater annotation burden.<p>You could imagine having named impls that are allowed to be incoherent as an additional feature on top of coherent unnamed impls, but to use them you would need to make any code that depends on their behavior parameterized by the impl as well as the types. In fact, you can pretty trivially emulate that behavior in Rust today by adding a dummy type parameter to your type and traits.<p>Again, it's all a set of trade offs.</p>
]]></description><pubDate>Fri, 22 Nov 2024 14:04:42 +0000</pubDate><link>https://news.ycombinator.com/item?id=42213911</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42213911</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42213911</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Traits are a local maximum"]]></title><description><![CDATA[
<p>Your conclusion is correct. I'm very happy with the two that Rust picked and tired of people pretending that there will be a magical pick three option if we just keep talking about it.</p>
]]></description><pubDate>Fri, 22 Nov 2024 12:56:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=42213439</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42213439</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42213439</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Traits are a local maximum"]]></title><description><![CDATA[
<p>Implementations are not exported or public at all: they are used in functions and those functions are exported. For correctness, you want those implementations to be resolved consistently (this is what coherence is). This post gives the example of unioning two sets: you need to know that they're ordered the same way for your algorithm to work.<p>So the problem isn't that the implementation is public, it's that its used somewhere by a function which is public (or called, transitively, by a public function). For a library, code which is not being used by a public function is dead code, so any impl that is actually used is inherently public.<p>You might say, okay, well can binaries define orphan impls? The problem here is that we like backward compatibility: when a new impl is added to your dependency, possibly in a point release, it could conflict with your orphan and break you. You could allow users, probably with some ceremony, to opt into orphan impls in binaries, with the caveat that they are accepting that updating any of their dependencies could cause a compilation failure. But that's it: if you allow this in libraries, downstream users could start seeing unsolvable, unpredictable compilation failures as point releases of their dependencies introduce conflicts with orphan impls in other dependencies.</p>
]]></description><pubDate>Fri, 22 Nov 2024 11:34:02 +0000</pubDate><link>https://news.ycombinator.com/item?id=42212962</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42212962</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42212962</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Traits are a local maximum"]]></title><description><![CDATA[
<p>This post is written by a fan of implicits, so it frames it as "better" than traits, though at the end it admits it is in fact a complex trade off, which is the truth. In my opinion, the trade off favors traits, but others may feel differently.<p>The core difference between traits (also called type classes) and ML modules is that with traits the instance/implementation has no name, whereas for ML modules they do. The analogy here is between Rust/Haskell's traits/typeclasses and ML's signatures and between Rust/Haskell's impls/instances and ML's structures. In Rust/Haskell, implementations are looked up by a tuple of types and a trait to determine the implementation. The advantage of this is that you don't need to name the impl and then invoke that name every time you use it; since we usually don't think of "Hash for i32" as something which has a meaningful name beyond the relationship between Hash and i32, this is quite nice.<p>But coherence requires that instances resolve consistently: if I hash an integer in one code location to insert into a map and then hash it again in a different location to do a lookup on the same map, I need to hash integers the same way each time. If you care about coherence, and the correctness property it implies, you can't allow overlapping impls if impls aren't named, because otherwise you aren't guaranteed a consistent result every time you look up the impl.<p>This introduces another problem: you can't see all the impls in the universe at once. Two libraries could add impls for types/traits in their upstream dependencies, and the incoherence won't be discovered until they are compiled together later on. This problem, called "orphan impls," causes its own controversy: do you just let downstream users discover the error eventually, when they try to combine the two libraries, or do you prohibit all orphan impls early on? Rust and Haskell have chosen different horns of this dilemma, and the grass is always greener.<p>Of course with implicits, this author intends a different solution to the problem of resolving instances without naming them: just allow incoherence (which they re-brand as "local coherence"). Instead, incoherence impls are allowed and are selected in a manner based on proximity to code location.<p>As the post eventually admits, this does nothing to solve the correctness problem that coherence is meant to solve, because code with different nearest impls can be compiled together, and in Rust such a correctness problem could become a memory safety problem, and how you figure out if the impl you've found for this type is actually the nearest impl to your code is left as an exercise to your reader. But sure, since you've rebranded incoherence to "local coherence" you can do some juxtaposed wordplay to call coherence a "local maxima" because achieving it has the downside that you can't have arbitrary orphan impls.</p>
]]></description><pubDate>Fri, 22 Nov 2024 10:58:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=42212789</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=42212789</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42212789</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Async Rust is not safe with io_uring"]]></title><description><![CDATA[
<p>[flagged]</p>
]]></description><pubDate>Wed, 30 Oct 2024 19:09:40 +0000</pubDate><link>https://news.ycombinator.com/item?id=41999004</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=41999004</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41999004</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Async Rust is not safe with io_uring"]]></title><description><![CDATA[
<p>[flagged]</p>
]]></description><pubDate>Wed, 30 Oct 2024 19:05:33 +0000</pubDate><link>https://news.ycombinator.com/item?id=41998965</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=41998965</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41998965</guid></item><item><title><![CDATA[New comment by withoutboats3 in "Async Rust is not safe with io_uring"]]></title><description><![CDATA[
<p>I freely admit I’m frustrated by the discourse around async Rust! I’m also very frustrated because I feel I was iced out of the project for petty reasons to do with whom I’m friends with and the people who were supposed to take over my work have done a very poor job, hence the failure to ship much of value to users. What we shipped in 2019 was an MVP that was intended to be followed by several improvements in quick succession, which the Rust project is only now moving toward delivering. I’ve written about this extensively.<p>My opinion is that async Rust is an incredible achievement, primarily not mine (among the people who deserve more credit than me are Alex Crichton, Carl Lerche, and Aaron Turon). My only really significant contributions were making it safe to use references in an async function and documenting how to interface with completion based APIs like io-uring correctly. So it is very frustrating to see the discourse focused on inaccurate statements about async Rust which I believe is the best system for async IO in any language and which just needs to be finished.</p>
]]></description><pubDate>Wed, 30 Oct 2024 18:57:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=41998876</link><dc:creator>withoutboats3</dc:creator><comments>https://news.ycombinator.com/item?id=41998876</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41998876</guid></item></channel></rss>