Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: porte des definitions des variables de classe
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Pierre Weis <Pierre.Weis@i...>
Subject: Re: porte des definitions des variables de classe
> Sylvain BOULM'E wrote:
> 
> > Bonjour,
> >
> > Il me semble que c'est dans la semantique des classes
> > de Ocaml, qui supportent desormais les "variables statiques de classes"
> > partagees par tous les objets de la classe. (Les gens de Ocaml me
> > corrigeront ...)
> >
> > Ainsi,
> >
> > class test1 =
> > object
> >     val v = ref 5
> >     method get = !v
> >     method set x = v:=x
> > end;;
> >
> > est equivalent a
> >
> > class test1 = let v1=ref 5 in
> > object
> >     val v=v1
> >     ...
> >
> > Dans les 2 cas,
> >
> > let a=new test1 and b=new test1 in (b#set 4; a#get);;
> >
> > retourne 4.
> >
> 
> Effectivement, OCaml-2.0 semble fonctionné suivant ce schéma.
> Je trouve cette "nouveauté" embarrassante:

Je ne comprends pas le problème: cela ressemble fort à la sémantique
habituelle du Caml de base...

> - elle est ambigue;

Je ne vois pas non plus en quoi elle l'est. Je ne connais pas grand
chose aux objets mais ce comportement était celui que je prévoyais:
la référence ref 5 est partagée dans les deux cas, comme dans le
langage de base ...

> Cela va a l'encontre du "sens commun". Les variables d'instance sont
> declarees dans "object": je m'attends donc a ce que la porté de la variable
> soit locale à une instance de la classe.

C'est le cas. Je ne comprends pas. Ne confondez-vous pas partage des
valeurs et portée des identificateurs ou variables ?

> Lorsque je declare:
> 
> class test1 =
> object
>     val v = ref 5
>     method get = !v
>     method set x = v:=x
> end;;
> 
> je m'attends a ce que la variable v soit locale à chaque nouvel objet
> construit à partir de (new test1).

C'est le cas. Seulement vous avez tout fait pour partager la référence
ref 5: pas de paramètre à la classe donc calcul fait une fois pour
toutes donc allocation unique donc partage. À quoi d'autre
pourrions-nous nous attendre ?

> D'ailleurs, il est confondant de voir que la déclaration suivante:
> 
> class test3 =
> object
>     val mutable v = 5
>     method get = v
>     method set x = v<-x
> end;;
> 
> se comporte différement de test1 !

Absolument pas. Il est rassurant que ça se comporte d'une façon
différente, puisque maintenant la variable v est mutable!

> - elle n'est pas consistante
> Rien ne me previent du changement de fonctionnalité dans ce cas
> particulier.

Bien sûr que si: c'est cohérent car compatible avec toute la
sémantique du langage de base (donc in fine avec celle de la réduction
faible du lambda-calcul en appel par valeur). Enfin tout vous prévient
de la différence entre les exemples: la présence du mot-clé mutable,
l'absence de paramètre à la classe, le let ... in pour la deuxième
version. 

> Il suffit de supprimer ou d'ajouter un paramètre à une classe pour en changer
> complètement la sémantique.
> Si je redefinis test1 :
> 
> class test1 (x:int) =
> object
>     val v = ref x
>     method get = !v
>     method set x = v:=x
> end;;
> 
> alors la variable v n'est plus partagée...

Bien entendu. Rien d'étonnant là-dedans. Avez-vous remarqué combien la
sémantique d'une fonction change quand on modifie son nombre de
paramètres ? En particulier lorsqu'une fonction passe de 1 à zéro
paramètres comme c'est le cas ici ?

Comparez par exemple:

let f () = exit 0;;

let f = exit 0;;

Vous devriez observer une différence de sémantique certaine. Remplacez
classe par fonction dans votre phrase et vous obtenez:

``Il suffit de supprimer ou d'ajouter un paramètre à une fonction pour
en changer complètement la sémantique.''

Il me semble que ce problème de paramètre ajouté ou suprimé est
général à beaucoup de constructions du langage.

Blague: disons-le en Caml !

let étonnement = function construction ->
  "Il suffit de supprimer ou d'ajouter un paramètre à " ^ construction ^
  " pour en changer complètement la sémantique.";;

étonnement "une classe";;
étonnement "une fonction";;
étonnement "un module";;
étonnement "un foncteur";;
étonnement "un type";;

etc..

> - elle n'est pas necessaire;
> Si on en a besoin, on peut simplement partager des variables "statiques"
> entre différentes instances de la meme classe.

Je laisse la parole aux spécialistes des objets.

> Enfin c'est mon avis d'utilisateur.

Et il est très intéressant. Merci de nous le faire partager. Je crois
qu'il montre aux implémenteurs de Caml qu'il y a sans doute un décifit
d'explications sur le langage en général et sur ses objets en particulier.

> Pour la petite histoire, il m'a fallu
> tout un weekend pour comprendre pourquoi mon code ne marchait plus sous
> OCaml-2.0, alors que la version 1.07 marche tres bien...

Peut-être encore ce déficit d'explications ...

> Objectivement votre,
> 
>     Serge Fantino

Cordialement,

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/