<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: Wilfred</title><link>https://news.ycombinator.com/user?id=Wilfred</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Sat, 04 Apr 2026 09:25:43 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=Wilfred" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by Wilfred in "Beagle, a source code management system that stores AST trees"]]></title><description><![CDATA[
<p>This is actually possible with glasses-mode in Emacs: <a href="https://codelearn.me/2025/02/24/emacs-glasses-mode.html" rel="nofollow">https://codelearn.me/2025/02/24/emacs-glasses-mode.html</a><p>I think it sees very little usage though.</p>
]]></description><pubDate>Sun, 08 Mar 2026 19:44:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=47300548</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=47300548</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=47300548</guid></item><item><title><![CDATA[New comment by Wilfred in "TmuxAI: AI-Powered, Non-Intrusive Terminal Assistant"]]></title><description><![CDATA[
<p>If I've understood this interesting workflow correctly, there's two major components.<p>streamdown: a markdown renderer for the terminal, intended for consuming LLM output. It has affordances to make it easier to run the code snippets: no indentation, easy insertion in the clipboard, fzf access to previous items.<p>llmehelp: tools to slurp the current tmux text content (i.e. recent command output) as well as slurp the current zsh prompt (i.e. the command you're currently writing).<p>I think the idea is then you bounce between the LLM helping you and just having a normal shell/editor tmux session. The LLM has relevant context to your work without having to explicitly give it anything.</p>
]]></description><pubDate>Mon, 28 Apr 2025 04:21:01 +0000</pubDate><link>https://news.ycombinator.com/item?id=43817517</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=43817517</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43817517</guid></item><item><title><![CDATA[New comment by Wilfred in "Two Years of Rust"]]></title><description><![CDATA[
<p>In `use foo::bar; use bar::foo;`, am I importing an external crate called foo that has a submodule bar::foo, or vice versa?<p>This bit me when trying to write a static analysis tool for Rust that finds missing imports: you essentially need to loop over imports repeatedly until you reach a fixpoint. Maybe it bites users rarely in practice.</p>
]]></description><pubDate>Mon, 21 Apr 2025 22:09:14 +0000</pubDate><link>https://news.ycombinator.com/item?id=43757049</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=43757049</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43757049</guid></item><item><title><![CDATA[New comment by Wilfred in "Two Years of Rust"]]></title><description><![CDATA[
<p>> Rust's users find the module system even more difficult than the borrow checker. I've tried to figure out why, and figure out how to explain it better, for years now.<p>The module system in Rust is conceptually huge, and I feel it needs a 'Rust modules: the good parts' resource to guide people.<p>(1) There are five different ways to use `pub`. That's pretty overwhelming, and in practice I almost never see `pub(in foo)` used.<p>(2) It's possible to have nested modules in a single file, or across multiple files. I almost never see modules with braces, except `mod tests`.<p>(3) It's possible to have either foo.rs or foo/mod.rs. It's also possible to have both foo.rs and foo/bar.rs, which feels inconsistent.<p>(4) `use` order doesn't matter, which can make imports hard to reason about. Here's a silly example:<p>use foo::bar;
use bar::foo;<p>(Huge fan of your writing, by the way!)</p>
]]></description><pubDate>Wed, 16 Apr 2025 05:19:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=43701756</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=43701756</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43701756</guid></item><item><title><![CDATA[New comment by Wilfred in "Pijul: Version-Control Post-Git [video]"]]></title><description><![CDATA[
<p>> How well do existing VCSs integrate with it?<p>Git supports external diffing tools really well with GIT_EXTERNAL_DIFF, which you can use with difftastic[1]. Other VCSs are less flexible. For example, I haven't found a nice way of getting a pager when using difftastic with mercurial.<p>> Did you feel restricted at any point by writing a diffing tool, instead of basing a new VCS around this concept?<p>Oh, that's an interesting question! Difftastic has been a really big project[2] despite its limited scope and I'm less interested in VCS implementation.<p>I think text works well as the backing store for a VCS. There are a few systems that have structured backends (e.g. monticello for smalltalk), but they're more constrained. You can only store structured content (e.g. monticello requires smalltalk code) and it must be well-formed (your VCS must understand any future syntax you use).<p>Unison[3] is a really interesting project in this space, it stores code by hash in a sqlite backend. This makes some code changes trivial, such as renames.<p>From the perspective of a text diff, an AST diff is lossy. If you add an extra blank line between two unchanged functions, difftastic ignores it. That's great for understanding changes, but not for storage.<p>[1]: <a href="https://difftastic.wilfred.me.uk/git.html" rel="nofollow noreferrer">https://difftastic.wilfred.me.uk/git.html</a><p>[2]: <a href="https://www.wilfred.me.uk/blog/2022/09/06/difftastic-the-fantastic-diff/" rel="nofollow noreferrer">https://www.wilfred.me.uk/blog/2022/09/06/difftastic-the-fan...</a><p>[3] <a href="https://www.unison-lang.org/" rel="nofollow noreferrer">https://www.unison-lang.org/</a></p>
]]></description><pubDate>Sat, 12 Aug 2023 18:06:01 +0000</pubDate><link>https://news.ycombinator.com/item?id=37102694</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=37102694</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37102694</guid></item><item><title><![CDATA[New comment by Wilfred in "Pijul: Version-Control Post-Git [video]"]]></title><description><![CDATA[
<p>Shameless plug: I've written difftastic[1], a tool that builds ASTs and then does a structural diff of them. You can use it with git too.<p>It's an incredibly hard problem though, both from a computational complexity point of view, and trying to build a comprehensible UI once you've done the structural AST diff.<p>[1]: <a href="https://github.com/wilfred/difftastic">https://github.com/wilfred/difftastic</a></p>
]]></description><pubDate>Sat, 12 Aug 2023 04:56:38 +0000</pubDate><link>https://news.ycombinator.com/item?id=37097171</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=37097171</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=37097171</guid></item><item><title><![CDATA[New comment by Wilfred in "The quest for a simple smartwatch"]]></title><description><![CDATA[
<p>Another enthusiastic Bangle.js user here: I had the original and used it, programmed it until the strap (integrated into the body) broke.<p>Apparently you can actually connect it to phone notifications using gadgetbridge[0] but I didn't have much success when I tried it. The BLE was a little flaky at the best of times (pairing to a PC for programming failed more often than I'd like).<p>[0] <a href="https://www.espruino.com/Gadgetbridge" rel="nofollow noreferrer">https://www.espruino.com/Gadgetbridge</a></p>
]]></description><pubDate>Thu, 29 Jun 2023 05:31:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=36516688</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=36516688</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=36516688</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>tree-sitter has first class support for parsing errors as ERROR nodes in the output tree. I treat these as just another atom in the s-expression.<p>In practise I haven't noticed any issues yet. I suspect that difftastic doesn't see many syntax errors because users have fixed most of them by the time they run the diff. When you look at diffs of committed code you hopefully have no parse errors at all.<p>The tree-sitter parsers could still reject valid code I suppose. I worry slightly more about the parsers getting precedence/associativity wrong, but it would be hard to construct an example that produce identical parse trees due to incorrect precedence.</p>
]]></description><pubDate>Thu, 08 Sep 2022 16:36:43 +0000</pubDate><link>https://news.ycombinator.com/item?id=32768030</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32768030</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32768030</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>Thanks for the feedback. This is really hard to explain.<p>Autochrome has a brilliant worked example <a href="https://fazzone.github.io/autochrome.html" rel="nofollow">https://fazzone.github.io/autochrome.html</a> and it still took me several readings before it clicked.<p>Every graph vertex represents a pair of pointers (or positions) to AST nodes. So in the example, the start program is `A` and the end program is `X A`. The positions point to AST nodes in these programs.<p>I try to use 'vertex' consistently for graph vertices, to avoid confusion with AST/s-expression nodes. If you have any suggestions for better terminology I'd be very interested too :)</p>
]]></description><pubDate>Thu, 08 Sep 2022 06:53:03 +0000</pubDate><link>https://news.ycombinator.com/item?id=32762117</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32762117</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32762117</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>I've looked at several tree diffing papers, including Chawathe et al, but it's not always easy to assess whether their approach would suit difftastic.<p>I know that sdiff by Arun Isaac is based on applying that paper to Scheme: <a href="https://archive.fosdem.org/2021/schedule/event/sexpressiondiff/" rel="nofollow">https://archive.fosdem.org/2021/schedule/event/sexpressiondi...</a> , although he also reports performance challenges.<p>Most tree diffing papers that I've seen focus on either (1) providing a minimal diff and accepting the performance cost or (2) providing a relatively minimal diff and focusing on the performance.<p>I've generally found that you need a minimal diff to get a good result, so papers in (2) are less applicable. I've also found several cases where there are several possible minimal diffs, but there's a clear 'correct' answer from the user's perspective.<p>Difftastic doesn't handle moves: the edit set is add, remove, or replace similar comment. If you reorder functions, it will take the largest unchanged subset. Moves are hard to model in a diffing algorithm, but they're also very hard to display coherently in the UI.<p>I know a few code forge websites (e.g. Phabricator) show moves in a fairly comprehensible way, although they're all based on line-based diffs.</p>
]]></description><pubDate>Thu, 08 Sep 2022 06:46:29 +0000</pubDate><link>https://news.ycombinator.com/item?id=32762070</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32762070</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32762070</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>Side-by-side diff displays work really great in a browser. You usually have more screen real estate, and you can offer a responsive UI.</p>
]]></description><pubDate>Wed, 07 Sep 2022 16:52:05 +0000</pubDate><link>https://news.ycombinator.com/item?id=32753082</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32753082</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32753082</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>Thanks for the feedback! I'll look to clarify the wording here. The failed example was a real output that difftastic gave in early versions.<p>I agree that the classic red/green colour scheme of diffs isn't great for colourblind users. I've asked a few colourblind developers and they were happy with terminal ANSI colours (which is what difftastic uses), because they can configure each colour individually.</p>
]]></description><pubDate>Wed, 07 Sep 2022 16:50:33 +0000</pubDate><link>https://news.ycombinator.com/item?id=32753060</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32753060</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32753060</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>You can use difftastic as your default git diff tool, but you can also use it as an opt-in diffing tool. I recommend using it as an opt-in, but defining a git alias so you can do 'git difft'.<p><a href="https://difftastic.wilfred.me.uk/git.html" rel="nofollow">https://difftastic.wilfred.me.uk/git.html</a> has docs.</p>
]]></description><pubDate>Wed, 07 Sep 2022 16:45:30 +0000</pubDate><link>https://news.ycombinator.com/item?id=32752976</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32752976</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32752976</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic, the fantastic diff"]]></title><description><![CDATA[
<p>Yep, that's correct. Difftastic is only a syntactic analysis, although it often makes the semantic intent clearer.</p>
]]></description><pubDate>Wed, 07 Sep 2022 16:43:17 +0000</pubDate><link>https://news.ycombinator.com/item?id=32752951</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=32752951</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=32752951</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic: A diff that understands syntax"]]></title><description><![CDATA[
<p>tree-sitter inserts error nodes and gives you an AST for all inputs. It seems to work well in practice.</p>
]]></description><pubDate>Wed, 30 Mar 2022 21:28:47 +0000</pubDate><link>https://news.ycombinator.com/item?id=30861010</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=30861010</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30861010</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic: A diff that understands syntax"]]></title><description><![CDATA[
<p>I imagine it's a misunderstanding with the rustc-hash dependency used in difftastic for faster hashing.</p>
]]></description><pubDate>Wed, 30 Mar 2022 21:26:26 +0000</pubDate><link>https://news.ycombinator.com/item?id=30860984</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=30860984</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30860984</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic: A diff that understands syntax"]]></title><description><![CDATA[
<p>I'd like to add it, but I haven't found any good tree-sitter parsers for Scheme.</p>
]]></description><pubDate>Tue, 29 Mar 2022 20:15:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=30847800</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=30847800</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30847800</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic: A diff that understands syntax"]]></title><description><![CDATA[
<p>This looks like you're using a version of Rust older than the minimum required (1.56).</p>
]]></description><pubDate>Tue, 29 Mar 2022 20:14:40 +0000</pubDate><link>https://news.ycombinator.com/item?id=30847794</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=30847794</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30847794</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic: A diff that understands syntax"]]></title><description><![CDATA[
<p><a href="https://github.com/andreyvit/json-diff" rel="nofollow">https://github.com/andreyvit/json-diff</a> works really well for JSON diffing in my experience.<p>It's more simplistic than difftastic though: it considers `1` and `[1]` to have nothing in common.</p>
]]></description><pubDate>Tue, 29 Mar 2022 20:12:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=30847775</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=30847775</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30847775</guid></item><item><title><![CDATA[New comment by Wilfred in "Difftastic: A diff that understands syntax"]]></title><description><![CDATA[
<p>It's really hard! :)<p>(1) Parsing an arbitrary language is hard. Without tree-sitter, difftastic would probably be a lisp-only tool. You also want a parser that preserves comments.<p>(2) Inputs may not be syntactically well formed.<p>(3) Efficiently comparing trees is extremely difficult (difftastic is O(N^2) in time and memory).<p>(4) Displaying tree diffs is equally difficult. Alignment is particularly challenging when your 'unchanged before' and 'unchanged after' are syntactically the same, but textually different.</p>
]]></description><pubDate>Tue, 29 Mar 2022 20:09:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=30847725</link><dc:creator>Wilfred</dc:creator><comments>https://news.ycombinator.com/item?id=30847725</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=30847725</guid></item></channel></rss>