Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] object
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jacques Garrigue <garrigue@k...>
Subject: Re: [Caml-list] object
From: Michal Moskal <malekith@pld-linux.org>
> On Mon, Feb 17, 2003 at 12:14:44PM +0300, inv2002 wrote:
> > class a_obj = ...
> > class b_obj = ...
> > 
> > class object_list = object
> >   val ht = Hashtbl.create 5
> > 
> >   method add: 'a. string -> (#obj as 'a) -> unit = fun key o ->
> >     Hashtbl.add ht key (o :> obj) (* i don't know right way, how to store objects *)
> > 
> >   method find key =
> >     Hashtbl.find ht key
> > 
> > end
> > 
> > i want to store a_obj and b_obj in object_list,
> > after find it and execute a_fun method
> > if the object is a_obj
> 
> How do you know object is really of type a_obj?
> 
> There are few solutions:
> 
> 1. type a_or_b_obj = A_obj of a_obj | B_obj of b_obj
> 
> method add k o = Hashtbl.add ht k o
> 
> foo#add (A_obj a)
> foo#add (B_obj b)
> 
> 2. add a_fun and b_fun with ,,assert false'' like implementation
> 3. use Obj.magic
> 
> First solution gives you static typing, second gives you dynamic typing,
> and third -- no typing.

Please, never suggest using Obj.magic on this list.
(Maybe we should have a special filter so that messages containing the
words Obj.magic are reviewed by hand)
Using Obj.magic in a user program is throwing away all the safety
ensured by caml, going back to the C level. And gdb will not help you.

If you look at the caml list archives with the keyword "downcast" you
will see a whole litterature about how to solve this kind of problems

http://pauillac.inria.fr/bin/wilma_glimpse/caml-list?query=downcast

Solution (1) and (2) above are good enough for simple cases.

If you don't like the restrictions caused by solution (1), my prefered
answer uses parametric classes:

class virtual ['a] obj = object
    method virtual real : 'a
    ...
  end

class ['a] a_obj = object (self)
  inherit ['a] obj
  method real = `Ta self
  method a_fun = ...
end

class ['a] b_obj = object
  inherit ['a] obj
  method real = `Tb self
  method b_fun = ...
end

This way you can get back your original type by pattern matching on
o#real. OO purists would say that it does not work well with
subtyping, but if your problem is about subtyping then solution (2)
above might be better.

Note also that it may just be that your example does not need objects
at all.  This kind of by-case reasonning is often better handled by
simple sum types.

Cheers,

        Jacques
-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners