revo,编程语言
摘要
Revo 是一种新的编程语言,具有干净的数据流(无嵌套)、错误即值、一切皆表达式、编译时执行和过程宏等特点。
<p><a href="https://lobste.rs/s/ikkx3r/revo_programming_language">评论</a></p>
查看缓存全文
缓存时间: 2026/06/02 19:36
# revo
来源:https://gills.pages.dev/revo/
``
⣄⠔⠄⡨⣀⣹⣥⣣⡚⣿⣓⣾⣫⣷⠮⡧⣬⣬⣑⢤⠤⡉⣿⡥⣂⢟⣕⡴⠬⠆⠸⡈⡆⠀⠀⠀⡋⠄⠂⠨⡆⠀⠠⠃⡀⠀⠀⠈⢰⣿
⠩⣽⢟⢭⠶⢷⢵⣻⠿⢍⣟⡅⡧⡭⣽⡯⡯⣶⠭⣽⡢⠱⢿⢧⠓⢥⠨⠧⠉⣡⠐⠀⢑⣀⠂⠈⠆⡅⠀⡀⢥⠤⢁⠀⢣⠀⠀⢘⠽⡏
⠬⡓⣼⢟⢜⡧⣷⣇⣧⡷⢯⣿⣿⣿⡶⣭⠍⣯⣻⢥⠞⣮⣬⣩⠅⢏⠆⠁⡀⠌⢩⡁⢁⠅⠡⢀⠠⠀⢉⢈⠀⠀⡅⠀⡇⠀⠀⠃⠭⣯
⡎⣟⣵⠅⣾⢭⣿⣾⣯⣿⣿⢿⣿⣿⣿⣿⣧⡳⣥⢜⣟⡤⠉⣁⢧⢨⠌⡂⠀⠒⠬⡪⣊⠄⠀⠘⠀⠢⡁⠀⡀⠅⠅⠀⡄⠀⠈⠀⢕⡟
⡕⣧⡗⠎⠷⣯⣿⣿⣷⣿⡻⢵⣿⣿⣿⣭⣿⡿⣟⣇⡧⣿⡭⢨⠫⠮⠄⠖⠀⠆⠦⠕⠁⠅⠀⠆⡁⠁⡀⠀⠄⡉⠁⠀⠄⡀⡂⠀⢼⣇
⠃⣶⣯⠢⡗⣟⣿⡿⣿⣯⢿⣷⢾⢿⣛⣿⣿⣯⡻⣾⡾⣾⢵⣏⣩⠅⠅⠥⠀⠃⠠⠅⠃⠀⡈⠀⠭⠅⠀⠀⠁⠔⠀⠀⢂⠅⠅⠀⠽⡇
⠱⣻⣻⡥⢫⢯⢿⣷⣷⣿⣿⢾⢿⣷⢯⣉⣟⣟⣾⣿⠳⣿⣇⣃⠯⠘⠔⡇⠒⠅⡖⠁⠄⠡⠑⣀⠀⡁⠀⡀⠃⠈⠀⠀⠅⠀⠀⠂⣋⡇
⢂⠵⣓⣿⣍⢯⢯⡯⣟⣝⠷⣟⢝⣋⡏⣧⠯⣿⣿⢯⣼⣯⡂⡂⣟⡧⠐⣅⠂⠥⠏⠀⠂⡅⠅⡁⠁⠄⠠⠊⠀⠨⠀⢈⠀⠄⠉⢘⡟⡆
⡥⣯⢌⡤⢽⣗⣏⠗⢿⣻⡭⡞⡷⣭⢿⡻⡯⡟⣕⣾⢽⢯⡭⠂⡍⠀⠏⠀⢌⠴⠂⠊⡄⢗⠂⠰⠀⠤⠣⠀⠀⠀⠁⠀⠀⠀⠅⠀⢕⡽
⠵⡭⡩⠋⠽⣽⡛⡹⢯⠍⡛⡏⣯⢟⠟⠿⣩⣳⡿⡟⢗⣭⡤⡯⠁⡬⠠⠂⢄⠂⢤⠀⢖⠀⠀⢀⠂⢖⠀⠘⠀⠀⠂⠡⢤⠠⠀⠀⣫⡿
⠀⢰⡇⢂⣃⠙⣧⡵⡙⠇⡷⠶⡷⠶⡟⡙⣩⡌⠯⡺⡍⡲⡸⣆⠼⠅⡱⠌⠡⠂⢄⣠⠃⠀⠀⡂⠈⠂⠠⢀⠀⠀⠀⠔⠀⠂⠂⠀⠨⣯
⡔⠰⠼⣝⢪⢋⢋⠣⣧⡦⣦⡁⡭⠽⡛⠁⡫⢡⡄⠿⡫⣕⣔⢳⠌⢡⡸⠁⠁⠂⣠⡇⠀⠀⠀⠍⠈⠄⠀⠀⢀⠀⠔⠆⠁⠈⠠⠀⡹⡏
⡖⣠⠄⠀⠯⢜⢨⠊⣒⢡⠨⡀⠢⢭⠴⡊⢕⠐⣄⡓⡾⠋⠗⠉⢀⠚⠀⢃⠂⠥⠲⠀⠀⠀⠄⠐⠀⠀⠐⠀⠁⠄⠱⠁⠊⠈⡀⠀⠊⣽
⠀⡉⠒⣃⠰⡀⢁⠘⡉⠪⠋⡲⡅⠍⡎⡪⢣⠽⢭⠍⡥⠁⠂⡰⠠⣄⠥⠐⠀⠣⠄⢀⠐⠁⡀⠀⢐⠐⠀⠠⠁⠂⠄⠠⠀⠁⡀⠐⣫⡟
⠐⢔⠁⠀⠬⠑⠗⠴⠀⠢⡁⢌⠅⢘⠓⡛⠈⡀⠄⠆⠠⠠⠢⢂⠕⠷⠈⢀⠈⡒⠄⠂⠀⠀⠈⠀⡀⠡⠈⠀⠆⡐⠀⠀⠓⠀⠀⠀⢐⢼
⡀⠀⠈⠐⠠⠀⠀⠁⠁⠣⢀⡁⡄⠂⠔⠂⠂⢉⠁⡌⠄⠜⠈⠡⠐⠀⡐⠀⢨⠀⠁⠀⠀⡀⠍⠄⠠⠁⠀⠠⢄⠈⠀⠀⡄⠀⠀⡀⠒⣸
⢘⠉⡒⠤⠌⢀⠑⠕⠀⠄⠄⠄⠀⠄⠑⠉⠨⠀⠄⠀⠂⠃⠀⠀⠈⠄⠄⠠⠈⠀⠀⡀⠠⠁⢠⠁⠁⠀⠐⠱⠀⠀⠀⡐⠀⠉⠄⠀⢸⠾
⠀⠘⠈⡀⠈⠀⠈⠨⠐⠠⠠⠐⡀⡄⢠⠀⢀⠨⠀⠃⠀⠀⡁⡠⠀⠩⠀⠂⠁⠀⠀⠀⢒⡄⠊⠀⠀⢀⠈⠁⠀⠀⠀⠆⠘⠁⠄⠀⠄⣿
⠄⡄⠀⠈⠠⠀⡀⠀⠀⠄⠀⠂⠀⠀⠄⠀⢀⠁⠁⢁⠁⠆⠀⠀⠀⠀⡀⠀⠈⠀⡀⠀⠱⠀⠀⠀⠀⠂⢄⠈⠀⠀⡀⡨⠠⡀⠠⠀⠄⡼
⠠⠀⠁⠊⢀⠀⠠⠁⠁⠂⠂⡄⢄⠐⡀⢀⠊⠂⡀⡁⡀⢀⢀⠠⠀⠄⠂⠡⠠⠁⠀⠀⠀⠂⠀⢠⠒⠀⠀⠀⠐⠢⠀⢀⠀⠀⠄⠄⣿⣿
⠁⠋⠙⠊⠐⠕⠁⡂⠈⠅⠠⠈⠐⠀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡠⠀⠉⠀⠐⠀⠀⠀⠀⠀⣈⠀⠀⠀⠀⠈⡂⠈⠀⠀⠘⠌⢀⠥
⠀⠀⠀⠀⠔⠔⠀⡀⡉⠀⠀⠀⠂⠠⠠⠀⠄⠄⠀⣀⢀⠀⡈⠀⠌⡐⠈⠈⠀⠀⠀⠀⠅⠀⣐⠉⠄⠀⠀⣂⠠⠁⡈⠀⠄⠄⢀⠣⢶⢿
⠄⠀⠀⡁⠀⠄⠀⠀⠁⠈⠀⠈⠀⠁⠀⠁⡀⠁⠀⠁⠀⠀⠀⡀⠀⠀⠀⠀⠀⠠⡀⠑⠀⠀⠎⠀⢬⢠⠀⢂⠠⠢⠠⠈⡐⠸⠀⡐⣹⢷
⠩⠥⠂⠆⡆⢠⠀⢄⠀⣀⡀⣄⠀⢈⠀⠀⣀⡀⡀⡀⠄⡄⠡⠀⠐⠀⠑⠀⠀⠁⠒⠒⠉⠡⡀⠈⠈⢀⠥⠈⠀⠀⠀⠀⠈⣞⣏⣿⡏⣿
⠾⠝⠷⢿⣯⣿⠧⡧⠭⠣⠭⡭⡮⢭⠶⠶⠶⠦⣗⡶⠽⠭⣿⣶⠷⠵⠮⠽⠿⠮⠿⢷⡶⣖⡷⠲⠞⠷⠾⢿⢷⣿⣿⣿⣿⣯⢇⠟⡧⢈
``
## 管道
无需嵌套的清晰数据流
事物自上而下流动
``
"hello!!"
|> string.upper
|> string.sub(0, 4)
|> fn(s) s + ", world!"
|> inspect
# 或使用占位符,
"hello!!"
|> _:upper() # obj:method() == obj.method(obj)
|> _:sub(0, 4)
|> do
# 甚至可以在此放置任何表达式
# 包括 do-end 块
_ + ", world!"
end
|> print
# 效果相同,但请注意运算顺序
print(log("hello":upper():sub(0, 4) + ", world!"))
``
## 错误即值
nil 和布尔值被原子替换
不使用任何值必须处理错误,所有崩溃都是显式的(开发中)
通过模式匹配、`?`、`orelse` 和 `:unwrap()` 大幅简化
``
# f 可能是
# (:ok, "文件内容")
# 或 (:err, :IoError)
const f = fs.open({path = "./readme.md"})
# `?` 解包 :ok,在顶层遇到 :err 时崩溃
const f2 = fs.open({path = "./readme.md"})?
# 遇到 :err 时崩溃
const f = fs.open({path = "./readme.md"}):unwrap()
``
## 一切都是表达式
没有语句,所有内容(真的)始终返回一个值……但代码看起来仍然是过程式的
``
let x = 10 # 这一行求值为 10
let label = if x > 0 "正数" else "零"
let a = let b = 5 # 这一行整体求值为 5
fn is_true() 5 + 5 == 10
# x 和 is_true 都是同一个函数
const x = fn is_true() do # do-end 也是一种
# return 和 break 是特殊的
return 5 + 5 == 10
end
``
## 编译时执行
在编译时执行任何(真的)表达式
任何脚本都可以编译成字节码,并嵌入任意值
``
revo -b script.rv
revo script.rvo
``
编译时 VM 与运行时 VM 完全一致
``
# 构建时请求一行输入
# 然后在运行时保留结果
const x = comp read()
const long = do
let t = 0
for x in 0..100
t += x
t # 类似于 Rust 的 {},
# revo 的 do-end 块返回最后一个值
end
``
## 过程宏
结合 AST 替换宏系统,
这让你能够获得原始 AST 令牌上的迭代器,运行任意代码对其进行转换,然后返回新 AST 的表
``
# > num, num, num -> Sigma^4_n=1(a * b + c)
proc cmul!(iter) do
print("内部: ", add3!(10,20,12))
print("窥视: ", iter:peek())
match iter:peek()
| (:number, n) => print("是数字", n)
| (other, n) => print(other, n)
| x => print("不是元组: ", x)
let a = 10 + (iter:next_of(:number))
let b = iter:next_of(:number)
let c = iter:next_of(:number)
let acc = 0
for i in 1..5 do
acc += a * b + c
end
{(:number, acc)}
end
print(cmul!(10,20,30))
``
## 模式匹配
就地解构和分支
你会喜欢使用原子和元组,它们是解决对应问题的优雅方案
``
match (:ok, 42)
| (:ok, v) => v
| (:err, e) => panic(e)
| _ => panic()
| _ => panic()
# _ 是通配符,当没有其他匹配时使用
# 如果你想捕获实际值
# ,只需在那里放任何绑定名称
const response = match "hello!"
| "hello!" => "hi!"
| x when (x:len() > 10) => ""
| x when string?(x) => x + " 也向你问好!"
| _ => ":("
let f = match read({path = "./readme.md"})
| (:ok, file) => file
| (:err, error) when error == :FileDNE
=> panic("文件不存在")
| (error) => panic("错误")
| x => panic("未知: ", x)
``
## 纤程
只需在阻塞代码前加一个 spawn,即可使其变为非阻塞
``
fn serve(peer, message) do
peer:send(message)?
end
while :true do
# 接受下一个连接;如果没有就绪,此纤程会暂停,直到
# 运行时在监听套接字上看到连接。
let conn = server:accept()?
# 要使其异步,只需添加 `spawn`!
spawn serve(conn, port - 1)
end
``
## 表
表示所有内容
用于 - 模块导出 - 数组 - 映射
``
let t = {1, 2, 3, key = "value"}
let rec = {name = "revo", version = 1}
rec.name
t[0]
let mt = {
name = fn(self) self.name,
set_version = fn(self, v) self.version = v,
DELTA = 0.0,
}
# 元表只是一个“表覆盖层”
# 可以把它覆盖到其他表上
set_metatable(rec, mt)
let rec = {name = "revo", version = 2}
set_metatable(rec2, mt)
# name 在 rec 或 rec2 中不存在,
# 但仍然可以调用它们
assert_eq(rec:version(), 1)
assert_eq(rec2:version(), 2)
assert_eq(rec.DELTA, rec2.DELTA)
``
## 便捷的类型系统
类型系统是可选的,但集成得很好
未类型化的代码也可以正常工作,但
类型化的代码更快,优化更好(并且在编译时确保代码正确性!)大部分代码会自动推断类型
``
type Result =
(:ok, any)
| (:err, atom)
struct User {
name: string = "me",
age: int = 21,
fn get_age(self) -> Result
(:ok, self.age),
}
# 类型被推断
let user = User{}
print(user:get_age())
``
## 一等测试
它们只是闭包,当返回错误时失败。`?` 后缀运算符传播错误,提供非常简单的体验
``
fn add(a, b) a + b
suite "add" do
test "加法" do
expect(add(20, 22) == 42)?
expect(add(20, 22) != 22)?
end
test/skip "添加两个表" do
expect(add({1,2}, {3, 4}) == {4,6})?
end
end
``
## 快速开始
唯一依赖是 zig (https://ziglang.org/) 0.16.0 版本:该仓库也在 codeberg (https://codeberg.org/lung/revo) 上提供
``
cd /tmp
git clone https://github.com/if-not-nil/revo
zig build -Doptimize=ReleaseFast # 静态构建,包含内置库
./zig-out/bin/revo -e 'print("hello " + "world")'
# 然后将该二进制文件放入路径中
cp ./zig-out/bin/revo ~/.local/bin/revo
``
## 使用
请先查看 `revo -h`
``
revo script.rv # 运行脚本
revo # 启动 REPL
revo -e "1 + 2" # 内联代码
revo -b script.rv # script.rv -> script.rvo
revo -b -o output.rvo script # 自定义输出路径
revo --bench1 script.rv # 基准测试 script.rv
revo --test script.rv # 运行测试块
revo --dis script.rv # 字节码反汇编
``
## LSP
参见 ./lsp (https://gills.pages.dev/revo/lsp)
相似文章
Reve 2.0
Reve 2.0 是一款产品,能够通过基于布局的控制生成和编辑4K图像。
Rip 语言:编译到 ES2022,内置响应式
Rip 是一门受 CoffeeScript 启发的新语言,可编译为 ES2022 JavaScript,自带响应式系统、十余种新运算符,并拥有零依赖的自托管编译器。
Recursi
Recursi 是一个自我改进的氛围编码环境,无需 API 费用。
@DeRonin_: 你明白 Repowise 刚开源了什么?给你的 AI 一个代码库地图,成本降低 50%、速度提升 4 倍...
Repowise 是一个开源工具,将代码库索引为四个智能层(AST、依赖图、Git 历史、LLM 生成的维基),并将其暴露为 MCP 工具,使 Claude Code 等 AI 编码智能体能够理解代码架构和历史,从而成本降低 50%,任务速度提升 4 倍。
Wren 编程语言的性能表现
Wren 官网发布微基准测试,称其运行速度超过标准 Python/Ruby/Lua 解释器,同时仍保持简单的字节码虚拟机,得益于 NaN 标记和固定对象布局。