<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: stuhood</title><link>https://news.ycombinator.com/user?id=stuhood</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Mon, 15 Jun 2026 12:55:31 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=stuhood" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by stuhood in "Teaching Postgres to Facet Like Elasticsearch"]]></title><description><![CDATA[
<p>Yes, thank you for your hard work! We rebased recently, and we'll likely talk about those improvements as part of our `0.21.x` release.</p>
]]></description><pubDate>Mon, 15 Dec 2025 15:34:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=46275807</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=46275807</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46275807</guid></item><item><title><![CDATA[New comment by stuhood in "Index 1.6B Keys with Automata and Rust (2015)"]]></title><description><![CDATA[
<p>An interesting exercise would be to compare this with the (confusingly similarly named) `fsst` string compression strategy: <a href="https://github.com/cwida/fsst" rel="nofollow">https://github.com/cwida/fsst</a></p>
]]></description><pubDate>Thu, 14 Aug 2025 02:23:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=44896104</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=44896104</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44896104</guid></item><item><title><![CDATA[New comment by stuhood in "We made Postgres writes faster, but it broke replication"]]></title><description><![CDATA[
<p>Thanks for the questions!<p><pre><code>    After reading I don’t get how locks held in memory affect WAL shipping.
    WAL reader reads it in a single thread, updates in-memory data structures
    periodically dumping them on disk. Perhaps you want to read one big
    instruction from WAL and apply it to many buffers using multiple threads?
</code></pre>
We currently use an un-modified/generic WAL entry, and don't implement our own replay. That means we don't control the order of locks acquired/released during replay: and the default is to acquire exactly one lock to update a buffer.<p>But as far as I know, even with a custom WAL entry implementation, the maximum in one entry would still be ~8k, which might not be sufficient for a multi-block atomic operation. So the data structure needs to support block-at-a-time atomic updates.<p><pre><code>    I guess your implementation generates a lot of dead tuples during
    compaction. You clearly fighting PG here. Could a custom storage
    engine be a better option?
</code></pre>
`pg_search`'s LSM tree is effectively a custom storage engine, but it is an index (Index Access Method and Custom Scan) rather than a table. See more on it here: <a href="https://www.paradedb.com/blog/block_storage_part_one">https://www.paradedb.com/blog/block_storage_part_one</a><p>LSM compaction does not generate any dead tuples on its own, as what is dead is controlled by what is "dead" in the heap/table due to deletes/updates. Instead, the LSM is cycling blocks into and out of a custom free space map (that we implemented to reduce WAL traffic).</p>
]]></description><pubDate>Tue, 22 Jul 2025 03:51:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=44643070</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=44643070</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44643070</guid></item><item><title><![CDATA[New comment by stuhood in "PostgreSQL Full-Text Search: Fast When Done Right (Debunking the Slow Myth)"]]></title><description><![CDATA[
<p>Thanks for reporting this! I'm having trouble finding the link you are referring to though. Would you mind sharing a link to the file/page containing the dead link?</p>
]]></description><pubDate>Wed, 09 Apr 2025 19:49:02 +0000</pubDate><link>https://news.ycombinator.com/item?id=43636937</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=43636937</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43636937</guid></item><item><title><![CDATA[New comment by stuhood in "Vine: A programming language based on Interaction Nets"]]></title><description><![CDATA[
<p>I think that `inverting` also subsumes async functions/values, which is pretty neat!<p>In the case where asynchrony was actually necessary, it seems like a great alternative to function coloring.<p>But whether you should actually use it for something like their `sub_min` example is highly dependent on how good the performance of their implementation is. Creating a graph of references rather than making two passes over an array of integers is not clearly faster ... or clearer, for that matter.</p>
]]></description><pubDate>Sun, 23 Feb 2025 15:51:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=43150114</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=43150114</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43150114</guid></item><item><title><![CDATA[New comment by stuhood in "Build a Database in Four Months with Rust and 647 Open-Source Dependencies"]]></title><description><![CDATA[
<p>They support lockfiles and tools like `audit`, yes. But they do not support having multiple versions of a dependency.<p>Tools based on loading libraries from a *PATH (Go, Python, JVM) usually do so by grabbing the first one that they encounter that contains the appropriate symbols. That is incompatible with having multiple versions of a package.<p>On the other hand, Rust and node.js support this -- each in their own way. In Rust, artifact names are transparently suffixed with a hash to prevent collisions. And in node.js, almost all symbol lookups are accomplished with relative filesystem paths.</p>
]]></description><pubDate>Wed, 15 Jan 2025 23:29:16 +0000</pubDate><link>https://news.ycombinator.com/item?id=42718723</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42718723</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42718723</guid></item><item><title><![CDATA[New comment by stuhood in "Build a Database in Four Months with Rust and 647 Open-Source Dependencies"]]></title><description><![CDATA[
<p>Yes. AFAIK, it evolved over time across 3+ package managers (`npm`, `yarn`, `pnpm`, etc), but the current state of that ecosystem is similar (including the behavior of dependabot).</p>
]]></description><pubDate>Wed, 15 Jan 2025 21:41:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=42717474</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42717474</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42717474</guid></item><item><title><![CDATA[New comment by stuhood in "Build a Database in Four Months with Rust and 647 Open-Source Dependencies"]]></title><description><![CDATA[
<p>When it comes to understanding the risks involved with having this many dependencies, one thing that folks might not understand is that Rust's support for dependency resolution and lock files is fantastic.<p>Tools like `cargo audit` can tell you statically based on the lockfile which dependencies have security vulnerabilities reported against them (but you have to run it!). And Github's <a href="https://github.com/dependabot/">https://github.com/dependabot/</a> will do that same thing automatically, just based on the existence of the lockfile in your repo (and will also open PRs to bump deps for you).<p>And as mentioned elsewhere: Cargo's dependency resolver supports providing multiple versions of a dep in different dependency subgraphs, which all but eliminates the "dependency hell" that folks expect from ecosystems like Python or the JVM. Two copies of a dep at different versions? Totally fine.</p>
]]></description><pubDate>Wed, 15 Jan 2025 20:45:33 +0000</pubDate><link>https://news.ycombinator.com/item?id=42716686</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42716686</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42716686</guid></item><item><title><![CDATA[New comment by stuhood in "Some programming language ideas"]]></title><description><![CDATA[
<p>Every method in Reboot has a type: reader, writer, transaction, or workflow. Our retry semantics are such that any method can always be retried from the top, but for different reasons:<p>In readers, no state changes are possible. And in writers and transactions, retry/abort is always safe because no state changes occur until the method completes successfully.<p>In workflows, retry is always safe, and is in fact <i>required</i> due to the primitives we use to implement durable execution (we will publish more docs on this soon!). The workflow retries durably until it eventually completes, one way or another.<p>That means that a workflow is always the right spot to execute an external side effect: if a reader/writer/transaction want to execute a side effect, they do so by spawning a task, which is only <i>actually</i> spawned if the method completes successfully. And we do "effect validation" (effectively: running your method twice!) to make it very hard to write a side effect in the wrong place.<p><a href="https://docs.reboot.dev/develop/side_effects" rel="nofollow">https://docs.reboot.dev/develop/side_effects</a> has some more details on our approach to side effects, but feel free to follow up in our discord too: <a href="https://discord.com/invite/cRbdcS94Nr" rel="nofollow">https://discord.com/invite/cRbdcS94Nr</a><p>----<p>> I have also read that exceptions can complicate control flow, disallowing some optimizations - but if they are transactional, then we can just add their reverse to the supposedly already slow error path, and enjoy our performance boost!<p>Somewhat...! When you write a transaction method in Reboot, code that fails with an exception <i>cannot</i> have had a side effect on the outside world, and all state changes will vanish if the transaction aborts. So there is never any need to clean something up, unless you are using exceptions to implement control flow.</p>
]]></description><pubDate>Fri, 10 Jan 2025 20:54:54 +0000</pubDate><link>https://news.ycombinator.com/item?id=42660085</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42660085</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42660085</guid></item><item><title><![CDATA[New comment by stuhood in "Some programming language ideas"]]></title><description><![CDATA[
<p>They are related, for sure. But one of the biggest differences is that operations affecting multiple Reboot states are transactional, unlike Azure's "entity functions".<p>Because multiple Azure entity functions are not updated transactionally, you are essentially always implementing the saga pattern: you have to worry about cleaning up after yourself in case of failure.<p>In Reboot, transactional function calls automatically roll back all state changes if they fail, without any extra boilerplate code. Our hypothesis is that that enables a large portion of an application to skip worrying about failure entirely.<p>Code that has side-effects impacting the outside world can be isolated using our workflow mechanism (effectively durable execution), which can themselves be encapsulated inside of libraries and composed. But we don't think that that is the default mode that developers should be operating in.</p>
]]></description><pubDate>Wed, 08 Jan 2025 22:38:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=42639262</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42639262</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42639262</guid></item><item><title><![CDATA[New comment by stuhood in "Some programming language ideas"]]></title><description><![CDATA[
<p>We have built something that hits on points 1, 3, 5, and 7 at <a href="https://reboot.dev/" rel="nofollow">https://reboot.dev/</a> ... but in a multi-language framework (supporting Python and TypeScript to start).<p>The end result is something that looks a lot like distributed, persistent, transactional memory. Rather than explicit interactions with a database, local variable writes to your state are transactionally persisted if a method call succeeds, even across process/machine boundaries. And that benefits point 7, because transactional method calls compose across team/application boundaries.<p>[1] Loosen Up The Functions
[3] Production-Level Releases
[5] Value Database
[7] A Language To Encourage Modular Monoliths</p>
]]></description><pubDate>Wed, 08 Jan 2025 20:57:28 +0000</pubDate><link>https://news.ycombinator.com/item?id=42638354</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42638354</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42638354</guid></item><item><title><![CDATA[New comment by stuhood in "Pex: A tool for generating .pex (Python EXecutable) files, lock files and venvs"]]></title><description><![CDATA[
<p>Not anymore: PEX now supports including an interpreter in the package: <a href="https://docs.pex-tool.org/scie.html" rel="nofollow">https://docs.pex-tool.org/scie.html</a><p>And unfortunately, PyOxidizer went into maintenance mode: <a href="https://gregoryszorc.com/blog/2024/03/17/my-shifting-open-source-priorities/" rel="nofollow">https://gregoryszorc.com/blog/2024/03/17/my-shifting-open-so...</a></p>
]]></description><pubDate>Sat, 16 Nov 2024 07:21:15 +0000</pubDate><link>https://news.ycombinator.com/item?id=42155021</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=42155021</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42155021</guid></item><item><title><![CDATA[New comment by stuhood in "Databases are the endgame for data-oriented design"]]></title><description><![CDATA[
<p>The fundamental difference between an ECS and a struct/object layout is that an ECS is column-oriented (aka columnar), while a struct/object layout is row-oriented.<p>Everything else about how you might query these layouts is more superficial... you can provide the same API with either layout, the same way you can in relational database systems (both layouts can be queried with SQL, but with different performance characteristics.)</p>
]]></description><pubDate>Thu, 07 Dec 2023 00:49:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=38551515</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=38551515</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=38551515</guid></item><item><title><![CDATA[Pants “Environments”: simpler multi-platform workflows]]></title><description><![CDATA[
<p>Article URL: <a href="https://blog.pantsbuild.org/environments-simpler-multi-platform-workflows/">https://blog.pantsbuild.org/environments-simpler-multi-platform-workflows/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=35346048">https://news.ycombinator.com/item?id=35346048</a></p>
<p>Points: 2</p>
<p># Comments: 0</p>
]]></description><pubDate>Tue, 28 Mar 2023 18:54:48 +0000</pubDate><link>https://blog.pantsbuild.org/environments-simpler-multi-platform-workflows/</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=35346048</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=35346048</guid></item><item><title><![CDATA[New comment by stuhood in "Converting a polyglot project build to Bazel"]]></title><description><![CDATA[
<p>> I’m more familiar with Bazel. Though I don’t “love it”, I spend plenty of time with it every day. Gazelle like rules for java would be nice.<p>We'd love your feedback on Pants' support for Java. Pants' "dependency inference" eliminates most BUILD file maintenance: <a href="https://blog.pantsbuild.org/automatically-unlocking-concurrent-builds-and-fine-grained-caching-on-the-jvm-with-dependency-inference/" rel="nofollow">https://blog.pantsbuild.org/automatically-unlocking-concurre...</a></p>
]]></description><pubDate>Tue, 25 Oct 2022 03:50:06 +0000</pubDate><link>https://news.ycombinator.com/item?id=33325970</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=33325970</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=33325970</guid></item><item><title><![CDATA[Pants 2.13: Adds Kotlin support, simplifies CLI arguments, improves JVM support]]></title><description><![CDATA[
<p>Article URL: <a href="https://blog.pantsbuild.org/introducing-pants-2-13/">https://blog.pantsbuild.org/introducing-pants-2-13/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=32782107">https://news.ycombinator.com/item?id=32782107</a></p>
<p>Points: 4</p>
<p># Comments: 0</p>
]]></description><pubDate>Fri, 09 Sep 2022 17:16:23 +0000</pubDate><link>https://blog.pantsbuild.org/introducing-pants-2-13/</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=32782107</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32782107</guid></item><item><title><![CDATA[Multiple Lockfiles in Python Repos: A Hybrid Approach with Pants]]></title><description><![CDATA[
<p>Article URL: <a href="https://blog.pantsbuild.org/multiple-lockfiles-python/">https://blog.pantsbuild.org/multiple-lockfiles-python/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=31741911">https://news.ycombinator.com/item?id=31741911</a></p>
<p>Points: 2</p>
<p># Comments: 0</p>
]]></description><pubDate>Tue, 14 Jun 2022 16:34:06 +0000</pubDate><link>https://blog.pantsbuild.org/multiple-lockfiles-python/</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=31741911</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=31741911</guid></item><item><title><![CDATA[Building self-contained Python applications with the new PyOxidizer Pants Plugin]]></title><description><![CDATA[
<p>Article URL: <a href="https://blog.pantsbuild.org/packaging-python-with-the-pyoxidizer-pants-plugin/">https://blog.pantsbuild.org/packaging-python-with-the-pyoxidizer-pants-plugin/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=30431233">https://news.ycombinator.com/item?id=30431233</a></p>
<p>Points: 7</p>
<p># Comments: 0</p>
]]></description><pubDate>Tue, 22 Feb 2022 18:09:14 +0000</pubDate><link>https://blog.pantsbuild.org/packaging-python-with-the-pyoxidizer-pants-plugin/</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=30431233</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30431233</guid></item><item><title><![CDATA[Pants 2.9: Alpha support for Java and Scala]]></title><description><![CDATA[
<p>Article URL: <a href="https://blog.pantsbuild.org/pants-2-9/">https://blog.pantsbuild.org/pants-2-9/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=29923469">https://news.ycombinator.com/item?id=29923469</a></p>
<p>Points: 2</p>
<p># Comments: 0</p>
]]></description><pubDate>Thu, 13 Jan 2022 17:16:41 +0000</pubDate><link>https://blog.pantsbuild.org/pants-2-9/</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=29923469</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=29923469</guid></item><item><title><![CDATA[New comment by stuhood in "Dependency inference: Fine-grained caching and concurrent builds for the JVM"]]></title><description><![CDATA[
<p>For those familiar with sbt's incremental Scala compiler library Zinc: we believe that this strategy allows for 90%* of the benefits of Zinc with regard to incremental builds, but with the added benefits of caching and parallelism.<p>(* The last 10% would come from adding early cutoff when public member signatures haven't changed.)</p>
]]></description><pubDate>Mon, 29 Nov 2021 22:10:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=29385935</link><dc:creator>stuhood</dc:creator><comments>https://news.ycombinator.com/item?id=29385935</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=29385935</guid></item></channel></rss>