Version française
Home     About     Download     Resources     Contact us    
Browse thread
Why can't I use val mover : < move : int -> unit; .. > list -> unit ?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Mattias Waldau <mattias.waldau@t...>
Subject: RE: Why can't I use val mover : < move : int -> unit; .. > list -> unit ?
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 = <fun>
> val q : p1d_1 = <obj>
> val p : p1d_2 = <obj>
> val mover : < move : int -> unit; .. > list -> unit = <fun>
>
> *)
>
>