2014-12-05Published on 2014-12-05
OCaml Object-Oriented Features
Note that the relation between object, class and type in OCaml is very different from that in mainstream object-oriented languages like Java or C++, so that you should not assume that similar keywords mean the same thing.
class point = object val mutable x = 0 method get_x = x method move d = x <- x + d end;; let p = new point;; p#get_x;; (* 0 *) p#move 3;; p#get_x;; (* 3 *)
Class could have parameters, which are visible in the whole body of the definition, including methods.
class point x_init = object val mutable x = x_init method get_x = x method get_offset = x - x_init method move d = x <- x + d end;; new point;; (* this is a function of type int -> point *) let p = new point 7;; (* this is an object *)
Expressions can be evaluated and bound before defining the object body of the class.
class adjusted_point x_init = let origin = (x_init / 10) * 10 in object val mutable x = origin method get_x = x method get_offset = x - origin method move d = x <- x + d end;;
There is another, more direct way to create an object: create it without going through a class. Unlike classes, which cannot be defined inside an expression, immediate objects can appear anywhere, using variables from their environment. Immediate objects have two weaknesses compared to classes: their types are not abbreviated, and you cannot inherit from them. But these two weaknesses can be advantages in some situations.
let p = object val mutable x = 0 method get_x = x method move d = x <- x + d end;; p#get_x;; (* 0 *) p#move 3;; p#get_x;; (* 3 *)
Reference to Self
A method or an initializer can send messages to self (that is, the current object). For that, self must be explicitly bound, here to the variable s (s could be any identifier, even though we will often choose the name self.)
class printable_point x_init = object (s) val mutable x = x_init method get_x = x method move d = x <- x + d method print = print_int s#get_x;print_newline() end;; let p = new printable_point 7;; p#print;;
Let-bindings within class definitions are evaluated before the object is constructed. It is also possible to evaluate an expression immediately after the object has been built. Such code is written as an anonymous hidden method called an initializer. Therefore, it can access self and the instance variables.
class printable_point x_init = let origin = (x_init / 10) * 10 in object (self) val mutable x = origin method get_x = x method move d = x <- x + d method print = print_int self#get_x initializer print_string "new point at "; self#print; print_newline () end;; let p = new printable_point 17;; (* the initializer will be evaluated immediately, with some messages printed out *)
Include Virtual Methods, Private Methods, Inheritance and so on.
About Natural Language Processing
Automaton: Spelling Check, Morphological Analysis, Part-of-Speech Tagging
Word Segmentation: Automaton, Hidden Morkov Model (HMM), Character-Based Tagging
Word Sense Disambiguation: Mutual-Information, Bayes Classifier, Thesaurus