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 QAA16434 for caml-redistribution; Thu, 8 Oct 1998 16:36:05 +0200 (MET DST) Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id PAA27277 for ; Thu, 8 Oct 1998 15:43:51 +0200 (MET DST) Received: from mad.unice.fr (mad.unice.fr [134.59.10.81]) by nez-perce.inria.fr (8.8.7/8.8.7) with ESMTP id PAA27888; Thu, 8 Oct 1998 15:43:49 +0200 (MET DST) Received: from math.unice.fr (fantino@localhost [127.0.0.1]) by mad.unice.fr (8.8.7/8.8.7) with ESMTP id PAA06143; Thu, 8 Oct 1998 15:42:01 +0200 Sender: weis Message-ID: <361CC129.8F7CA6E3@math.unice.fr> Date: Thu, 08 Oct 1998 14:42:01 +0100 From: Serge Fantino Organization: Organization X-Mailer: Mozilla 4.05 [en] (X11; I; Linux 2.0.35 i686) MIME-Version: 1.0 To: Jerome Vouillon CC: caml-list@inria.fr, Vyskocil Vladimir Subject: Re: porte des definitions / initialisation des variables de classe References: <199810070730.JAA17668@pauillac.inria.fr> <361B6699.EFF02DF3@math.unice.fr> <19981007232533.54502@pauillac.inria.fr> Content-Type: text/plain; charset=iso-8859-1 Content-Transfer-Encoding: 8bit Jerome Vouillon wrote: > On Wed, Oct 07, 1998 at 02:03:21PM +0100, Serge Fantino wrote: > > Bon. Je vais essayer de vous faire sentir ce qui me gene sur un exemple: > > > > class test1 = > > object > > val x = Random.int 1000 > > method get = x > > end > > > > Je m'attends a ce que chaque nouvel objet cree a partir de test1 soit initialise > > avec une valeur différente pour x. > > En effet, l'initialisation est effectuee dans le corps de l'"object", elle ne > > devrait donc etre effectuee que lorsque j'instancie un nouvel objet. > > Le contenu des enregistrements (dans le language de base) et des > structures (dans le langage de module) est évalué. Il me paraît donc > naturel que ce soit également le cas pour "object ... end" dans le > langage de classe. > Ce qui est naturel, c'est que l'objet soit initialisé lorsqu'il est créé. Or l'objet est créé lorsqu'on appelle "new", pas lorsque l'on définit la classe... Que ce passe-t-il dans caml ? (j'espere que vous me corrigerez...) - "class xxx" définit la classe "xxx", qui n'est pas une valeur caml standard (elle vit dans l'espace des classes, avec un espace de nom séparé,...) - "class xxx" définit également un constructeur, qui est une fonction caml standard à valeur "object" - "new" est une fonction spéciale, définie de l'espace des classes dans l'espace des valeurs standards: elle associe à un nom de classe son constructeur, permettant d'instancier un nouvel objet Le fonctionnement normal d'un objet est donc le suivant: * les objets sont initialisés à chaque appel à "new" * les valeurs des variables d'instances sont a priori indépendantes (sauf si explicitement lors de l'instanciation JE décide de partager une valeur entre certains objets, OU si je définis le constructeur de classe de tel sorte qu'il définisse un environnement commun à tous les objets) Maintenant, examinons le cas où la classe est définie "sans paramètre": - le constructeur n'est pas une fonction à valeur "object" mais simplement une constante "object": l'objet est instancié lors de la définition de la classe - la fonction spéciale "new" retourne une copie de l'objet constant, ce qui a comme conséquences: * tous les objets de la classe sont initialisés avec les memes valeurs * toutes les valeurs "pointeurs" (array,hashtbl,ref,...) sont partagées par tous les objets de la classe (par contre les variables déclarées "mutable" sont indépendantes (?)) Est-ce que c'est correct ? Si oui, il me semble alors que la sémantique du langage est uniquement conditionnée par l'implémentation. Je ne vois aucune raison a priori pour que le mécanisme d'instanciation soit différent selon que la classe accepte ou non des paramètres. De plus je trouve anormal que la définition d'une classe puisse induire l'instanciation d'un objet: classes et objets "vivent" dans des espaces différents; seule la fonction spéciale "new" devrait permettre de passer de l'un à l'autre. Pour moi, l'implémentation de caml devrait vérifier: "les variables d'instances sont initialisées à chaque création d'un nouvel objet". Cela dit, je peux complètement me tromper, ne pas voir l'évidence, etre le seul à trouver le fonctionnement actuel "counter-intuitive". Cordialement, Serge Fantino PS: En OCaml-1.0x, la définition d'une classe sans paramètre était prohibée, ainsi que l'évaluation partielle des constructeurs: la raison de ce bridage (volontaire ?) n'était-elle pas d'éviter ce genre de problème ? > > Actuellement, que ce passe-t-il ? Si je declare la classe test3: > > > > class test3 range = > > object > > val x = Random.int range > > method get = x > > end > > > > alors chaque nouvelle instance est initialisée avec une valeur > > différente de \ x, ie l'initialisation est effectuée au moment de > > l'instanciation. > > > > Si je declare maintenant: > > class test3_1000 = test3 1000;; > > > > il est logique de s'attendre a ce que test3_1000 soit une classe > > specialisée de test3, fonctionnant de facon similaire a test3. Les > > expressions suivantes devraient retourner des resultats similaires, > > ie des valeurs différentes <1000 pour chaque instance: > > let l1 = List.map (fun _ -> (new test3 1000)#get) [0;0;0;0] > > let l2 = List.map (fun _ -> (new test3_1000)#get) [0;0;0;0] > > > > Helas, la liste l2 repete la meme valeur... pourquoi ? > > Je ne comprends pas trop pourquoi ce résultat te choque. Les arguments > que tu donnes pourraient tout aussi bien s'appliquer à l'exemple > suivant : > > type t = { x : int } > let test3 range = { x = Random.int range } > let test3_1000 = test3 1000 > let l1 = List.map (fun _ -> (test3 1000).x) [0;0;0;0] > let l2 = List.map (fun _ -> (test3_1000).x) [0;0;0;0] > > En fait, je crois que ce qui apparaît comme pas très intuitif est > que deux objets puissent partager une même valeur mutable. Mais c'est > également le cas lorsque l'on utilise Oo.copy ou {< ... >}. > > -- Jérôme