Re: subtyping and inheritance

From: Jerome Vouillon (Jerome.Vouillon@inria.fr)
Date: Wed Jan 27 1999 - 15:28:31 MET


Date: Wed, 27 Jan 1999 15:28:31 +0100
From: Jerome Vouillon <Jerome.Vouillon@inria.fr>
To: Hendrik Tews <tews@irritatie.cs.kun.nl>, caml-list@inria.fr
Subject: Re: subtyping and inheritance
In-Reply-To: <199901201150.MAA09911@irritatie.cs.kun.nl>; from Hendrik Tews on Wed, Jan 20, 1999 at 12:50:21PM +0100

--7zPtVaVf+AK4Oqc4
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit

On Wed, Jan 20, 1999 at 12:50:21PM +0100, Hendrik Tews wrote:
> There was already a proposal how to solve the problem by Jerome
> Vouillon. Just for demonstration I append another solution, which
> uses a self implemented type case. It supports code reuse better,
> but loses type security by using the Obj module. Maybe one of the
> people who "understand the whole source code for the O'Caml
> compiler, runtime and libraries" and by that can use the Obj
> module, can comment on its use here.

Your example indeed works, as coercions do not actually modify
objects.
When you need to make use of the Obj module, it is however advised to
limit this use to a small module with a type-safe interface. Your
example can be rewritten this way:

class top = object
  inherit Property.c
  method eq (x : top) = print_string "top = top ? "; true
end;;
let left_k = Property.create_key ();;
class left (l1 : int) = object (self)
  inherit top as super
  initializer Property.add left_k self l1
  method eq x =
    try
      let l1' = Property.find left_k x in
      print_string "left = left ? ";
      l1 = l1'
    with Not_found -> super#eq x
end;;
let right_k = Property.create_key ();;
class right (r1 : int) = object (self)
  inherit top as super
  initializer Property.add right_k self r1
  method eq x =
    try
      let r1' = Property.find right_k x in
      print_string "right = right ? ";
      r1 = r1'
    with Not_found -> super#eq x
end;;

-- Jérôme

--7zPtVaVf+AK4Oqc4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="property.mli"

type 'a t

type u and u'

class virtual s : object
  method virtual properties : u
  method virtual add_property : u' -> unit
end

class c : object
  method properties : u
  method add_property : u' -> unit
end

val create_key : unit -> 'a t
val add : 'a t -> #c -> 'a -> unit
val find : 'a t -> #c -> 'a

--7zPtVaVf+AK4Oqc4
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="property.ml"

type 'a t = int

module Properties = Map.Make (struct type t = int let compare = compare end)

type u' = int * Obj.t
type u = Obj.t Properties.t

class virtual s = object
  method virtual properties : u
  method virtual add_property : u' -> unit
end

class c = object
  val mutable properties = (Properties.empty : u)
  method properties = properties
  method add_property (k, p) = properties <- Properties.add k p properties
end

let i = ref (-1)
let create_key () = incr i; !i

let add p x v = x#add_property (p, Obj.repr v)

let find p x = Obj.obj (Properties.find p (x#properties))

--7zPtVaVf+AK4Oqc4--



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:18 MET