Function 是否在每次函数调用时计算可选参数的默认值?

Function 是否在每次函数调用时计算可选参数的默认值?,function,ocaml,optional-parameters,Function,Ocaml,Optional Parameters,这些文件将默认值的使用记录到可选参数中,但没有指定如果默认值是(例如)每次可能返回不同值的函数,会发生什么情况 从一些测试来看,如果没有传入参数,则每次都会对值进行评估;e、 g 设x=ref 0;; 让我们加入= x:=!x+1; !x ;; let测试?(a=增量x)(=a;; 调用test()会导致1、2、3、…,每次递增,但调用test~a:123()不会递增ref 运行test()或test~a()的行为大致类似 let test?a()= 让我们= 匹配 |无->增量x |一些a-

这些文件将默认值的使用记录到可选参数中,但没有指定如果默认值是(例如)每次可能返回不同值的函数,会发生什么情况

从一些测试来看,如果没有传入参数,则每次都会对值进行评估;e、 g

设x=ref 0;;
让我们加入=
x:=!x+1;
!x
;;
let测试?(a=增量x)(=a;;
调用
test()
会导致1、2、3、…,每次递增,但调用
test~a:123()
不会递增ref

运行
test()
test~a()
的行为大致类似

let test?a()=
让我们=
匹配
|无->增量x
|一些a->a
在里面
_测试~a()的主体
;;

这是正确的建模方法吗?而且,这种行为是否有记录在案?

这确实是预期的行为。从(我的)重点来看:

形式为
fun的函数?lab:(pattern=expr0)->expr
相当于
有趣吗?lab:ident->let pattern=将ident与某些ident->ident | None->expr中的expr0匹配

如果
ident
是一个新变量,除非在计算
expr0
时未指定该变量

尽管对增量的评估工作与您认为的一样,但在函数应用程序中“隐藏”效果是非常不明智的。值得注意的是,以下代码可能返回
true
false
,但不能保证编译器的另一个版本会给出相同的行为

let test2 ?(a = incr x) ?(b = incr x) () = a < b
if test2 () then ...
让test2?(a=incr x)?(b=incr x)()=a
这确实是预期的行为。从(我的)重点来看:

形式为
fun的函数?lab:(pattern=expr0)->expr
相当于
有趣吗?lab:ident->let pattern=将ident与某些ident->ident | None->expr中的expr0匹配

如果
ident
是一个新变量,除非在计算
expr0
时未指定该变量

尽管对增量的评估工作与您认为的一样,但在函数应用程序中“隐藏”效果是非常不明智的。值得注意的是,以下代码可能返回
true
false
,但不能保证编译器的另一个版本会给出相同的行为

let test2 ?(a = incr x) ?(b = incr x) () = a < b
if test2 () then ...
让test2?(a=incr x)?(b=incr x)()=a
我想知道这里的“未指定”是指在程序启动时还是每次调用时只评估一次。或者如果“未指定”与函数中计算
expr0
的位置有关。可以是下一个未命名参数被绑定时、最后一个参数被绑定时或在函数中首次使用时。可能值得在文档中要求澄清。对我来说,文档的第一部分清楚地表明,在每次调用时都会对其进行评估,而不是在调用时。我不得不承认,这个措辞是可疑的,但我要说的是,无论如何,在可选参数中隐藏不纯的表达式是一种不好的做法。但是,对自动递增ID来说,这太诱人了。抵制黑暗面吧,戈斯温!:-)可以手动编写可选参数的等效代码。我不知道这里的“未指定”是指它在程序启动时还是每次调用时只评估一次。或者如果“未指定”与函数中计算
expr0
的位置有关。可以是下一个未命名参数被绑定时、最后一个参数被绑定时或在函数中首次使用时。可能值得在文档中要求澄清。对我来说,文档的第一部分清楚地表明,在每次调用时都会对其进行评估,而不是在调用时。我不得不承认,这个措辞是可疑的,但我要说的是,无论如何,在可选参数中隐藏不纯的表达式是一种不好的做法。但是,对自动递增ID来说,这太诱人了。抵制黑暗面吧,戈斯温!:-)可以手动编写可选参数的等效代码。这样就定义了它的行为方式和评估时间。