OCaml 局部参数入门

原标题Introducing Local Parameters in OCaml

通过示例了解 Jane Street 实验性的 local 模式如何限制值逃逸,并让函数接口更易于推理。

频道
Jane Street
发布
2024年1月5日
视频
8:52
阅读
3 分钟
幻灯片
4
原文
英语
在 YouTube 打开
往下滚动阅读时,视频会缩到右下角继续播放。字幕跟随阅读语言。
阅读语言共 2 种语言可读
由 AI 从英语原文翻译。打开“对照原文”可以逐段核对。
摘要

30 秒看懂

一位 Jane Street 演讲者介绍公司 OCaml 编译器实验分支中的 local 模式。他通过返回值、可变引用和文件回调等例子,解释局部参数向调用方作出的承诺,并为后续讨论内存分配做好铺垫。

  1. 1实验性模式local 模式是在 Jane Street 的 OCaml 编译器分支中开发的想法。演讲者先介绍其类型系统行为,再讨论它对内存分配的益处。
  2. 2不能逃逸的参数把函数参数标为 local,意味着该参数不能逃逸其区域。返回这个参数会产生编译器错误。
  3. 3存储也是一种逃逸将局部字符串存入外部引用也会使其逃逸,即使函数返回的是另一个值,编译器仍会拒绝。
  4. 4推理可变操作调用方可以利用 local 标注推断,函数在返回后没有保留第一个参数,从而分析之后修改该参数的影响。
  5. 5文件回调接收局部文件句柄的回调不能保留它,因此外层函数可以在回调返回后关闭文件。

要点建议

  1. 演示中的 local 模式来自 Jane Street 的实验性编译器分支,长期目标是将相关工作合并到上游。
  2. 局部参数不能逃逸其区域,例如不能通过返回或存入外部引用而逃逸。
  3. local 模式约束函数实现,同时允许调用方传入局部或全局参数。
  4. 不逃逸的参数有助于调用方推理后续修改以及回调中资源的生命周期。
  5. 该系列后续会把 local 模式与内存分配行为及延迟敏感型代码的性能联系起来。
全文

按章节阅读整理后的全文

只看原始文稿
01

local 模式实验

演讲者介绍 Jane Street 的 OCaml 编译器分支中的 local 模式,解释为什么本集从类型系统行为开始。长期目标包括改善延迟敏感型代码的内存分配。

我想开始一个关于 local 模式的系列,它是在 Jane Street 的 OCaml 编译器实验分支中开发的想法。我们在这个分支中尝试和完善新想法,目标是最终将它们合并到主编译器。目前,我们可以在 Jane Street 的编译器中探索 local 模式。

我们会逐步了解 local 如何影响类型系统。最终的好处是改善内存分配行为,从而可能加快延迟敏感型代码。但我认为,先理解类型层面的行为,比直接讨论内存分配更容易入手。

我使用的是 Jane Street 版本的 OCaml 4.14.1。local 是一种模式,并不完全等同于类型,因此我不想称它为局部类型。示例中,我会为 let 绑定写出完整的类型标注:local 模式支持类型推断,但显式签名让例子更紧凑,错误信息也更清楚。

02

参数与区域逃逸

局部参数不能通过返回或存储到其他位置而逃逸其区域。演讲者展示编译器错误,并指出“每个函数都定义一个区域”这一简化规则存在例外。

先从一个简单函数开始,给它的参数加上 local 标注。这表示参数不会逃逸函数。如果函数返回这个局部参数,编译器就会报告该值逃逸了其区域:返回它违背了标注作出的承诺。

局部参数与尝试返回
幻灯片 1 / 4局部参数与尝试返回示例将一个参数标为 local,并展示不逃逸的承诺。

对于有两个参数的函数,标注可以只作用于第一个参数 x。返回 x 会产生逃逸错误,返回没有标注的第二个参数 y 则可以通过编译。我们对 x 作出了承诺,而不是对 y 作出了承诺。

区域是代码中的一片范围。目前可以先认为每个函数都定义了一个区域,不过其中有一个例外,我会在后续视频中解释。局部参数不能逃逸其区域,返回它就是一种逃逸方式。

把局部值存到其他地方也是一种逃逸。例如,如果 x 是一个局部字符串参数,而我把它赋给外部字符串引用,即使函数返回的是 y,编译器也会拒绝这次赋值。local 标注向调用方承诺参数不会逃逸。

将局部参数存入引用
幻灯片 2 / 4将局部参数存入引用代码尝试把局部参数赋给外部引用,这是值逃逸的另一种方式。
03

推理可变操作与回调

不逃逸的参数有助于调用方推理之后的修改。文件回调示例展示如何防止局部句柄逃出预期生命周期。

这有什么用?假设某个类型有一个可变字符串字段,函数 f 将第一个参数作为局部参数接收。调用方可以用 t1 和 t2 调用 f,之后再修改 t1。由于 f 不能保留 t1,调用方可以推断,之后的修改不会影响 f 对该参数保留的关系或 f 返回的值。

将可变值传给局部参数
幻灯片 3 / 4将可变值传给局部参数示例为分析调用一个首参数为 local 的函数后,可变记录会发生什么提供了背景。

局部参数对回调也有用。想象一个 with_file 函数,它接收文件名和一个回调,回调的文件句柄参数标为 local。回调结束后,外层函数知道回调没有存储或返回句柄,因此可以关闭文件。没有这一保证,我们就只能相信回调不会保留句柄。

回调中的局部文件句柄
幻灯片 4 / 4回调中的局部文件句柄回调签名将句柄参数标为 local,使其不能在回调结束后继续保留。
04

对调用方的承诺

local 模式约束的是函数实现,而不是调用方可以传入的参数种类。局部和全局参数都可以传入。

这个标注约束的是函数实现,而不是调用方可以传入什么。局部参数既可以接收局部实参,也可以接收全局实参。不能返回或存储该参数,是函数向每个调用方作出的承诺;这只是探索的开始。

同频道的其他文章

1:48:29EN → 简体中文
JSJane Street· 2026年10月16日AI 如何改变编程:John Krazit 与 Ron Minsky 的对话Ron Minsky, John Krazit · Jane StreetJane Street 的 AI 工具负责人和 Signals and Threads 主持人探讨智能体基础设施、安全、代码审查,以及软件开发体验的变化。编程智能体Developer productivity评估+2
1:36:37EN → 简体中文
JSJane Street· 2026年9月23日Aaron Bauer:在 AI 时代教授软件工程Ron Minsky, Aaron Bauer · Jane Street当模型能够生成代码时,学习目标、主动练习和编辑器设计如何影响工程教育。AI in EducationSoftware engineeringEducation+2
9 张幻灯片1:05:45EN → 简体中文
JSJane Street· 2026年9月11日Cyrus Omar:实时编程与人与 AI 共享的计算公共空间Cyrus Omar通过 Hazel 演示,探讨即时反馈、结构化协作和精细权限如何帮助人类与 AI 智能体共同工作。Programming LanguagesHuman-AI Collaboration开发流程与测试+2
1:25:00EN → 简体中文
JSJane Street· 2026年9月2日Eric Mannes:如何将杂乱的外部数据用于交易研究Ron, Eric Mannes · Jane Street从商品期货和 Excel 风险系统,到时点数据集和 AI,Eric Mannes 解释 Jane Street 数据工程背后的领域知识。Data quality & curation开发流程与测试Investing+2
7 张幻灯片1:16:29EN → 简体中文
JSJane Street· 2026年8月26日Grant Sanderson 与 Alok Puranik:从群论看位置编码Grant Sanderson, Alok Puranik · 3Blue1Brown从注意力机制的假设出发,他们推导矩阵指数,并将旋转、衰减和 Jordan 块与 RoPE、ALiBi 联系起来。Transformers & attentionMathematics机器学习基础+1
4:41EN → 简体中文
JSJane Street· 2026年7月6日走进 Jane Street 实习项目:工作、导师与学习Cody · Jane Street实习生和员工讲述协作式面试、从零学习金融,以及参与公司实际使用的项目的经历。CareersCompany CultureMachine Learning+1