Julien Roussel wrote:
Akim Demaille <akim(a)epita.fr> disait le 09/01/04
que :
>>>>"Théo" == Thierry GERAUD <theo(a)lrde.epita.fr> writes:
>
> > vous récupérez l'archive compgen (elle existait sous ce nom sous
prcs
;
sinon vous la trouverez ici :
/mnt/doc/langs/bench/compgen.tgz),
vous la jouez et vous pouvez poster vos benchmarks.
svn co
https://svn.lrde.epita.fr/genericity-support-comparison
svn co
https://svn.lrde.epita.fr/svn/genericity-support-comparison
plutôt !
rappel historique (pour les anciens) ou info (pour les moins
anciens) :
1.
point de départ =
on veut des algos génériques (1 implémentation pour des entrées
de nature variée mais qui conviennent)
2.
pour le C et le C++ =
il existe plusieurs approches (paradigmes de programmation) ; elles
sont récapitulées ici :
http://www.lrde.epita.fr/cgi-bin/twiki/view/Publications/200102-Ai
(lire les slides suffit)
et dans le projet genericity-support-comparison avec une version
supplémentaire : l'utilisation des macros en C pour avoir du code
générique fortement typé (sans void*)
Depuis 2001, nous savons qu'il y a plusieurs façons d'être statiques
en C++ ; notre choix s'est porté vers SCOOP parce que nous voulions
représenter des abstractions avec la notion de classes et d'héritage.
On a bcp travaillé pour arriver à des caractéristiques sympatiques
de ce formalisme : plusieurs façons d'avoir des hiérarchies statiques
ont été explorées et étudiées (Cf. rapport de Raph) et ont donné
lieu à plusieurs évolutions de la façon de coder dans olena. Ceux
qui étaient là à ce moment pourront témoigner que les
modifications de oln/core/ n'ont entraîné que des modifications
*légères* des autres répertoires (des routines de traitement).
On voulait s'éloigner du typage structurel du paradigme de la C++ std
lib. Pourquoi : on *sait* nommer les abstractions, on veut contraindre
les signatures de routines (msg d'err plus clairs), surcharger les
routines (point très important !) + cela permet d'éviter à l'utilisateur
qui souhaite fournir une routine de devoir faire de la méta-prog
pour écrire des disjonctions d'implémentation (la méta-prog est
repoussée dans oln/core/) + le "simple" utilisateur (celui qui se
contente d'appeler des routines déjà écrites) a l'impression de
travailler en C. Bref, que des avantages du côté utilisateur.
En 2003-2004, on obtient SCOOP qui répond à nos attentes : ça y est
on a un modèle objet statique avec des fonctionnalités supplémentaires
par rapport à l'objet classique (covariance, multi-méthodes, etc.)
*La* fonctionnalité importante qui nous manque encore est la gestion
de plusieurs discriminants orthogonaux pour une hiérarchie. J'insiste
sur le *la* : il s'agit bien de l'unique fonctionnalité manquante à
nos désirs d'écriture générique et de simplicité pour l'utilisateur.
Pour comprendre, il faut savoir que des envies sur une olena
idéale ont été exprimées très tôt (il y a plusieurs années) mais
que leur expression n'a pas été systématiquement *écrite* et n'a
pas été renouvelée régulièrement ; par exemple : à quoi bon parler
du problème des discriminants tant qu'on était incapable d'écrire
une (simple) hiérarchie statique, etc.
Toujours pour préciser, il y a de nombreuses fonctionnalités "de
base" qui manquent toujours à olena mais à quoi bon les implémenter
tant qu'il y a bcp plus important à faire.
Enfin, réussir à gérer ce qui semble être *une* hiérarchie derrière
l'abstraction de plus niveau (abstract::image) sachant qu'il y a
en fait plusieurs abstractions orthogonales n'a pu être rendu possible
que grâce à l'augmentation progressive de notre savoir-faire en
programmation statique en C++. On dépasse ici largement le paradigme
des objets.
Il se trouve que l'approche par "propriétés", qui permet d'écrire ce
que l'on veut, simplifie grandement l'écriture de oln/core/ (pour un
aperçu de ce que j'avance, une preuve de concept en fait), vous pouvez
aller regarder ~theo/temp/oln-proto.tgz C'est pas du code très propre,
il est très criticable, incomplet par rapport à ce que l'on a déjà
mais c'est un début. A titre d'exemple : ajouter la partie 1d m'a pris
moins de 2h, ajouter un morpheur prend environ 20 lignes de code...
3.
pour d'autres langages =
Cf. le projet genericity-support-comparison
Conclusion :
Si on veut/doit se poser des questions sur olena en tant que
bibliothèque générique en C++, il faut d'abord lister les
caractéristiques et fonctionnalités attendues de ce projet.
C'est le second point prioritaire de ma /to-do-list/.
"Se poser des questions" se comprend au sens large. Plusieurs
illustrations suivent.
- Si en C non générique, on est 20% plus rapide, ce n'est pas donc
mieux car on a 0/20 sur l'évaluation de la généricité. Vous
remplacez "généricité" par autre chose, vous en arrivez à la
même conclusion.
Ce point, comme tous les autres d'ailleurs, peut être discuté.
Vous pouvez bien sûr ne pas être d'accord sur un "trait" attendu
d'olena et donc mettre en perspective / critiquer ce que l'on
est en train de faire. Exemple : la généricité n'est pas si
utile que ça (idem avec la surcharge, les morpheurs) ; mais
apportez vos arguments, vos justifications.
- Si on trouve qu'olena n'est pas idéale pour prototyper, c'est
normal. On fournit (pour l'instant) une /bibliothèque/ de
routines et on n'a pas passé assez de temps sur l'aspect
"interface" (graphique ou commande en ligne ou interpréteur,
etc.) Pourquoi rejeter / critiquer une bibliothèque en la
considérant pour ce qu'elle n'est pas ?
Pour ceux que ce sujet intéresse, il faut se souvenir que
Jérôme avait fait très vite un travail sur l'interfaçage avec
Octave (Matlab-like) et il faut savoir que, maintenant, on
peut s'inspirer de projets tels que
http://lnc.usc.edu/~holt/matwrap/index.html
si jamais on veut s'interfacer.
- Si vous trouver un langage ou un outil qui nous permette
d'être aussi générique et rapide qu'olena, très bien. Mais
faites de vrais tests, des tests pertinents. Ca nous sera
utile et votre travail sera béni.
Dans le projet genericity-support-comparison (qui date d'il
y a 3 ans) vous trouverez en filigrane une routine simple
pour effectuer vos tests. Avec le recul, je voudrais
seulement la généraliser un peu plus : le but est de faire un
map (au sens fonctionnel du terme) en passant une fonction.
En "C++ std lib"-like, ça donnerait :
template <typename I, typename F>
O map(const I& in, F fun)
{
O out(in.size());
typename I::iter_type p(in.size());
for_all(p)
out[p] = fun(in[p]);
return out;
} // il reste à exprimer O...
Merci d'avoir lu ; à vous de jouer si vous le voulez bien.
Je suis ouvert à toute discussion à partir de mi-septembre
(avant = booké).