[英]When are physically distinct values created in OCaml?
我试图理解物理相等运算符( Pervasives.(==)
和Pervasives.(!=)
)在OCaml中的含义。
语言手册说表达式""
是“常量”,而不是“表达式”:
6.5常数
constant :: == ... string-literal
但是我找不到任何表明常量是单独/预先评估或合并的,并且REPL表明可变字符串值(谢天谢地)没有合并。
(* a *) "" == "";; (* false *)
(* b *) "foo" == "foo";; (* false *)
(* c *) "" == String.copy "";; (* false *)
(* d *) () == ();; (* true *)
(* e *) (42, -42) == (42, -42);; (* false *)
(* f *) ("", 1) == ("", 1);; (* false *)
(* g *) None == None;; (* true *)
(* h *) (Some None) == (Some None);; (* false *)
“ 19.3 OCaml数据类型的表示 ”一节表明,语言规范要求bool,int,chars,单位值,简单变体和空列表都是无私的。
实现是否必须像上面那样成为一个符合要求的OCaml实现?
一个符合条件的OCaml实现可以重写b
处的指针指向a
当a = b (* structurally *)
为真且两者都是不可变类型的值(或有效不可变值,如零长度字符串/数组),有时会这样做减少代际GC中可达到的较年轻值的数量?
当我阅读语言规范时,很少有关于何时值不同的保证。 我相信唯一的保证是在Pervasives模块的文档中:
在可变类型(如引用,数组,字符串,具有可变字段的记录和具有可变实例变量的对象)上,当且仅当e1的物理修改也影响e2时,e1 == e2才为真。 在非可变类型上,(==)的行为是依赖于实现的; 但是,保证e1 == e2意味着比较e1 e2 = 0。
关于FP的一个很酷的事情是编译器和运行时可以使用不可变值自由地做任意聪明的事情。 所以这个保证就是你真正想拥有的(恕我直言)。
总之,是的,运行时或编译器是免费的(再次,恕我直言)以任何它认为有用的方式共享(而不是共享)不可变值。
我不会将表示部分解释为语言规范的一部分。 它只是当前实现的有用文档。
只是一个注释:字符串常量的汇集方式与您测试的方式不同:
let f () = "foo"
let b = f () == f () (* true *)
如果你改变f ()
调用的输出,这可能确实会导致错误:这也将影响所有进一步的调用。 关于该行为的共识是可变字符串是一个历史错误(一个应该具有与主字符串类型不同的可变缓冲区类型,编码选择和连接复杂性应该更重要)并且语义破坏池很有趣性能方面允许假设字符串常量没有变异。 如果想要避免池化,则应该直接在字符串常量上调用String.copy
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.