Exploring 'Rust but Lisp': S-Expressions Meet Systems Programming
The intersection of Lisp's minimalist syntax and Rust's rigorous memory safety model is a provocative concept. A new project, "rust-but-lisp," attempts to bridge these two worlds by providing a way to write Rust using S-expressions, which then compile directly into standard Rust code. The goal is to leverage Rust's performance and safety—no runtime, no garbage collection—while utilizing the parenthetical structure characteristic of Lisp.
While the project presents an interesting syntactic experiment, it has sparked a significant debate among the developer community regarding its practical utility, its reliance on LLMs, and the fundamental nature of what it means to be a "Lisp."
The Core Concept: S-Expressions as a Rust Frontend
At its heart, "rust-but-lisp" is a transpiler. It takes S-expressions (symbolic expressions) and maps them to Rust syntax. This approach essentially treats the Lisp-like syntax as a frontend for the Rust compiler. As noted by some observers, this is effectively writing Rust in an AST-like (Abstract Syntax Tree) format.
One of the primary arguments in favor of this approach is that it surfaces Rust-specific semantics without introducing new language rules. As user @hawkice points out:
I think some comments are missing the upside of it being precisely Rust, without any new semantics. If you want lisp that compiles to machine code, Common Lisp can get reasonably efficient. The purpose of bringing Rust into it is to surface Rust-specific semantics -- which many people quite like!
By remaining faithful to Rust's semantics, the project avoids the need to implement a new type system or memory management model, instead piggybacking on the existing power of the Rust compiler.
Community Critiques and Technical Hurdles
Despite the novelty, the project has faced several critical technical questions from the Hacker News community.
Syntax Coverage and Tooling
One of the most immediate concerns is whether the project can actually handle the complexities of Rust's syntax. Specifically, advanced features like lifetime specifications and the "turbofish" operator (::<>) are notoriously difficult to represent. User @vermilingua noted that the project claims full syntax coverage but lacks examples of these critical, trickier elements of the language.
Furthermore, the loss of the Rust ecosystem's tooling is a significant drawback. The Rust community relies heavily on rust-analyzer for IDE support and the compiler's legendary error messages. When writing in a Lisp-like wrapper, these benefits are diminished. As @skulk questioned:
So if I wanted to actually use this and I write some rust-but-lisp code and there's a compile error, will it show me a nice error message with an arrow pointing to where the error happened in my lisp code?
The "Lisp" Identity Crisis
There is a philosophical divide over whether this project is a "Lisp" at all. A true Lisp dialect usually implies a certain level of dynamism, macros, and a specific way of handling code as data. Critics argue that simply wrapping Rust syntax in parentheses is not the same as creating a Lisp dialect.
User @GalaxyNova observed that the project feels more like "writing Rust in an s-expression syntax instead of having a proper lisp dialect that compiles to Rust," calling the result "weird-looking" for experienced Lisp programmers.
The Role of LLMs in Modern Tooling
A recurring theme in the discussion is the project's apparent reliance on Large Language Models (LLMs) for its generation and documentation. This has led to two distinct points of contention:
- Documentation Style: Several users criticized the "LLM-style" phrasing in the README, specifically the use of repetitive, punchy phrases like "no runtime, no GC, just..." which some perceive as "slop" rather than technical writing.
- Implementation Choice: Some developers questioned why an LLM was used to generate the project when S-expression parsers are fundamentally simple to write by hand.
- Agent Compatibility: Interestingly, @jaggederest pointed out that S-expressions might actually be a poor choice for LLM-based coding agents, as these agents often struggle with deep parenthesis matching compared to Algol-style or Pythonic grammars.
Conclusion
"Rust but Lisp" serves as a fascinating thought experiment in syntactic sugar and language interoperability. While it successfully demonstrates that Rust's semantics can be mapped to S-expressions, the project highlights the gap between a syntactic wrapper and a fully realized language ecosystem. For those interested in the marriage of Lisp and Rust, other projects like Loon—which takes inspiration from Rust's ownership model—may offer a more integrated approach to the problem.