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