<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: chriswarbo</title><link>https://news.ycombinator.com/user?id=chriswarbo</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Fri, 15 May 2026 21:25:36 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=chriswarbo" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by chriswarbo in "Fixing a 20-year-old bug in Enlightenment E16"]]></title><description><![CDATA[
<p>Whenever I try something else, I always seem to keep going back to E16. Back in the day, it worked well in Gnome 2.x; these days I tend to use it in XFCE, but it feels a bit less integrated.</p>
]]></description><pubDate>Wed, 15 Apr 2026 09:29:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=47776707</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47776707</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47776707</guid></item><item><title><![CDATA[New comment by chriswarbo in "jj – the CLI for Jujutsu"]]></title><description><![CDATA[
<p>Exactly the same thing happened when git showed up (alongside the same things for bzr, darcs, hg, etc. too!)</p>
]]></description><pubDate>Tue, 14 Apr 2026 16:28:47 +0000</pubDate><link>https://news.ycombinator.com/item?id=47767772</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47767772</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47767772</guid></item><item><title><![CDATA[New comment by chriswarbo in "jj – the CLI for Jujutsu"]]></title><description><![CDATA[
<p><a href="https://git-scm.com/docs/git-worktree" rel="nofollow">https://git-scm.com/docs/git-worktree</a></p>
]]></description><pubDate>Tue, 14 Apr 2026 16:18:35 +0000</pubDate><link>https://news.ycombinator.com/item?id=47767626</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47767626</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47767626</guid></item><item><title><![CDATA[New comment by chriswarbo in "jj – the CLI for Jujutsu"]]></title><description><![CDATA[
<p>I suppose it depends what you mean by "horribly break things".<p>The only thing I've noticed is that `jj` will leave the git repo with either a detached HEAD, or with a funny `@` ref checked out.<p>I don't think that would trouble someone who's experienced with git and knows its "DAG of commits" model.<p>For someone who's less experienced, or only uses git for a set of branches with mostly linear history (like a sort of "fancy undo"), I could imagine getting a shock when trying to `git commit` and not seeing them on any of the branches!</p>
]]></description><pubDate>Tue, 14 Apr 2026 16:17:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=47767613</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47767613</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47767613</guid></item><item><title><![CDATA[New comment by chriswarbo in "jj – the CLI for Jujutsu"]]></title><description><![CDATA[
<p>> It wants me to start with the new and describe command<p>jj doesn't "want" anything.<p>I always <i>end</i> a piece of work with `new`: it puts an empty, description-less commit as the checked-out HEAD, and is my way of saying "I'm finished with those changes (for now); any subsequent changes to this directory should go in this (currently empty) commit"<p>The last thing I do to a commit, once all of its contents have settled into something reasonable, is describe it.<p>In fact, I mostly use `commit` (pressing `C` in majutsu), which combines those two things: it gives the current commit a description, and creates a new empty commit on top.</p>
]]></description><pubDate>Tue, 14 Apr 2026 15:59:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=47767389</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47767389</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47767389</guid></item><item><title><![CDATA[New comment by chriswarbo in "jj – the CLI for Jujutsu"]]></title><description><![CDATA[
<p>> I often find that in the process of making one change, I have also made several other changes, and only recognize that they are distinct after following the ideas to their natural conclusion.<p>I do that all the time. With git, everything starts "unstaged", so I'd use magit to selectively stage some parts and turn those into a sequence of commits, one on top of another.<p>With jj I'd do it "backwards": everything starts off committed (with no commit message), so I'd open the diff (`D` in majutsu), selecting some parts and "split" (`S` in majutsu) to put those into a new commit <i>underneath</i> the remaining changes. Once the different changes are split into separate commits, I'd give each a relevant commit message.</p>
]]></description><pubDate>Tue, 14 Apr 2026 15:51:25 +0000</pubDate><link>https://news.ycombinator.com/item?id=47767267</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47767267</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47767267</guid></item><item><title><![CDATA[New comment by chriswarbo in "More on Version Control"]]></title><description><![CDATA[
<p>Tooling can support both (e.g. don't assume all hashes have the length of a SHA1, etc.); but they can't be used together <i>in one repo</i>.</p>
]]></description><pubDate>Mon, 30 Mar 2026 15:26:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=47575530</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47575530</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47575530</guid></item><item><title><![CDATA[New comment by chriswarbo in "Two studies in compiler optimisations"]]></title><description><![CDATA[
<p>Haskell has a package to make testing this sort of thing easier <a href="https://hackage.haskell.org/package/inspection-testing" rel="nofollow">https://hackage.haskell.org/package/inspection-testing</a></p>
]]></description><pubDate>Thu, 26 Mar 2026 13:25:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=47530190</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47530190</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47530190</guid></item><item><title><![CDATA[New comment by chriswarbo in "Shell Tricks That Make Life Easier (and Save Your Sanity)"]]></title><description><![CDATA[
<p>Pipelines are usually built up step by step: we run some vague, general thing (e.g. a `find` command); the output looks sort of right, but needs to be narrowed down or processed further, so we press Up to get the previous command back, and add a pipe to the end. We run that, then add something else; and so on.<p>Now let's say the output looks wrong; e.g. we get nothing out. Weird, the previous command looked right, and it doesn't seem to be a problem with the filter we just put on the end. Maybe the filter we added part-way-through was discarding too much, so that the things we actually wanted weren't reaching the later stages; we didn't notice, because everything was being drowned-out by irrelevant stuff that that our latest filter has just gotten rid of.<p>Tricks like this `\#` let us turn off that earlier filter, without affecting anything else, so we can see if it was causing the problem as we suspect.<p>As for more general "why use CLI?", that's been debated for decades already; if you care to look it up :-)</p>
]]></description><pubDate>Thu, 26 Mar 2026 13:03:51 +0000</pubDate><link>https://news.ycombinator.com/item?id=47529942</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47529942</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47529942</guid></item><item><title><![CDATA[New comment by chriswarbo in "Shell Tricks That Make Life Easier (and Save Your Sanity)"]]></title><description><![CDATA[
<p>I'm confused; how is writing a shell command (using shortcuts like those in the article!) "wasting time", but describing what you want to an LLM, having it make a plan, reading the plan, editing it, and running it is somehow <i>not</i> a waste of time?<p>You also mention there being "little value", when your proposed approach costs literal money in form of API/token usage (when using hosted models).<p>> Now I've moved to coding in Haskell<p>You might like <a href="https://hackage.haskell.org/package/turtle" rel="nofollow">https://hackage.haskell.org/package/turtle</a> or <a href="http://nellardo.com/lang/haskell/hash/" rel="nofollow">http://nellardo.com/lang/haskell/hash/</a></p>
]]></description><pubDate>Thu, 26 Mar 2026 11:33:54 +0000</pubDate><link>https://news.ycombinator.com/item?id=47529209</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47529209</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47529209</guid></item><item><title><![CDATA[New comment by chriswarbo in "Shell Tricks That Make Life Easier (and Save Your Sanity)"]]></title><description><![CDATA[
<p>Theirs "turns off" one element of a pipeline; yours turns off everything after a certain point.<p>This will output the stdout of mycmd1:<p><pre><code>    mycmd1 #| mycmd2 | mycmd3
</code></pre>
This will output the stdout of mycmd3:<p><pre><code>    mycmd1 | \# mycmd2 | mycmd3</code></pre></p>
]]></description><pubDate>Thu, 26 Mar 2026 11:23:41 +0000</pubDate><link>https://news.ycombinator.com/item?id=47529154</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47529154</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47529154</guid></item><item><title><![CDATA[New comment by chriswarbo in "Obsolete Sounds"]]></title><description><![CDATA[
<p>I love that Amiga emulators (FS/E/Win)UAE have an option to emulate the floppy drive sound. Very nostalgic, but also useful as an indication that something's happening!</p>
]]></description><pubDate>Thu, 26 Mar 2026 10:41:27 +0000</pubDate><link>https://news.ycombinator.com/item?id=47528805</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47528805</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47528805</guid></item><item><title><![CDATA[New comment by chriswarbo in "Hypothesis, Antithesis, synthesis"]]></title><description><![CDATA[
<p>> thanks to Curry-Howard isomorphism, the full-fidelity mathematical model of a database or web browser are their binaries themselves.<p>Maybe I'm misunderstanding you, but Curry-Howard is a mapping between mathematical jargon and programming jargon, where e.g. "this is a proof of that proposition using foo logic" maps to "this program has that type in programming language foo".<p>I don't see how that makes "binaries" a "full-fidelity mathematical model": compilation is (according to Curry-Howard) translating a proof from one system of logic to another. For a binary, the resulting system of logic is machine code, which is an absolutely <i>terrible</i> logic: it has essentially one type (the machine word), which makes every proposition trivial; according to Curry-Howard, your database binary is proof of the proposition corresponding to its type; since the type of every binary is just "some machine words", the proposition that your database binary is a "full-fledged mathematical model" of is essentially just "there exists a machine word". Not very useful; we could optimise it down to "0", which is also a proof that there exists a machine word.<p>If we assume that you want to prove something non-trivial, then the first thing you would need to do is <i>abstract</i> away from the trivial logic of machine code semantics, by inferring some specific structures and patterns from that binary, then developing some useful semantics which captures those patterns and structures. Then you can start to develop non-trivial logic on those semantics, which will let you state worthwhile propositions. If we apply the Curry-Howard lens to <i>that</i> process, it corresponds to... <i>decompilation</i> into a higher-level language!<p>tl;dr Curry-Howard tells us that binaries are literally the worst possible representation we could hope for.</p>
]]></description><pubDate>Tue, 24 Mar 2026 20:30:18 +0000</pubDate><link>https://news.ycombinator.com/item?id=47508724</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47508724</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47508724</guid></item><item><title><![CDATA[New comment by chriswarbo in "Hypothesis, Antithesis, synthesis"]]></title><description><![CDATA[
<p>> But it's still a "blind" fuzzer and it would be nice to write one that gets feedback from code coverage somehow<p>There have been simplistic attempts at this, e.g. instead of performing 100 tests, just keep going as long as coverage increases.<p>The Choice Gradient Sampling algorithm from <a href="https://arxiv.org/pdf/2203.00652" rel="nofollow">https://arxiv.org/pdf/2203.00652</a> feels like a nice way to steer generators in a more nuanced way. That paper uses it to avoid discards when rejection-sampling; but I have a feeling it could be repurposed to "reward" based on new coverage instead/as-well.</p>
]]></description><pubDate>Tue, 24 Mar 2026 19:40:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=47507959</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47507959</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47507959</guid></item><item><title><![CDATA[New comment by chriswarbo in "Leanstral: Open-source agent for trustworthy coding and formal proof engineering"]]></title><description><![CDATA[
<p>> The moment you let the LLM write the tests without understanding them, you may as well just let it write the code directly.<p>I disagree. Having tests (even if the LLM wrote them itself!) gives the model <i>some</i> grounding, and exposes <i>some</i> of its inconsistencies. LLMs are not logically-omniscient; they can "change their minds" (next-token probabilities) when confronted with evidence (e.g. test failure messages). Chain-of-thought allows more computation to happen; but it doesn't give the model any extra <i>evidence</i> (i.e. Shannon information; outcomes that are surprising, given its prior probabilities).</p>
]]></description><pubDate>Tue, 17 Mar 2026 15:32:17 +0000</pubDate><link>https://news.ycombinator.com/item?id=47414114</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47414114</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47414114</guid></item><item><title><![CDATA[New comment by chriswarbo in "Leanstral: Open-source agent for trustworthy coding and formal proof engineering"]]></title><description><![CDATA[
<p>> The scientific approach starts with a theory that does it's best to explain some phenomenon<p>At the risk of stretching the analogy, the LLM's internal representation is that theory: gradient-descent has tried to "explain" its input corpus (+ RL fine-tuning), which will likely contain relevant source code, documentation, papers, etc. to our problem.<p>I'd also say that a piece of software is a theory too (quite literally, if we follow Curry-Howard). A piece of software generated by an LLM is a more-specific, more-explicit subset of its internal NN model.<p>Tests, and other real CLI interactions, allow the model to find out that it's wrong (~empiricism); compared to going round and round in chain-of-thought (~philosophy).<p>Of course, test failures don't tell us how to make it <i>actually pass</i>; the same way that unexpected experimental/observational results don't tell us what an appropriate explanation/theory should be (see: Dark matter, dark energy, etc.!)</p>
]]></description><pubDate>Tue, 17 Mar 2026 11:04:32 +0000</pubDate><link>https://news.ycombinator.com/item?id=47411034</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47411034</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47411034</guid></item><item><title><![CDATA[New comment by chriswarbo in "Leanstral: Open-source agent for trustworthy coding and formal proof engineering"]]></title><description><![CDATA[
<p>Tests (and type-checkers, linters, formal specs, etc.) ground the model in reality: they show it that it got something wrong (without needing a human in the loop). It's empiricism, "nullius in verba"; the scientific approach, which lead to remarkable advances in a few hundred years; that over a thousand years of ungrounded philosophy couldn't achieve.</p>
]]></description><pubDate>Tue, 17 Mar 2026 09:38:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=47410440</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47410440</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47410440</guid></item><item><title><![CDATA[New comment by chriswarbo in "Separating the Wayland compositor and window manager"]]></title><description><![CDATA[
<p>Yeah, it took me a while to discover that it was removed from KWin. (I eventually ended up reading the sources). It didn't help that KWin also does 3D effects, so all of my Web searches for "shading" were returning results for "shader" :-(</p>
]]></description><pubDate>Mon, 16 Mar 2026 13:02:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=47398452</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47398452</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47398452</guid></item><item><title><![CDATA[New comment by chriswarbo in "How I write software with LLMs"]]></title><description><![CDATA[
<p>I'm considering using subagents, as a way to manage context and delegate "simple" tasks to cheaper models (if you want to see tokens burn, watch Opus try fixing a misplaced ')' in a Lisp file!).<p>I see what you mean w.r.t. different hats; but is it useful to have different tools available? For example, a "planner" having Web access and read-only file access, versus a "developer" having write access to files but no Web access?</p>
]]></description><pubDate>Mon, 16 Mar 2026 11:35:52 +0000</pubDate><link>https://news.ycombinator.com/item?id=47397677</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47397677</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47397677</guid></item><item><title><![CDATA[New comment by chriswarbo in "How I write software with LLMs"]]></title><description><![CDATA[
<p>> investing energy in formulating a syntactically nice sentence<p>This seem to be completely subjective; I write syntactically/grammatically "nice" sentences to LLMs, because that's how I write. I would have to "invest energy" to force myself to write in that supposedly "simpler" style.</p>
]]></description><pubDate>Mon, 16 Mar 2026 11:30:25 +0000</pubDate><link>https://news.ycombinator.com/item?id=47397636</link><dc:creator>chriswarbo</dc:creator><comments>https://news.ycombinator.com/item?id=47397636</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47397636</guid></item></channel></rss>