Re: Ocaml et les objets

Francois Rouaix (Francois.Rouaix@inria.fr)
Thu, 05 Jun 1997 12:08:59 +0200

Message-Id: <199706051009.MAA30520@madiran.inria.fr>
From: Francois Rouaix <Francois.Rouaix@inria.fr>
To: Vyskocil Vladimir <vyskocil@math.unice.fr>
Subject: Re: Ocaml et les objets
Date: Thu, 05 Jun 1997 12:08:59 +0200

> Par exemple si l'on veut creer une liste qui
> contienne des objets derives d'un type parent il faut les "caster"
> en ce type parent mais ensuite comment les recuperer en tant qu'objets
> derives ?
Une fois qu'on a "oubli=E9" le vrai type d'un objet, on ne peut plus y
revenir, parce que le typage est statique. Redescendre dans la hi=E9rarch=
ie
des types imposerait une v=E9rification de type =E0 run-time.
Par contre, l'objet lui-m=EAme garde son type, et si cet objet a =E9t=E9 =
li=E9
avec son vrai type dans l'environnement, on y a toujours acc=E8s.
De plus, il ne faut pas oublier que le polymorphisme s'applique aussi
aux interfaces.

> J'ai essaye le package Obj avec notamment la fonction
> Obj.magic mais ca me parait un peu risque
En effet. Le syst=E8me de types est l=E0 pour garantir que le programmeur=

fait les choses proprement. Utiliser Obj.magic est une mauvaise id=E9e.

> et je n'arrive pas a faire une
> fonction qui puisse renvoyer un objet derive quelconque car justement i=
l
> n'ont pas des types compatibles,
Une fonction ne peut pas renvoyer des valeurs de type "variable", sauf
lorsqu'elle est polymorphe et qu'elle connait le vrai type en entree.

A mon avis, si on doit avec plusieurs objets de types differents (A, B, C=
)
mais dont l'interface a un sous-ensemble commun I, on peut tres bien les
mettre dans une liste et ensuite faire des traitements ou transformations=

sur cette liste pourvu que ces traitements soient en realite dans des
methodes des classes A, B et C. On peut meme avoir des methodes qui
"copient" des objets, comme dans l'exemple (incomplet) suivant:

let o1 =3D new A
and o2 =3D new B
and o3 =3D new C
let l =3D [(o1 :> I); (o2 :> I); (o3 :> I)]
let f l =3D List.map (fun o -> o#m)) l
let l' =3D f l

Ci-joint une version de ton exemple:

class virtual object (class_name : string) : 'a =3D
val name =3D class_name

method get_name =3D name
virtual m : 'a

and closed o_int (new_i : int) =3D
inherit object "o_int"
=

val i =3D new_i =

=

method get_value =3D i

method m =3D new o_int (i+1)

and closed o_float (new_f : float) =3D
inherit object "o_float"
=

val f =3D new_f =

method get_value =3D f

method m =3D new o_float (f+.1.0)

end

let o1=3Dnew o_int 1;;
let o2=3Dnew o_float 2.5;;
let l =3D [(o1 :> object); (o2 :> object)];;
(* val l : object list *)

let incremente l =3D List.map (fun o -> o#m) l;;
(* val incremente : < m : 'a; .. > list -> 'a list *)

let l' =3D incremente l;;
(* val l' : object list *)

--f