2026年开启OCaml与Eio学习之旅:体验、挑战与Raft实现展望!

📅 2026/7/23 12:46:21 👁️ 阅读次数 📝 编程学习
2026年开启OCaml与Eio学习之旅:体验、挑战与Raft实现展望!

2026年体验OCaml和Eio:学习实践全记录,Raft实现待归来!

2026年7月15日,博主开启了体验OCaml和Eio的旅程。博主在该网站的第一篇博客文章是关于Haskell的,虽一直对函数式编程感兴趣,但觉得Haskell的复杂性不值得深入研究。

博主早就听说过OCaml却未尝试,近期随着多核支持、效应系统引入,以及Jane Street推出更注重系统编程的OxCaml,OCaml迎来复兴,此时学习正当时,且博主对Eio并发框架也很好奇,因其使用效应系统且具有确定性,对测试有帮助。

书籍与教程

博主先在谷歌搜索后选择了《Real World OCaml》,以为它和《Real World Haskell》类似且自己有函数式编程基础,便跳过前言直接阅读。后来才发现这本书用Jane Street的`Base`标准库替代方案,虽历史上OCaml标准库功能薄弱,但现在已改善。博主吸取教训重读,前半部分学习顺利,但学到广义代数数据类型和一等模块时犯迷糊,且觉得书里缺少练习。

之后博主找到CS3110,它有视频和文字,还有练习,适合不同学习风格的人。博主建议先学这门课程,再学《Real World OCaml》掌握高级特性,不过若希望找到像《Real World Haskell》那样基于项目的书,可能会失望。

实际编码感受

总体而言,用OCaml编写代码很愉快,它融合了函数式编程和命令式编程。例如遍历列表时,既可用递归函数,也可用`List.map`及其相关函数;若需要,还能使用可变变量等。不过,OCaml的语法有些冗长,如`let .. in`、`match .. with`等结构,但博主认为语法不是编程语言中有趣的部分,有命名参数还是不错的。

让博主困扰的是编译器,它遇到错误就放弃处理文件其余部分,使迭代开发过程变慢,难以批量修复错误。

Eio

Eio是基于效应系统的IO并发库,较新且有支持io_uring等有趣特性。博主的最终目标是实现Raft共识算法并测试。Raft论文提到用远程过程调用在服务器之间通信,一个简单的RPC客户端/服务器是很好的入门项目。

博主设计了简单协议,过程调用包含请求ID、名称和参数,整数用单字节表示,字符串先以一个字节表示长度再是具体数据。响应只包含请求ID和返回的字符串值。

在开始前,需要熟悉Eio构建模块的术语:Fiber是执行线程但非系统线程;Switch用于将纤维分组,类似Go语言中的`sync.WaitGroup`;Flow是可读写对象;Stream是有界、线程安全的队列,类似Go语言中的通道;Promise大家比较熟悉。

服务器部分

先从服务器开始,要获取Flow并循环,从中读取过程调用,执行并发送响应。定义了保存连接的类型,使用`Buf_read`或`Buf_write`类型进行缓冲读写以提高效率,`read_string`/`write_string`函数来自`Utils`模块。还需要辅助函数获取缓冲流并运行循环,以及测试可执行文件。测试结果不错。

客户端部分

对于客户端,要确保安全并发使用,通过两个纤维实现:一个读取,一个写入。写入纤维从流中获取任务,调用方法时向流中添加任务。将响应返回给调用者的方法是在流中发送Promise并存储在哈希表中,服务器响应后解决Promise。接收循环可读取响应并解决Promise,还能在多个不同纤维中使用。

总结

总体来说,学习和使用OCaml很有趣,它有很多优点,支持函数式和命令式编程,是编译型语言且编译器速度快,可选择使用异常或错误值等。但它的用户群体相对较小,目前不太清楚最佳入门方式,可供学习的代码也不多。

对于用过Go语言的人来说,Eio会很熟悉。博主使用时常遇到流被关闭的问题,后来发现是该阻塞操作时启动了纤维。博主希望不久后能带着可用的Raft实现回归。