8 ms·
OCaml: Objects
- agumonkey 12y agoOlder, hopefully still relevant, article about OCaml objects : http://roscidus.com/blog/blog/2013/09/28/ocaml-objects/ http://roscidus.com/blog/blog/2013/09/28/ocaml-objects/ (from 0install author)
- BrianEatWorld 12y agoI went in expecting to see a write up on Common Lisp's CLOS[1], because at a recent Clojure Meetup, the speaker put forth the claim that CLOS is the most powerful OO system out there. He didn't have time to validate the claim, but it may be of interest to those who like this article. [1] http://cl-cookbook.sourceforge.net/clos-tutorial/index.html http://cl-cookbook.sourceforge.net/clos-tutorial/index.html
- tel 12y agoI don't think OCaml wants to vie for "most powerful" object system. It's almost the opposite, really. OCaml's object system is "best" because it's weak in exactly the kinds of ways that make it easy to reason about and more likely to be correct.
- theevilcellist 12y agoWas that the one in Austin last week? Also, I highly recommend Doug Hoyte's Let Over Lambda[1] where he goes into detail about a certain duality of closures and objects. [1] http://letoverlambda.com/ http://letoverlambda.com/
- wirrbel 12y agoSICP does the job of demonstrating the Closure-Object relationship just as fine, without boring the reader with endless references to the superiority of Lisp, as Let Over Lambda does.
- hyperpape 12y agoFrom the blurb: "Let Over Lambda is one of the most hardcore computer programming books out there. Starting with the fundamentals, it describes the most advanced features of the most advanced language: Common Lisp. Only the top percentile of programmers use lisp and if you can understand this book you are in the top percentile of lisp programmers. If you are looking for a dry coding manual that re-hashes common-sense techniques in whatever langue du jour, this book is not for you. This book is about pushing the boundaries of what we know about programming. While this book teaches useful skills that can help solve your programming problems today and now, it has also been designed to be entertaining and inspiring. If you have ever wondered what lisp or even programming itself is really about, this is the book you have been looking for."
- wirrbel 12y agoI should have known better when I ordered the book. Hoyte's first intention, writing a 2nd Volume for Paul Grahams On Lisp, which goes into detail about macros, is actually quite good. It just does not live up to "Volume 1". And about the 1 percentile and "only the best" talk: Lisp and Lisp Macros are not really "magic". They are accessible to programmers like you and me and if someone does not bother to write them it is not about lack of understanding, but lack of time it takes to write them properly.
- hyperpape 12y agoInteresting to hear. I don't have a particular opinion about the book, beyond having heard some praise, but I do think that blurb is assinine.
- BrianEatWorld 12y agoThanks for the reference. I will check out that and SICP[1] as mentioned by one of your replies. It was the Austin Meetup. The name of the presenter escapes me, but it was great overview. The topic wasn't meant to be CLOS, it was just mentioned in passing, which was why I was hoping that it was the topic of this article. [1] http://mitpress.mit.edu/sicp/ http://mitpress.mit.edu/sicp/
- agumonkey 12y agoLisp features are often the most powerful because they're as limited as Lisp, which we all know is pretty loose on this side.
- GFK_of_xmaspast 12y agoIf I had a nickel for every "it's the best" claim made by lisp evangelists....
- tel 12y agoTotal agreement! OCaml's object system is wonderfully austere. It arises as a pretty natural extension of the more restrained signature subtyping relation---and this helps drive home, as this article also emphasizes, the vital distinction between subclassing and subtyping. That alone means that you'll have a more well-principled and reasonable object system than basically any other one I've ever used. In day-to-day OCaml, I often hear people suggest that one should avoid the object system. The primary things it buys you are access to the row-typing system and class/object constructor hierarchies. It however is a bit slower due to the use of dynamic dispatch (instead of compiling vtables statically to their use site) and can face some inference issues. That said, row types are an incredibly useful type construct (often Haskellers lament the fact that they're missing leading to the creation of things like Ermine and Vinyl). Cautious use of the object system is very exciting!
- aplusbi 12y agoOCaml objects are pretty neat, although I rarely ever end up using them. Although I also rarely ever use OCaml for that matter. One issue with the article - the author confuses duck typing and structural typing. While they are similar, there are important differences. OCaml uses structural typing (which enforces type at compile time) and not duck typing.
- evmar 12y agoThis post is also a great demonstration as to why a programming language cannot be evaluated as a feature checklist. OCaml's object system is certainly awesome but in practice you'll find it is unevenly used -- some never use it, while I'm sure there are others who use it heavily. Because it behaves in a way that is not quite compatible with the rest of the language it is inconvenient to mix APIs that use the two styles of programming. Another comment here on HN links to a post that summarizes with the rule of thumb of simply "don't use objects". The lesson is that any given feature exists in an ecosystem of other features and its utility is dictated by many things (impedance mismatch with the rest of the language or even language cultural problems) other than the specification itself.
- haifeng 12y agoExcellent point!
- rwmj 12y agoI have a slightly more nuanced point of view. I pretty much write OCaml code for a living, and rarely use objects, but that's because they are rarely useful (as a general concept, nothing to do with OCaml). To give a concrete example of a program where I happened to use objects for the first time in ages[1], most of the program works by defining a set of types[2], and then using simple functions to work on those types. The program is essentially: transform the input structure to another structure to another structure. All the structures are publicly defined making it really easy to understand the program and debug when things go wrong. The flow of execution is simple and obvious, and the compiler picks up possible errors in that flow because of the strong typing. But there happened to be one place that I wanted the ability to hide data + use implicit variant code alongside that data, and then I switched over to using objects[3]. It's a narrow use case and I've written a lot of code without ever needing that. Of course in OOP languages you essentially have to use objects to get any work done, and so people go crazy and it's impossible to follow the flow of execution. [1] https://github.com/libguestfs/libguestfs/tree/master/v2v https://github.com/libguestfs/libguestfs/tree/master/v2v [2] https://github.com/libguestfs/libguestfs/blob/master/v2v/types.mli https://github.com/libguestfs/libguestfs/blob/master/v2v/typ... [3] https://github.com/libguestfs/libguestfs/blob/master/v2v/types.mli#L164-L193 https://github.com/libguestfs/libguestfs/blob/master/v2v/typ...
- jsnell 12y agoTo me the post is really not making the case at all that OCaml's object system is "best", as suggested in the HN headline. Really the only comparison to any other system is contrasting row polymorphism to duck typing. Like another user I was actually expecting this to be about CLOS based on the title. It'd still be a hard claim to make given some of the warts CLOS has, but at least it's a claim that people will often genuinely make. (This also seems to be the fourth time the same post was submitted by the same user, with increasingly clickbaity headlines.)
- dang 12y agoA small number of reposts is ok if an article hasn't had significant attention yet (see the FAQ). I'd say this is about the limit, though. You're right about the submitted headline ("Best object system is actually from a functional language").
- kxyvr 12y agoWhat I never understood is why OCaml allows row polymorphism in objects, but not in record types. For example, we can write: 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?
- rwmj 12y agoI believe it's because #info (ie. method access) is kind of dynamic. The string "info" is hashed and then the hash is looked up at runtime against the class vtable. (For precise details, see 19.3.5 here: http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html http://caml.inria.fr/pub/docs/manual-ocaml/intfc.html) I'm not clear under what circumstances this can be optimized to a direct call, and there is also some kind of cache, so repeated method calls to the same method are fast. This is the reason people who value performance over everything else steer clear of using objects in OCaml. Record fields are simply offsets in a struct, so the type must be fully known when compiling the code. It would not be possible to compile a function that could work on two different types of struct that both happened to have a .info field.