caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Coercion of arrays of objects (and some other containers)
@ 2005-04-13  0:14 Martin Jambon
  2005-04-13  0:49 ` [Caml-list] " Olivier Andrieu
  2005-04-13  0:59 ` Jacques Garrigue
  0 siblings, 2 replies; 5+ messages in thread
From: Martin Jambon @ 2005-04-13  0:14 UTC (permalink / raw)
  To: caml-list

Here is my problem:

# let obj =
object
  method a = ()
  method b = ()
end;;
        val obj : < a : unit; b : unit > = <obj>

(* That is nice: *)
# ([ obj ] :> < a : unit > list);;
- : < a : unit > list = [<obj>]

(* But why doesn't it work with arrays? *)
# ([| obj |] :> < a : unit > array);;
Characters 1-10:
  ([| obj |] :> < a : unit > array);;
   ^^^^^^^^^
This expression cannot be coerced to type < a : unit > array; it has type
  < a : unit; b : unit > array
but is here used with type < a : unit > array
Only the first object type has a method b


In practice I have this problem with a hash table of objects, and I
expected it to work since it works fine with lists of the same
type of objects...
Is there any workaround?

Martin

--
Martin Jambon, PhD
http://martin.jambon.free.fr



^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Coercion of arrays of objects (and some other containers)
  2005-04-13  0:14 Coercion of arrays of objects (and some other containers) Martin Jambon
@ 2005-04-13  0:49 ` Olivier Andrieu
  2005-04-13  0:59 ` Jacques Garrigue
  1 sibling, 0 replies; 5+ messages in thread
From: Olivier Andrieu @ 2005-04-13  0:49 UTC (permalink / raw)
  To: martin_jambon; +Cc: caml-list

Salut Martin,

 > Martin Jambon [Tue, 12 Apr 2005]:
 > Here is my problem:
 > 
 > # let obj =
 > object
 >   method a = ()
 >   method b = ()
 > end;;
 >         val obj : < a : unit; b : unit > = <obj>
 > 
 > (* That is nice: *)
 > # ([ obj ] :> < a : unit > list);;
 > - : < a : unit > list = [<obj>]
 > 
 > (* But why doesn't it work with arrays? *)
 > # ([| obj |] :> < a : unit > array);;
 > Characters 1-10:
 >   ([| obj |] :> < a : unit > array);;
 >    ^^^^^^^^^
 > This expression cannot be coerced to type < a : unit > array; it has type
 >   < a : unit; b : unit > array
 > but is here used with type < a : unit > array
 > Only the first object type has a method b

It's a variance problem : a list is covariant so the coercion
works. But an array is invariant (because of the Array.set
operations).

Otherwise after coercion you would be able to do store in the array an
object without a `b' method, this object being also reachable through
the original array.

 > In practice I have this problem with a hash table of objects, and I
 > expected it to work since it works fine with lists of the same
 > type of objects...
 > Is there any workaround?

Maybe this :

  Array.map (fun o -> (o :> < a : unit >)) [| obj |] 

-- 
   Olivier


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Coercion of arrays of objects (and some other containers)
  2005-04-13  0:14 Coercion of arrays of objects (and some other containers) Martin Jambon
  2005-04-13  0:49 ` [Caml-list] " Olivier Andrieu
@ 2005-04-13  0:59 ` Jacques Garrigue
  2005-04-13  6:37   ` Matthieu Dubuget
  1 sibling, 1 reply; 5+ messages in thread
From: Jacques Garrigue @ 2005-04-13  0:59 UTC (permalink / raw)
  To: martin_jambon; +Cc: caml-list

From: Martin Jambon <martin_jambon@emailuser.net>

> Here is my problem:
> 
> # let obj =
> object
>   method a = ()
>   method b = ()
> end;;
>         val obj : < a : unit; b : unit > = <obj>
> 
> (* That is nice: *)
> # ([ obj ] :> < a : unit > list);;
> - : < a : unit > list = [<obj>]
> 
> (* But why doesn't it work with arrays? *)
> # ([| obj |] :> < a : unit > array);;
> Characters 1-10:
>   ([| obj |] :> < a : unit > array);;
>    ^^^^^^^^^
> This expression cannot be coerced to type < a : unit > array; it has type
>   < a : unit; b : unit > array
> but is here used with type < a : unit > array
> Only the first object type has a method b

Suppose that it worked.
Then you could have this scenario.
  let arr = [|obj|];;
  let arr' = (arr :> <a:unit> array);;
  arr'.(0) <- object method a = () end;;
  arr.(0)#b;;
  Segmentation fault.

Such subtyping is allowed in Java, but this is an unsafe part of the
type system, which requires time-consuming runtime checks.

> In practice I have this problem with a hash table of objects, and I
> expected it to work since it works fine with lists of the same
> type of objects...
> Is there any workaround?

If you don't need to add objects to this hash table, this is possible
with the following approach:

  class ['a,+'b] table tbl =
    object
      val tbl : ('a,'b) Hashtbl.t = tbl
      method find = Hashtbl.find tbl
      method find_all = Hashtbl.find_all tbl
      method mem = Hashtbl.mem tbl
    end
  (* class ['a, 'b] table :
    ('a, 'b) Hashtbl.t ->
    object
      val tbl : ('a, 'b) Hashtbl.t
      method find : 'a -> 'b
      method find_all : 'a -> 'b list
      method mem : 'a -> bool
    end *)
  let coerce tbl = (tbl : ('a,<a:int;b:int>) table :> ('a,<a:int>) table)

See that 'b appears only in covariant positions, allowing its
subtyping.

Jacques Garrigue


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Coercion of arrays of objects (and some other containers)
  2005-04-13  0:59 ` Jacques Garrigue
@ 2005-04-13  6:37   ` Matthieu Dubuget
  2005-04-13 14:11     ` Olivier Andrieu
  0 siblings, 1 reply; 5+ messages in thread
From: Matthieu Dubuget @ 2005-04-13  6:37 UTC (permalink / raw)
  To: caml-list

I'm sorry, but I feel stupid.

The variance and covariance terms/notions appear often in this list, and 
seems to be very basic notions.

I tried to find explanation on internet but did not succeed.

Could somebody point me some links  to understand, please?

Thanks in advance

Salutations

Matthieu


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Caml-list] Coercion of arrays of objects (and some other containers)
  2005-04-13  6:37   ` Matthieu Dubuget
@ 2005-04-13 14:11     ` Olivier Andrieu
  0 siblings, 0 replies; 5+ messages in thread
From: Olivier Andrieu @ 2005-04-13 14:11 UTC (permalink / raw)
  To: matthieu.dubuget; +Cc: caml-list

 Matthieu Dubuget [Wed, 13 Apr 2005]:
 > I'm sorry, but I feel stupid.
 > 
 > The variance and covariance terms/notions appear often in this
 > list, and seems to be very basic notions.
 > 
 > I tried to find explanation on internet but did not succeed.
 > 
 > Could somebody point me some links  to understand, please?

I do not have a link but the idea (as I understand it) is simple :

This concerns parameterized types ('a t) and how a subtyping relation
on the parameter can yield a subtyping relation on the type.

When the parameter is covariant :
  if a is a subtype of b then a t is a subtype of b t

When the parameter is contravariant :
  if a is a subtype of b then b t is a subtype of a t

For instance lists are covariant. [`A|`B|`C] is a supertype of [`A|`B]
so a [`A|`B|`C] list is a supertype of [`A|`B] list.

Function arguments are contravariant : ([`A|`B] -> unit) is a
supertype of ([`A|`B|`C] -> unit). When you have a function that
accepts A B or C, you can also view it as a function that accepts just
A or B (qui peut le plus peut le moins).

Records with mutable fields (or arrays) are neither covariant nor
contravariant. 

Well maybe my terminology isn't quite correct but I hope you get the
idea.

-- 
   Olivier


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-04-13 14:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-04-13  0:14 Coercion of arrays of objects (and some other containers) Martin Jambon
2005-04-13  0:49 ` [Caml-list] " Olivier Andrieu
2005-04-13  0:59 ` Jacques Garrigue
2005-04-13  6:37   ` Matthieu Dubuget
2005-04-13 14:11     ` Olivier Andrieu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).