Elegant Retry Loops: Avoiding Redundancy and Unexpected Sleeps

2025-08-27

The author explores writing an elegant retry loop that clearly bounds the number of retries, avoids spurious sleep after the last attempt, reports the original error if retrying fails, and avoids code duplication. Several approaches are compared, ultimately settling on a `try while` loop with an upper bound to guarantee termination, addressing boundary issues and potential runaway loops in previous solutions. While the final solution isn't perfect, it represents a significant improvement in brevity and robustness over previous attempts.

Read more
Development

Neat Zig Idiom: Partially Matching Enums

2025-08-09

Zig offers an elegant solution for handling partial matching in enums, avoiding redundant code and runtime panics. The article details a clever technique using `inline` and `comptime unreachable` to allow the compiler to check for unnecessary `else` branches at compile time, improving code robustness and readability. This is particularly useful when dealing with numerous enum variants, significantly simplifying code logic.

Read more
Development Compile-time checks

The Misunderstood Usefulness of `font-size-adjust`

2025-07-26

This article challenges the common misconception surrounding the CSS property `font-size-adjust`. The author argues that `font-size` specifies the size of the box around a glyph, not the glyph itself, leading to inconsistencies across different fonts. Instead of solely focusing on font fallback, `font-size-adjust` can be used to ensure more consistent sizing across various fonts on a page. The author recommends setting it to `ex-height 0.53` in a CSS reset for improved typographic consistency.

Read more
Development

Minimalist RSS Reader: Building a Personalized Blog Feed with Deno

2025-06-26

Tired of bloated RSS readers? The author took a different approach, building a custom RSS reader using Deno and a simple text file. It displays only the titles and links of the three latest posts, without local full-text storage or read/unread markers, and is automatically updated daily via GitHub Actions. The code is concise, easy to understand and extend, a minimalist's dream.

Read more
Development

Fast Rust Builds: Secrets to Sub-10 Minute CI

2025-06-20

It's a common complaint that Rust compiles slowly, but the author argues that most Rust projects compile far slower than they should. Using rust-analyzer (200k lines of code plus a million lines of dependencies) as an example, they achieve an 8-minute CI pipeline on GitHub Actions. The article details strategies for optimizing build times, including leveraging CI caching, splitting CI tasks, disabling incremental compilation and debug info, reducing dependencies, utilizing `cargo build -Z timings` for profiling, and carefully architecting code to avoid excessive generic instantiation across crate boundaries. The author stresses the impact of build time on developer productivity and recommends regularly optimizing build times to keep CI times for large Rust projects within a reasonable range, e.g., around 10 minutes.

Read more
Development Build Optimization

Open Source's Coordination Problem: Lessons from Linux Desktop and LSP

2025-06-20

The author uses their experience with NixOS and a KDE application as a starting point to discuss the challenges of coordinating open-source software in the Linux desktop environment. They highlight the lack of a unified API standard in the Linux desktop, leading to a fragmented software ecosystem, described as an "Escher-like perpetual motion machine." This is contrasted with the release of the Language Server Protocol (LSP) by Microsoft a decade ago. While the implementation was mediocre, its mere existence solved the coordination problem for IDE features, driving industry progress. The author argues that the open-source community's lack of coordination led to the missed opportunity to create a unified IDE protocol before LSP. Linux's success, however, is attributed to the pre-defined API standard provided by POSIX, reducing coordination difficulties. This article prompts reflection on the open-source community's coordination mechanisms and software ecosystem development models. Category: Tech

Read more
Tech

Two Thumb Rules for Efficient Code

2025-05-17

This article presents two practical tips for improving code efficiency: moving `if` conditions upwards and `for` loops downwards. Moving `if` conditions to the caller function reduces branching, simplifies control flow, and improves readability. Moving `for` loops to where batch data is processed leverages batch processing advantages, improves performance, and potentially unlocks vectorization. These two tips complement each other, effectively enhancing code efficiency, especially when handling large amounts of data.

Read more
Development

Beyond Scalar Select: Batching Event Streams for Efficiency

2025-05-15

The author describes the inefficiency of the scalar select anti-pattern in stateful service design, exemplified by an LSP server. Processing events one at a time leads to delays and resource waste. The proposed solution is to batch process event streams. A `batch_stream` function merges incoming events into batches, significantly improving efficiency. Under low load, it behaves like single-event processing, but under high load, it dramatically reduces overhead, boosting performance.

Read more
Development

Zig's Comptime: Powerful Yet Restrained Metaprogramming

2025-04-20

Zig's comptime feature is renowned for its capabilities: generics, conditional compilation, and more. However, it's deliberately restrictive, disallowing dynamic code generation, custom syntax extensions, runtime type information (RTTI), and I/O. This article explores the reasoning behind these limitations, showcasing how Zig achieves efficient and understandable metaprogramming through partial evaluation and type specialization. A custom printing function example demonstrates how Zig performs type-safe runtime reflection without RTTI. The article concludes by praising Zig's unique elegance in metaprogramming; while less powerful than alternatives, it's remarkably efficient and easy to use in practice.

Read more

Debugger as REPL: IntelliJ IDEA's Run to Cursor and Quick Evaluate Expression

2025-03-28

Tired of traditional debuggers, especially gdb and lldb's limitations with native code, the author discovered a powerful workflow in IntelliJ IDEA. Combining "Run to Cursor" and "Quick Evaluate Expression" transforms the debugger into a REPL. "Run to Cursor" executes the program to the cursor's position, while "Quick Evaluate Expression" lets you evaluate expressions (even newly typed code!) within the current stack frame. This approach replaces the line-by-line stepping with a more experimental, two-dimensional interaction within the editor, leveraging code completion and offering a significantly more efficient debugging experience.

Read more
Development

Favor Long Options in Scripts

2025-03-22

Many command-line utilities offer both short (-f) and long (--force) options. While short options are convenient for interactive use, long options are far superior in scripts. Their improved readability and self-explanatory nature enhance maintainability and understanding. For instance, in Git, `git switch --create release-{today} origin/main` is significantly clearer than `git switch -c my-new-branch`, particularly within complex scripts.

Read more
Development long options

Hardcore Rust: A Ray Tracer Without Dynamic Memory Allocation

2025-01-30

This post details a case study of writing a Rust application using only a minimal, artificially constrained API (no dynamic memory allocation). The author critiques RAII (Resource Acquisition Is Initialization) for leading to messy resource management and proposes a "hard mode": splitting the program into a `std` binary and a `#![no_std] no_alloc` library, allowing only the binary to directly request resources from the OS. Using a toy ray tracer as an example, the author meticulously explains handling pixel buffers, parallelization, the memory allocator, and scene parsing in this "hard mode," ultimately achieving a ray tracer without dynamic memory allocation.

Read more
Development

Invariants: A Powerful Tool for Writing Correct Code

2025-01-12

This article explores the concept of 'invariants' in programming and their applications. Starting with a small example—writing a binary search variation that computes the insertion point—the author demonstrates how defining and maintaining invariants leads to correct code. Invariants, the article explains, are properties that hold true throughout a system's dynamic evolution, simplifying reasoning by avoiding the complexities of considering numerous execution paths. Examples from projects like Cargo, rust-analyzer, and TigerBeetle illustrate the benefits of using invariants in large systems, such as improved maintainability and performance. The author concludes by summarizing the importance of invariants in both small-scale and large-scale programming, highlighting their value in writing correct and efficient code.

Read more

Revolutionary Idea: Applying Magit Principles to the jj Version Control System

2024-12-13

The author proposes a novel approach: applying the Magit version control interface from Emacs (which uses text files as its UI) to the nascent jj version control ecosystem. The article points out that Magit's text-based UI offers efficiency and portability. By leveraging the LSP protocol, a Magit-like experience can be implemented in various editors, avoiding redundant development. The author envisions generating specific text files (such as .jj/status.jj) and utilizing LSP features like semantic tokens, folding ranges, and goto definition to achieve Magit-like version control operations. The ultimate goal is to create a cross-platform, efficient user interface for jj version control.

Read more
Development