Reading "Types and programming languages", I got impressed by the object implementation using closures and record subtyping (chapter 18). Is there any particular reason OCaml doesn't support record subtyping (I know objects do, though)? In fact, I can't find any language that support this.
Technically, OCaml's objects do not really support subtyping in the usual sense, but row polymorphism. There are many advantages of row polymorphism over subtyping, in particular it both is more expressive and works much better with type inference (subtyping and type inference do not mix well at all).
The primary problem with using either structural subtyping or row polymorphism for all records is that it requires a significantly more involved runtime implementation, and consequently, also is more expensive. Where simple records can trivially be translated into plain tuples, with field access being just indexing, structural subtyping or row polymorphism require the ability to transparently "slice" an object, i.e. view it under a supertype with random fields removed. In general, this requires either field lookup by hashing (such as Ocaml's objects), or evidence passing techniques, where the index of every field used by a function or any of its callees has to be passed as a hidden argument in addition to the actual record (that's what SML# is doing, for example).
In any case, Ocaml has polymorphic records, they are just called objects. But you can ignore all the class mess around them if you don't need it.
Record subtyping is quite dangerous on a typing point of view.
Let's say you have a record with three fields: a, b and c. And you want to create a record with only two fields: a and c. The compiler doesn't know what type you're using until it finishes reading the whole record, and still at the end, cannot help you if you made a mistake : you forgot the b field for example.
I fully agree that this point of view is contestable, but I think that's how people who write ocaml think.
© 2022 - 2024 — McMap. All rights reserved.