1个不稳定版本

0.1.0 2023年3月27日

#1230 in Rust模式

MIT/Apache

46KB
788

简而言之,这个库解决了函数着色问题以及其他一些关键字泛型计划正在关注的问题。这是如何将效应系统融入到Rust中的一个实验。

effing-mad,Rust的效应库

这个库通过提供特性和宏,将代数效应和效应处理器引入Rust,允许以与Rust现有async函数大致相同的方式编写有效应的代码。

这是什么意思

使用此库的有效应函数可以显式挂起(yield)其执行并将控制权交回调用者,调用者稍后恢复函数。数据可以通过这两种转换传递,并且这种数据在Rust中以预期的方式强类型。

从有效应函数传递出的数据指定一个操作。它被交给效应处理器,执行操作并将结果传回给有效应函数。然后,有效应函数的执行继续。就像调用函数,但方向相反。

事实上,反向调用函数有一些非常好的优点。由于效应是在调用者内部处理的,而不是在调用者外部,因此它们在异步、可选、可失败或其他各种副词上的处理没有界限。此外,不同的调用者可以使用不同的处理器来处理同一个有效应函数,这意味着执行I/O的有效应函数可以从常规的fnasync fn调用,并在两种情况下以“自然”的方式进行I/O。不再有popular_cratepopular_crate::blocking之间的区别!*

* effing-mad 不保证会变得流行。自行承担风险。

您可以在 examples/ 目录中看到整个混乱的情况。首先查看“基本”示例,除非你真的很聪明或勇敢或类似的人。

为什么

TL;DR: API实验和乐趣

我看到了一篇关于近期努力使函数既能从异步上下文也能从同步上下文使用的文章。[文章链接] 作者们还提到了希望高阶函数,如Option::map能够是异步的、可选的、可能失败的,或具有其他一些形容词——而无需为每一组效果编写一个专门的函数,如try_async_map。这正是我上一段提到的那个问题,我在那里还解释了效果系统是如何解决这个问题的。

了解到这一点,我惊讶地看到在文章的常见问题解答中,他们回答“你正在构建一个效果系统吗?”时说“不是真的”。他们从未解释过为什么不是!所以我亲自做了这件事,因为我想看看会发生什么。

这有多酷?

effing-mad很酷。甚至很棒。看看它有哪些酷炫的功能

  • 不稳定编译器功能(生成器、generator_trait)
  • 一个有22个类型参数的函数
  • #![无_std]
  • 令人恐惧的范畴论词汇(积产物!👻)
  • 过程宏
  • 声明式宏(曾经有,但因为我需要它们生成标识符,而它们做不到:)
  • 不安全
  • 原始指针
  • Pin,这意味着我真的很擅长Rust
  • 一个名为“frunk”的依赖项。嘿嘿嘿嘿

2022年进行的一项市场分析确定,没有其他库像effing-mad那样拥有那么多酷炫的功能,也许core除外。我的意思是,core 发明了Pin,这是作弊,所以实际上我赢了。

一些其他事实

在像Haskell这样的纯函数语言中,副作用(如I/O)通常使用monads(单调)在语言及其类型系统中编码。这些类型持有效果和/或纯计算的输出。因此,如果您想有多个类型的效果,事情会变得棘手,因为所有效果类型都想持有纯的东西在里面,但您只有一个纯的东西在进行。这意味着您必须使用monad transformers。我不太懂monad transformers,因此它们很糟糕。

另一方面,我确实理解代数效果,因此它们很好。而且它们更容易组合,在我看来,它们更直观。今天下载effing-mad!

更多事实——这次与Rust有关

effing-mad使用生成器。由于语言团队已经需要能够暂停和恢复的函数,因此它的实现变得更加容易,因为这促使他们发明了生成器。尽管它们是为了使编译器能够编译异步函数而制造的,但它们的通用性比异步函数要广泛得多。

编译器使用了生成器,但直接使用它们尚未稳定,因为没有人真的需要这样做。这就是为什么您需要使用nightly编译器来使用effing-mad。

依赖项

~0.6–1MB
~22K SLoC