是否在每次函数调用时评估可选参数的默认值?
Are default values to optional parameters evaluated on every function call?
OCaml spec 记录了可选参数的默认值的使用,但没有具体说明如果默认值是例如一个每次可以 return 不同值的函数。
从一些测试来看,似乎每次都计算值 如果 参数没有传入;例如
let x = ref 0;;
let incr x =
x := !x + 1;
!x
;;
let test ?(a = incr x) () = a;;
调用 test ()
结果为 1、2、3、...,每次递增,但调用 test ~a:123 ()
不会递增 ref。
运行 test ()
或 test ~a ()
的行为似乎大致类似于
let test ?a () =
let a =
match a with
| None -> incr x
| Some a -> a
in
body_of_test ~a ()
;;
这是建模的正确方法吗?而且,这种行为是否记录在某处?
这确实是预期的行为。从documentation(强调我的)看:
A function of the form fun ? lab :( pattern = expr0 ) -> expr
is equivalent to
fun ? lab : ident -> let pattern = match ident with Some ident -> ident | None -> expr0 in expr
where ident
is a fresh variable, except that it is unspecified when expr0
is evaluated.
尽管对增量的评估如您所想的那样工作,但在函数应用程序中 "hide" 效果是非常不明智的。值得注意的是,以下代码可以 return true
或 false
,但不能保证另一个版本的编译器会给出相同的行为。
let test2 ?(a = incr x) ?(b = incr x) () = a < b
if test2 () then ...
OCaml spec 记录了可选参数的默认值的使用,但没有具体说明如果默认值是例如一个每次可以 return 不同值的函数。
从一些测试来看,似乎每次都计算值 如果 参数没有传入;例如
let x = ref 0;;
let incr x =
x := !x + 1;
!x
;;
let test ?(a = incr x) () = a;;
调用 test ()
结果为 1、2、3、...,每次递增,但调用 test ~a:123 ()
不会递增 ref。
运行 test ()
或 test ~a ()
的行为似乎大致类似于
let test ?a () =
let a =
match a with
| None -> incr x
| Some a -> a
in
body_of_test ~a ()
;;
这是建模的正确方法吗?而且,这种行为是否记录在某处?
这确实是预期的行为。从documentation(强调我的)看:
A function of the form
fun ? lab :( pattern = expr0 ) -> expr
is equivalent tofun ? lab : ident -> let pattern = match ident with Some ident -> ident | None -> expr0 in expr
where
ident
is a fresh variable, except that it is unspecified whenexpr0
is evaluated.
尽管对增量的评估如您所想的那样工作,但在函数应用程序中 "hide" 效果是非常不明智的。值得注意的是,以下代码可以 return true
或 false
,但不能保证另一个版本的编译器会给出相同的行为。
let test2 ?(a = incr x) ?(b = incr x) () = a < b
if test2 () then ...