let bar x = x#info + 1
and OCaml will give a type: val bar : < info : int; .. > -> int = <fun>
which is precisely what we want since we can now define functions on any object that has an info member. At the same time, we can't write let buz x = x.info + 1
because we receive the error Error: Unbound record field info
This is a big deal since the exposed members of objects must be methods in OCaml. Certainly, we can declare values and mutable values, but these are not exposed in the objects type. Specifically, # class foo = object val info = 1 end;;
class foo : object val info : int end
# let bar = new foo;;
val bar : foo = <obj>
# bar#info;;
Error: This expression has type foo
It has no method info
In order to get around this, we can change these values to methods (or add getter methods that return these values). However, the problem with doing that is then we can't make a new object with all of the same values, but with the specified valued changed: # class foo = object method info = 1 end;;
class foo : object method info : int end
# let bar = new foo;;
val bar : foo = <obj>
# bar # info;;
- : int = 1
# let buz = bar with info = 2;;
Error: Parse error: [str_item] or ";;" expected (in [top_phrase])
In other words, we don't have a good mechanism for creating a bunch of immutable objects.In other words, OCaml records allow immutable records, but they lack row polymorphsim. OCaml classes allow row polymorphism, but disallow immutable updates (immutable updates meaning create a new object with everything the same, but one element different.)
Does anyone know why this is the case?