OCaml 参数传递方案中的断点
Breakpoints in the argument-passing scheme of OCaml
今天,我正在查看 Jane Street's Core_kernel
module and I came across compose
函数的源代码:
(* The typical use case for these functions is to pass in functional arguments
and get functions as a result. For this reason, we tell the compiler where
to insert breakpoints in the argument-passing scheme. *)
let compose f g = (); fun x -> f (g x)
我会将 compose
函数定义为:
let compose f g x = f (g x)
他们给出这样定义 compose
的原因是“因为 compose
是一个以函数 f
和 g
作为参数的函数,并且 returns 函数 fun x -> f (g x)
结果,他们定义了 compose
他们告诉编译器在 f
和 g
之后但在 [=23] 之前插入断点的方式=] 在参数传递方案中。”
所以我有两个问题:
- 为什么我们需要在参数传递方案中设置断点?
- 如果我们以正常方式定义
compose
会有什么不同?
来自 Haskell,这个约定对我来说没有任何意义。
这是一种效率技巧,可以避免评论中指出的预期用例中部分应用程序的成本。
OCaml 将柯里化函数编译成固定元数结构,并在必要时使用闭包部分应用它们。这意味着该参数的调用是高效的——没有闭包构造,只有函数调用。
对于fun x -> f (g x)
,将是compose
中的闭包构造,但这将比部分应用更有效。由部分应用程序生成的闭包通过一个包装器 caml_curryN
来确保效果在正确的时间发生(如果该闭包本身是部分应用的)。
编译器选择的固定元数是基于简单的句法分析——本质上是连续接受多少个参数,中间没有任何参数。 Jane St. 程序员通过注入 ()
"in between" 个参数,将其用于 select 他们想要的参数。
简而言之,let compose f g x = f (g x)
是一个不太理想的定义,因为它会导致常见的双参数情况 compose f g
成为更昂贵的部分应用程序。
在语义上,当然,完全没有区别。
值得注意的是,部分应用程序的编译在 OCaml 中得到了改进,不再需要这种性能破解。
今天,我正在查看 Jane Street's Core_kernel
module and I came across compose
函数的源代码:
(* The typical use case for these functions is to pass in functional arguments
and get functions as a result. For this reason, we tell the compiler where
to insert breakpoints in the argument-passing scheme. *)
let compose f g = (); fun x -> f (g x)
我会将 compose
函数定义为:
let compose f g x = f (g x)
他们给出这样定义 compose
的原因是“因为 compose
是一个以函数 f
和 g
作为参数的函数,并且 returns 函数 fun x -> f (g x)
结果,他们定义了 compose
他们告诉编译器在 f
和 g
之后但在 [=23] 之前插入断点的方式=] 在参数传递方案中。”
所以我有两个问题:
- 为什么我们需要在参数传递方案中设置断点?
- 如果我们以正常方式定义
compose
会有什么不同?
来自 Haskell,这个约定对我来说没有任何意义。
这是一种效率技巧,可以避免评论中指出的预期用例中部分应用程序的成本。
OCaml 将柯里化函数编译成固定元数结构,并在必要时使用闭包部分应用它们。这意味着该参数的调用是高效的——没有闭包构造,只有函数调用。
对于fun x -> f (g x)
,将是compose
中的闭包构造,但这将比部分应用更有效。由部分应用程序生成的闭包通过一个包装器 caml_curryN
来确保效果在正确的时间发生(如果该闭包本身是部分应用的)。
编译器选择的固定元数是基于简单的句法分析——本质上是连续接受多少个参数,中间没有任何参数。 Jane St. 程序员通过注入 ()
"in between" 个参数,将其用于 select 他们想要的参数。
简而言之,let compose f g x = f (g x)
是一个不太理想的定义,因为它会导致常见的双参数情况 compose f g
成为更昂贵的部分应用程序。
在语义上,当然,完全没有区别。
值得注意的是,部分应用程序的编译在 OCaml 中得到了改进,不再需要这种性能破解。