gpt4 book ai didi

ocaml - OCaml 中 `let rec` 绑定(bind)与常规 `let` 绑定(bind)的优势

转载 作者:行者123 更新时间:2023-12-04 19:07:13 25 4
gpt4 key购买 nike

这个问题是这个 SO 问题的后续问题:How to make a covariant observable in OCaml

接受的答案的作者(随便)注意到使用 let rec绑定(bind)两个独立的值比两个单独的值更“经济”let绑定(bind)。

let make x =
let queue = Queue.create () in
let obj = x in
let watch f = Queue.add f queue in
let notify () = Queue.iter (fun f -> f x) queue in
{ obj; watch; notify; }

对比
let make x =
let queue = Queue.create () in
let obj = x in
let rec watch f = Queue.add f queue
and notify () = Queue.iter (fun f -> f x) queue in
{ obj; watch; notify; }

他的说法正确吗?如果是这样,为什么第二个版本更“经济”?

最佳答案

正如我在评论中已经说过的,似乎通过使用 let rec ,您可以避免创建更多的闭包。为了检查这一点,我创建了两个略有不同的文件,如下所示:
test1.ml有没有 let rec 的“通常”方式:

let test1 x =
let x = 5 in
let w () = x + 1 in
let n () = x + 1 in
w () + n ()

另一方面, test2.ml使用 let rec :
let test2 x =
let x = 5 in
let rec w () = x + 1
and n () = x + 1 in
w () + n ()

我然后 ocamlc -dinstr 'd 两个文件(即我为两个文件生成字节码)并获得以下内容:

对于 test1.ml , 我有:
    branch L2
L3: envacc 1
offsetint 1
return 1
L4: envacc 1
offsetint 1
return 1
L1: const 5
push
acc 0
closure L4, 1
push
acc 1
closure L3, 1
push
const 0a
push
acc 1
apply 1
push
const 0a
push
acc 3
apply 1
addint
return 4
L2: closure L1, 0
push
acc 0
makeblock 1, 0
pop 1
setglobal Closuretest!

文件 test2.ml结果如下:
    branch L2
L3: envacc 3
offsetint 1
return 1
L4: envacc 1
offsetint 1
return 1
L1: const 5
push
acc 0
closurerec 3 4, 1
const 0a
push
acc 1
apply 1
push
const 0a
push
acc 3
apply 1
addint
return 4
L2: closure L1, 0
push
acc 0
makeblock 1, 0
pop 1
setglobal Closuretest2!

来自 Caml Virtual Machine — Instruction set Document (可惜我也不知道是不是官方的,不过看起来还是有道理的),貌似说明书 closureclosurerec在堆栈上生成一个闭包。如您所见, test1.ml 的字节码总共生成 3 个闭包,而 test2.ml只生成两个闭包(一个通过 closurerec )。

我不是组装大师,但你可以测试 ocamlopt -S filename.ml ,以便编译器留下(并且不删除)程序集(然后在 filename.s 中),您也可以在其中发现类似的差异。

关于ocaml - OCaml 中 `let rec` 绑定(bind)与常规 `let` 绑定(bind)的优势,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21500537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com