32Fermer34
PolluxLe 13/05/2008 à 12:02
PpHd (./31) :
Pollux (./29) :
- Je viens de regarder may_subs_c, déjà il y a un gros problème c'est que le namespace des fonctions et des variables est le même : si je fais un subs sur l'expression digamma+1 ça va planter
Non. Il ne se passera rien. Car digamma est une expression et tu as fourni à subs une fonction de ce nom. Donc il ne fera pas le remplacement.

Alors j'ai pas dû comprendre comment on s'en sert, tu pourrais écrire un exemple d'utilisation ?
Pollux (./29) :
- Je pensais plutôt au cas où c'est non pas l'utilisateur final (= programme Basic) qui l'utilise, mais un programme écrit en C appelant MAY directement et définissant des fonctions comme digamma pour son usage interne. Peut-être que tu veux plutôt qu'on définisse une extension dans ce cas-là en fait ?

A mon avis, la meilleure facon d'implanter çà efficacement (une vrai fonction, avec une dérivée, et tout, et tout), est de faire une classe d'extension regroupant toutes tes fonctions.
L'enfant 1 est un entier indiquant le numéro de la fonction (0->digamma, 1 ->besselJ, ...)
L'enfant 2 est l'argument de la fonction.
Tu parses ton expression SANS l'évaluer. Puis tu fais un subs_c avec toutes ces nouvelles fonctions, pour les remplacer par les extensions.
Puis tu fais un éval de ton expression (avec tes extensions).
Avec cette méthode, même si un digamma interne apparait, ton digamma reste prioritaire smile

OK, mais du coup il faut faire ton propre affichage, et surtout il faut refaire un parseur from scratch non ?
Pollux (./29) :
Je crois que c'est important de faire le parallèle entre put_string() et la fonction qui put() un objet arbitraire ^^
Ok

Et tu devrais éviter de parler de buffer interne : après tout, si on affiche directement sur stdout, il n'y aura pas de buffer interne... Peut-être aussi que convert2str n'est pas un nom idéal, un truc genre display() ou stringify() serait plus générique et plus proche des autres noms de fonction ?
Pollux (./30) :
- Ah oui, mais selon la doc bar ne devient pas entièrement invalide dans le premier cas puisqu'on peut encore l'évaluer ?!?
Oui. C'est la seule chose possible restante.

Alors il faut aussi préciser que ça reste valide aussi si on avait construit une autre expression non évaluée qui dépend d'elle : même si on n'évalue pas bar il reste bien valide. Par contre si je comprends bien on n'a plus le droit d'appeler un constructeur non évalué avec cette expression en paramètre ?
(et c'est quoi le rationale de ce truc-là ?)
Pollux (./30) :
- Ce serait possible de formaliser toutes les exigences des extensions pour qu'elles puissent maintenir ce genre d'invariants ? Là ça me paraît très très fragile, c'est à peu près certain que la première extension venue cassera tout si elle a une structure récursive...

Je ne pense pas que ca soit si fragile. En général, une forme _c ne vit pas très longtemps et tu l'évalues très rapidement (parce qu'autrement tu ne peux pas faire grand chose dessus).
De toute façon, si tu as les assertions activées, MAYLIB te lachera une robustesse très vite normalement dans ce cas.
Que verrais-tu dans la doc ?

Ben je verrais une formalisation des garanties fournies par MAY et des exigences qu'elle pose sur les extensions, qui serait tout aussi complète que si tu voulais prouver avec un truc genre Coq la correction de tes transformations. Par exemple les axiomes de commutativité, de distributivité, d'élément neutre, absorbant, etc. Et tes assertions ne rattraperont pas le dixième des problèmes : par exemple j'écris une extension mais il y a un bug qui fait que si je multiplie par 0 je n'obtiens pas toujours 0 (*). Du coup 0 != eval(0*ext) = subs(e=ext, eval(0*e)) = subs(e=ext, 0) = 0. Et à moins que eval() soit purement bottom-up, le problème eval o foo_c o bar_c != foo o bar va aussi se poser...

(*) : ça peut au contraire être voulu, c'est par exemple ce que fait AMS avec les valeurs infinies : mais pour savoir à quoi s'attendre, c'est important de le définir dans un contrat


Est-ce que la commutativité pour la multiplication est adéquatement représentée par un flag statique ? Comment est-ce que tu décides si un arbre commute avec un autre ? Tu regardes si absolument toutes les feuilles des deux arbres commutent pour la multiplication ? Ca peut être trop prudent, par exemple si j'ai une fonction qui prend une matrice et qui me renvoie un nombre réel (genre le déterminant) le résultat sera commutatif même s'il utilise des matrices dans les feuilles.

Comment est-ce que tu évalues la commutativité multiplicative d'un identifiant ? S'il représente une matrice, ben ça commute pas...