A with-based effect notation
概述
本文提出了一种基于with的效果标记(notation)系统,用于Rust语言中的effect处理。这是作者关于Rust effect系统的后续文章。
核心思想: 不依赖冗长的函数前缀序列(如
pub const placing try gen fn foo() {}),而是将effects分离到自己的声明中。
什么是Effects
Effects是函数可以执行但不是其返回值的一部分。例如:
- async: 函数可能暂停执行
- throw: 函数可能抛出错误
- gen: 函数可能产生多个值
- const: 函数可能在编译时运行
Effect语法
// 基本函数
fn foo() -> i32 { ... }
// 带effect的函数
fn foo() [async, throws] -> i32 { ... }
// 更Pythonic的写法
with async, throws:
fn foo() -> i32 { ... }
Effect Aliases
该notation还提供effect aliases:命名一组effect的集合。例如:
effect io = { async, throws }
fn foo() [io] -> i32 { ... }
Effect参数化
一些effects如iteration和fallibility本身带有泛型参数:
- 迭代需要知道迭代的值的类型
- throw需要知道可能的错误类型
Effect泛型
通过引入新的泛型种类eff来实现:
fn foo<T, eff>(x: T) [eff] -> T
Effect排序
使用Flix模型,个别effect kinds不能重复。效果集合中的排序不重要:
fn foo() [async, throws] -> i32
fn bar() [throws, async] -> i32 // 等价
与现有工作的关系
- 与Koka语言的effect系统相似
- 与Leijen的"Structured asynchrony with algebraic effects"相关
- Flix的"Programming with effect exclusion"提供了广泛的条件表达
结论
这个notation为Rust中的effect系统提供了一个清晰的路径,使得effects的声明更加简洁和可读。它借鉴了多种学术研究成果,为Rust的未来发展提供了可能性。