tsp-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: RE : [Tsp-devel] Troll sur languages de script


From: Stephane Galles
Subject: Re: RE : [Tsp-devel] Troll sur languages de script
Date: Fri, 14 Apr 2006 18:36:04 -0400
User-agent: Mozilla/5.0 (Linux Firefox)



Erk wrote:
[...]

Ce que je voulais illustrer (mais très mal je te l'accorde)
c'est que lorsque la méthode elle-même
est un objet alors on se retrouve avec un objet "appelable"
dont le premier paramètre n'est même pas visible.

on ne fait myobj.b()
mais juste
b()

c'est comme si l'objet destinataire du message avait disparu.
Ha OK. I get your point. C'est vrai que ce n'est pas moins object puisque
comportement et données restent reliées.

[...]

Que faire de
a.method(b)?


A est toujours le seul et unique destinataire du message method.
B est un paramètre, pas un destinataire.

Sauf si "method" est un operateur....mais tu en parle après
Sauf également quand il se trouve que:

a.method(b) fasse en fasse en fait
b.visit(this) (ou this == a)

et tu reconnaitras le pattern du visiteur qui sert
justement à implémenter un double dispatch
quand on ne dispose que du single dispatch objet.

est-ce que ça aurait été moins objet de faire
visit(a,b)
surement.
Est-ce que c'est plus simple à implémenter sous
forme fonctionnelle pure qu'avec un visiteur
personnellement je pense que oui.
Oui, c'est vrai, je comprends ce que tu veux dire maintenant. D'ailleurs ce que tu me dis m'éclaire sur quelque chose qui m'avais toujours intrigué : le pattern visiteur m'a toujours semblé "suspect", bien qu'utile. J'avais cette sensation que la classe qui implémente le 2eme dispatch tendais à décentraliser du code de manière un peu suspecte. En reliant cela à ton explication, je comprend que parfois cette décentralisation est nécessaire et que le double dispatch
est un contournement...pour arriver à faire du procédural !

La différence est majeure me semble - il:
lorsque A.method(B) est executé, A a la responsabilité de l'execution de
la méthode.
Cela me communique que l'unité de traitement pour la méthode est dans A,
pas dans B.
Ce me communique également que lors du traitement A.method(B) les
interfaces publiques
et privées de A vont être impliquées, mais seule l'interface publique de
B peut être impliquée.
Enfin cela me communique que le message 'method' a surement plus de lien
avec les
données de a que celle de b (en partant du principe que l'objet A est un
bon objet :  à savoir
on a regroupé le traitement et les données sur lesquelles agissent les
traitements :
c.f : GRASP Pattern "Information Expert" :
http://people.msoe.edu/~blessing/cs489/cs489-13ch18.pdf

je vais lire ça tranquillement.
Maintenant que je comprend ce que tu voulais dire, oublie le paragraphe
précédent. J'enfonce une porte ouvert, et en plus je me rend compte que dans
le cas du double dispatch, le GRASP Pattern , c'est typiquement
ce que l'on essaie de contourner. Autrement dit, ce qui est généralement
un avantage de l'objet, je comprends que dans ce cas cela ce met en travers du chemin.

Mais mon idée était que pour les méthodes qui prennent plusieurs
paramètres je trouve que ce n'est pas toujours évident
de trouver qui est le "meilleur" destinataire.

Ensuite il y a des catégories d'algorithmes qui s'implémentent
naturellement avec des fonctions pures.
Max, Min, Find (en gros des opérations sur des collections).

On peut évidemment créer des objets collections qui contiennent
ces méthodes mais c'est sincèrement relativement artificiel.
Je préfère un algo fontionnel qui prend en paramètres quelques
itérateurs, comme celà est fait dans la STL.
http://www.sgi.com/tech/stl/

Effectivement, dans le meilleurs des cas "objet", on se retrouve à implémenter une classe comparateur (qui n'a pas d'état interne) que l'on passe à l'algo de tri. On manipule des functor si on est objet, mais l'approche reste avant tout fonctionnel en fait.

ou même
a+b
ou encore
a+b+c+d


Ce sont des cas particulier : celui où les objets sont du même
type, et que l'opérateur est commutatif.

objets du même type je ne suis pas d'accord.
je peux vouloir ajouter un vecteur à un point et
cela me donnera un point.
un vecteur à un vecteur et j'aurais un vecteur.
Donc je dois implémenter des 2 operations d'additions
dans vecteur et dans point?
Que se passera-t-il quand j'aurais une nouvelle classe
(pas prévue) dont les objets sont susceptibles de s'additionner
avec mes anciens Vecteur et Point?
je pourrais faire:
NewVecteur+Point
et
NewVecteur+Vecteur
mais probablement pas
Vecteur+NewVecteur (sans modifier l'ancienne classe)

En C++ tu pourrais définir une fonction template
(non attachée à une classe) et faire de la spécialisation partielle.
(dans le cas des types diffrents)
ou utiliser des 'traits'.
http://www.cantrip.org/traits.html


Rien à dire.

On ne peux pas généraliser avec ça.

Je suis d'accord c'est un peu spécial, mais ça arrive
quand le côté "fonctionnel" de la méthode profiterait
à ne pas être attaché à une classe/objet particulier.

Toujours rien à dire. Et oublie mon "on ne peut pas généraliser"
je comprend maintenant que tu voulais justement m'orienter sur
des exemples où l'approche objet se met en travers du chemin.

a.method(b,c,d);
c'est pas mieux
somme(a,b,c,d)?


Encore un fois, somme(a,b,c,d) est un cas particulier où a, b, c et d
ont vraissemblablement le même poids vis à vis du traitement.

Oui l'important ici c'est la somme pas a,b,c,b
et ça se généralise à d'autre opérations du genre accumulation.
http://www.sgi.com/tech/stl/accumulate.html

Oui, si j'avais mieux relu ma propre phrase j'aurais vu que ce tu essayais de m'expliquer se trouvait dedans. L'idée de l'approche objet est que on regroupe les données, et qu'on ajouter dessus les fonction à partir du constat que dans la plupart des cas les regroupements de données sont plus stables que les regroupements de fonction. Hors, dans les exemples que tu donnes, on touche à la limite de cette approche car comme tu dis, dans ce cas ce sont les fonctions, pas les données qui sont le point central (les données
"tournent autour" si on peut dire)

Hum... Sincèrement, tes explications m'éclairent beaucoup sur le sujet de la limite de l'approche objet. Je vais creuser la question pour ma culture personnelle.

[...]

alors qu'on pourrait faire du "multiple dispatch"
pour aboutir à une multiméthode
http://c2.com/cgi/wiki?GenericFunction
ce qui est bien sûr faisable en quelques lignes écrite de sang froid:
http://www.artima.com/weblogs/viewpost.jsp?thread=101605


Hum... j'ai comme l'impression qu'on perd alors la notion
d'encapsulation et
de cohésion qui fait l'intéret de l'objet : on a séparé données et
traitement.
(style 'friend' du C++). Mais bon, j'imagine que cela doit avoir
des cas d'utilisation

Les cas que je connais sont surtout dans le domaine numériques
ou les objets sont des points, vecteurs, matrices  etc... et les méthodes
des opérations sur ces objets.
Le single dispatch devient réellement pénible quand tu as une hiérarchie
de matrice et que tu veux avoir une méthode polymorphe qui fait

A = B*C+D


C'est sincèrement pénible ou au minimum TRES inéfficace quand
tu veux optimiser les objets temporaires ou éviter les calculs inutile.

Un exemple simple, le produit scalaire de 2 vecteurs V1 et V2.
V1 et V2 font la même taille sauf que V2 est "creux" c'est à dire que
c'est une sous-classe de Vecteur qui est optimisé parce qu'on sait
qu'il contient une majorité d'éléments nuls.

si je fais
1) a= V1.scalaire(V2);
ou
2) a=V2.scalaire(V1);

dans 1) je vais faire une boucle sur 1000 éléments alors
que 2) ne fera qu'une boucle sur les éléments non nul
de V2.

Une bonne fonction:

a= prod_scalaire(V1,V2);

s'arrangera pour TOUJOURS exécuter la version la moins chère.

Rien à dire de nouveau. Le fait est que n'ayant jamais eu à implémenter
ce genre de chose je n'ai jamais recontré ce problème et ai sous estimé
l'importance de ce genre de cas.
Je vais relire les liens que tu donnes intéret.

[...]

Pour l'instant je regarde du coté de Ruby

[...]

Après
tout je peux toujours
changer d'avis après l'avoir vraiment pratiqué !

Pareil pour moi pour Python je pourrais changer
après avoir vraiment pratiqué.


Mon objectif global n'était d'ailleur pas tant de justifier
les "erreurs" d'API foncitonnelle de Python mais plutot
de remarquer que le "tout objet" n'est parfois pas la meilleure
solution. Donc un langage objet qui permet de faire un peu
de fonctonnel/procédural me parait bien sympathique.
Oui, et merci pour tes explications je dois avouer que cela m'a été grandement utile.

Ce n'est pas un très bon Troll en fait. personnellement j'ai apris des choses, et en plus personne ne s'est insulté. Il va falloir qu'on travaille si un veut faire
de vrais Troll. :)

Steph

J'ai écris ce mail en 3 fois donc je m'excuse d'avance
des ruptures de sens :))
--
Erk


_______________________________________________
Tsp-devel mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/tsp-devel







reply via email to

[Prev in Thread] Current Thread [Next in Thread]