From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id KAA29442 for caml-red; Thu, 11 Jan 2001 10:32:32 +0100 (MET) Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id KAA27664 for ; Thu, 11 Jan 2001 10:08:01 +0100 (MET) Received: from mail.pi.se (mail.pi.se [195.7.64.8]) by concorde.inria.fr (8.11.1/8.10.0) with ESMTP id f0B97xj10467 for ; Thu, 11 Jan 2001 10:08:00 +0100 (MET) Received: from gateway ([195.7.85.166]) by mail.pi.se (8.8.8/8.8.8) with SMTP id KAA05760; Thu, 11 Jan 2001 10:07:40 +0100 (MET) From: "Mattias Waldau" To: "Brian Rogoff" , "Mattias Waldau" Cc: "Caml-List" Subject: RE: Why can't I use val mover : < move : int -> unit; .. > list -> unit ? Date: Thu, 11 Jan 2001 10:07:33 +0100 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 In-Reply-To: Sender: weis@pauillac.inria.fr I understand the principle that the compiler must be sure that everywhere I use the list, the elements will be of the right type. In this case each element must have the method move. However, it seems to me that in this case the compiler has already done the complex part, i.e. realizing that if all objects have a move-method, then everything is ok. So I don't see the point that I have to coerce explicitily when putting elements into the list. In general I don't see the difference to when I call the function main. Why isn't a coerce necessary here? let main x = x#move 3 let p = new p1d_2 type m = < move : int -> unit > let _ = main ( q :> m ) (* <== WHY ISN'T THIS NEEDED? *) Also, I would be interested in how Ocaml can make the call within main and mover to move efficiently. Other static compiled OO-languages use vtables, but I don't see how Ocaml can use a vtable. How expensive are these methods calls? There are no numbers of this in the Ocaml-FAQ /mattias -----Original Message----- From: Brian Rogoff [mailto:bpr@best.com] Sent: Wednesday, January 10, 2001 8:16 PM To: Mattias Waldau Cc: Caml-List Subject: Re: Why can't I use val mover : < move : int -> unit; .. > list -> unit ? On Wed, 10 Jan 2001, Mattias Waldau wrote: > In the example below I have two separate classes with no common > super class. Both classes have a method 'move'. > > I have no problem using the function main below that can an > arbitrary 'objects with move defined'. However, when I try to > expand the example to list of objects with move defined, I > cannot use this function. The problem is sticking the objects into the list, not the function "mover". Ocaml row polymorphism is a bit different than the OO you're probably used to; you need to coerce the objects to the common supertype before you put them in the list, so that they'll have the same type. Try something like this type t = < move : int -> unit > let _ = mover [(p :> t) ; (q :> t)] (* Don't forget the parens! *) You can write collection building functions which do this coercion for you. Hope this helps... -- Brian > > How can I use the function 'mover'? How do I coerce to > objects with move defined? > > /mattias > > > > > (* > > let _ = mover [p;q] > > This expression has type p1d_1 = < move : int -> unit > > but is here used with type > p1d_2 = < move : int -> unit; only_here : int -> int > > Only the second object type has a method only_here > > *) > > > class p1d_1 = > object > val mutable x = 0 > method move d = x <- x + d > end > > class p1d_2 = > object > val mutable x = 0 > method move d = x <- x + d > method only_here x = x + x > end > > let main x = > x#move 3 > > > let q = new p1d_1 > let p = new p1d_2 > > let _ = main q > let _ = main p > > > let mover l = List.iter (fun x -> x#move 10) l > > (* let _ = mover [p;q] *) > > > (* > class p1d_1 : object val mutable x : int method move : int -> unit end > class p1d_2 : > object > val mutable x : int > method move : int -> unit > method only_here : int -> int > end > val main : < move : int -> 'a; .. > -> 'a = > val q : p1d_1 = > val p : p1d_2 = > val mover : < move : int -> unit; .. > list -> unit = > > *) > >