 
 
 
 Functional Style
Object-oriented programming usually has an imperative style. A message is
sent to an object that physically modifies its internal state (i.e. its data
fields). It is also possible to use a functional approach to
object-oriented programming: sending a message returns a new object.
 Object Copy
Objective CAML provides a special syntactic construct for returning a copy of an object
self with some of the fields modified.
 Syntax 
 
{< 
name1=expr1;...;
namen=exprn 
>}
This way we can define functional points where methods for relative moves
have no side effect, but instead return a new point.
# class f_point p =
  object
   inherit point p
   method f_rmoveto_x (dx) = {< x = x + dx >}
   method f_rmoveto_y (dy) = {< y = y + dy >}
  end ;;
class f_point :
  int * int ->
  object ('a)
    val mutable x : int
    val mutable y : int
    method distance : unit -> float
    method f_rmoveto_x : int -> 'a
    method f_rmoveto_y : int -> 'a
    method get_x : int
    method get_y : int
    method moveto : int * int -> unit
    method print : unit -> unit
    method rmoveto : int * int -> unit
    method to_string : unit -> string
  end
With the new methods, movement no longer modifies the receiving object; instead a new object
is returned that reflects the movement.
# let p = new f_point (1,1) ;;
val p : f_point = <obj>
# print_string (p#to_string()) ;;
( 1, 1)- : unit = ()
# let q = p#f_rmoveto_x 2 ;;
val q : f_point = <obj>
# print_string (p#to_string()) ;;
( 1, 1)- : unit = ()
# print_string (q#to_string()) ;;
( 3, 1)- : unit = ()
Since these methods construct an object, it is possible to send a message
directly to the result of the method f_rmoveto_x.
# print_string ((p#f_rmoveto_x 3)#to_string()) ;;
( 4, 1)- : unit = ()
The result type of the methods f_rmoveto_x and f_rmoveto_y
is the type of the instance of the defined class, as shown by the 'a
in the type of f_rmoveto_x. 
# class f_colored_point (xc, yc) (c:string) =
   object
     inherit f_point(xc, yc)
     val color = c
     method get_c = color
   end ;;
class f_colored_point :
  int * int ->
  string ->
  object ('a)
    val color : string
    val mutable x : int
    val mutable y : int
    method distance : unit -> float
    method f_rmoveto_x : int -> 'a
    method f_rmoveto_y : int -> 'a
    method get_c : string
    method get_x : int
    method get_y : int
    method moveto : int * int -> unit
    method print : unit -> unit
    method rmoveto : int * int -> unit
    method to_string : unit -> string
  end
Sending f_rmoveto_x to an instance of f_colored_point
returns a new instance of f_colored_point.
# let fpc = new f_colored_point (2,3) "blue" ;;
val fpc : f_colored_point = <obj>
# let fpc2 = fpc#f_rmoveto_x 4 ;;
val fpc2 : f_colored_point = <obj>
# fpc2#get_c;;
- : string = "blue"
One can also obtain a copy of an arbitrary object, using the the primitive
copy from module Oo:
# Oo.copy ;;
- : (< .. > as 'a) -> 'a = <fun>
# let q = Oo.copy p ;;
val q : f_point = <obj>
# print_string (p#to_string()) ;;
( 1, 1)- : unit = ()
# print_string (q#to_string()) ;;
( 1, 1)- : unit = ()
# p#moveto(4,5) ;;
- : unit = ()
# print_string (p#to_string()) ;;
( 4, 5)- : unit = ()
# print_string (q#to_string()) ;;
( 1, 1)- : unit = ()
 Example: a Class for Lists
A functional method may use the object itself, self, to compute the
value to be returned. Let us illustrate this point by defining a simple
hierarchy of classes for representing lists of integers.
First we define the abstract class, parameterized by the type of list
elements.
# class virtual ['a] o_list () =
 object
   method virtual empty : unit -> bool
   method virtual cons  : 'a -> 'a o_list 
   method virtual head :  'a 
   method virtual tail : 'a o_list
 end;;
We define the class of non empty lists.
# class  ['a] o_cons (n ,l)  =
 object (self)
   inherit ['a] o_list ()
   val car = n
   val cdr = l
   method empty () = false
   method cons x = new o_cons (x, (self : 'a #o_list :> 'a o_list))
   method head = car
   method tail = cdr
 end;;
class ['a] o_cons :
  'a * 'a o_list ->
  object
    val car : 'a
    val cdr : 'a o_list
    method cons : 'a -> 'a o_list
    method empty : unit -> bool
    method head : 'a
    method tail : 'a o_list
  end
We should note that method cons returns a new instance of
'a o_cons. To this effect, the type of self is constrained
to 'a #o_list, then subtyped to 'a o_list. Without
subtyping, we would obtain an open type ('a #o_list), which appears in the
type of the methods, and is strictly forbidden (see page
??). Without the additional constraint, the type of
self could not be a subtype of 'a o_list.
This way we obtain the expected type for method cons. So now we know
the trick and we define the class of empty lists.
# exception EmptyList ;;
# class ['a] o_nil () =
  object(self)
   inherit ['a] o_list ()
   method empty () = true
   method cons x = new o_cons (x, (self : 'a #o_list :> 'a o_list))
   method head = raise EmptyList
   method tail = raise EmptyList
  end ;;
First of all we build an instance of the empty list, and then a list of integers.
# let i = new o_nil ();;
val i : '_a o_nil = <obj>
# let l = new o_cons (3,i);;
val l : int o_list = <obj>
# l#head;;
- : int = 3
# l#tail#empty();;
- : bool = true
The last expression sends the message tail to the list containing the
integer 3, which triggers the method tail from the class 'a o_cons.
The message empty(), which returns true, is sent to this result.
You can see that the method which has been executed is empty from
the class 'a o_nil.
 
 
