Show HN:Rust 但 Lisp

2026-05-10 1 阅读 thatxliner
rlisp 你好,黑客新闻。你没有错。这是一个周末项目,而不是生产编译器——缺少一些 Rust 语法(turbofish 现已修复,生命周期界限在列表中)。重点不在于完整性;而在于完整性。它正在探索当你将 Lisp 宏附加到 Rust 语义上时会发生什么。如果这听起来很有趣,请继续阅读。如果您正在寻找令人生气的事情,问题跟踪器已开放。使用 LISP 语法的 Rust 语义。一个透明的 s-表达式前端,直接编译为 Rust — 没有运行时,没有 GC,只是 (s-expr → .rs → 二进制) 。 (struct Point (x f64) (y f64)) (impl Point (fn distance (( &self ) (other &Point )) f64 ( let dx ( - ( . self x) ( . other x))) ( let dy ( - ( . self y) ( . other y))) (( . dx powf 2.0 ) + ( . dy powf 2.0 )) sqrt )) (fn main () () ( let p1 (new Point (x 0.0 ) (y 0.0 ))) ( let p2 (new Point (x 3.0 ) (y 4.0 ))) (println! " Distance: {} " ( . p1 distance (& p2)))) Rust 拥有的一切 — 所有权、借用、生命周期、泛型、特征、模式匹配 — 都表达为 s 表达式。没有语义差距。 rustc 进行类型检查、借用检查和优化。 rlisp 只处理语法。安装 git clone https://github.com/ThatXliner/rlisp.git cd rlisp Cargo install --path 。用法 rlisp compile file.lisp # 转译为 file.rs rlisp build file.lisp # 使用 rustc 转译和编译 rlisp run file.lisp # 转译、编译和运行 语法映射 LISP Rust (fn add ((x i32) (y i32)) i32 (+ x y)) fn add(x: i32, y: i32) -> i32 { (x + y) (让 x i32 42) 让 x: i32 = 42; (struct Point (x f64) (y f64)) struct Point { x: f64, y: f64 } (struct Pair f64 f64) struct Pair(f64, f64); (结构单元)结构单元; (enum Option (T) (Some T) None) enum Option { Some(T), None } (match val ((Some x) (handle x)) (None ())) match val { Some(x) => { handle(x) }, None => { } } (if (> x 0) (println! "yes") (println! "no")) if (x > 0) { println!("yes") } else { println!("no") } (impl Point (fn new (...) ...)) impl Point { fn new(...) ... } (trait Display (fn fmt (...) Result)) Trait Display { fn fmt(...) -> Result; } (new Point (x 1.0) (y 2.0)) Point { x: 1.0, y: 2.0 } (.obj 字段) obj.field (.obj 方法 arg) obj.method(arg) ([] arr 0) arr[0] (foo!args) foo!(args) (println! "{}" x) println!("{}", x) (loop (println!"tick")) 循环 { println!("tick") } (while (> x 0) (-= x 1)) while x > 0 { x -= 1 } (for x in 0..10 (println! "{}" x)) for x in 0..10 { println!("{}", x) } (lambda (x y) (+ x y)) |x, y| { x + y } (pub fn foo () i32 42) pub fn foo() -> i32 { 42 } (pub (crate) mod m (fn f () () ())) pub(crate) mod m { fn f() {} } (使用 std::collections::HashMap) 使用 std::collections::HashMap; (const MAX usize 1024) const MAX: usize = 1024; (rust "让 x: i32 = 42; x") 让 x: i32 = 42; x (::collect Vec<_>)collect::> (fn foo ('a) ((x &'a str)) (&'a str) x) fn foo<'a>(x: &'a str) -> &'a str { x } (break) 中断; (中断表达式)中断表达式; (返回表达式)返回表达式; (as x i32) x as i32 (if-let (Some v) x (body) (else)) if let Some(v) = x { body } else { else } (while-let (Some v) iter (body)) while let Some(v) = iter { body } (unsafe (body)) unsafe { body } 二元运算符 ( + , - , * , / , == , != , < , > , && 等)发出中缀: (+ a b) → (a + b) 。宏 rlisp 宏是编译时 s 表达式转换器 — 没有 proc_macro crate、没有 token 流、没有 syn/quote。宏只是从 s 表达式到 s 表达式的函数。宏体使用从 LISP 借用的三种特殊形式: 形式 含义(quasiquote 模板) “引用此模板,但允许在内部取消引用” — 就像标记的模板文字(取消引用名称) “在此处插入名称的值” — 模板中的一个洞(取消引用拼接名称) “将列表名称拼接到周围的列表中” — 用于插入多个形式 将 quasiquote 视为“返回这个精确的 s 表达式,除了取消引用之外洞。”如果没有它,您必须使用 list 和 cons 手动构造每个括号。 ; ;定义一个when宏:(when条件体...)(defmacrowhen(条件&restbody)(quasiquote(if