PpHd (./38) :
Pollux (./33) :
Alors j'ai pas dû comprendre comment on s'en sert, tu pourrais écrire un exemple d'utilisation ?
Si le pointeur que l'on donne pour remplacer l'expression est contenu dans la pile de MAY, c'est une expression => Donc on ne peut remplacer que des expressions avec. Si le pointeur que l'on donne pour remplacer l'expression n'est pas contenu dans la pile de MAY, c'est une fonction => Donc on ne peut remplacer que des fonctions avec.
OK, enfin c'est un tout petit peu crade quand même

Faut pas avoir envie d'allouer une zone de Data avec MAY pour mettre le code d'une fonction dedans

Et aussi c'est super crade de pas pouvoir faire la différence entre f(1,2) et f({1,2})

Pollux (./33) :
OK, mais du coup il faut faire ton propre affichage, et surtout il faut refaire un parseur from scratch non ?
Oui, mais comme on peut réutiliser le parseur précédent en grande partie, ce n'est pas si génant.
Comment ça ? Tu peux le réutiliser pour parser un flottant, oui, mais la structure arborescente tu es obligé de la recréer entièrement toi-même par exemple. Ou y a une API pour ça ?
Pollux (./33) :
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à ?)
C'est bien à cause de toutes ces complications que je sens que je vais simplifier la doc en disant que bar devient invalide.
Si bar devient complètement invalide ça veut dire qu'on peut juste créer une chaîne (linéaire) de constructeurs plutôt qu'un arbre quelconque, c'est peut être gênant au niveau performance ?
Sinon actuellement en quoi appeler plusieurs constructeurs avant d'évaluer est plus rapide que de faire l'évaluation au fur et à mesure ? Ca évite juste de faire plusieurs parcours de l'arbre (gain d'un facteur O(nb_de_constructeurs)) ou ça permet aussi de faire des optimisations top-down ? (gain d'un facteur arbitrairement grand)
Pour 0 != eval(0*ext) = subs(e=ext, eval(0*e)) = subs(e=ext, 0) = 0, je cite tout d'abord la doc: algebraically correct, possibly except for a set of measure zero: y / y is simplified into 1.
ensuite si si e est un identifiant, il ne peut être qu'au maximum dans le domaine des complexes, donc 0*e se simplifiant en 0 est tout à fait correct. C'est le subs qui est incorrect.
Ok ; à propos de ce que tu cites, comment est-ce que tu gères e / e où e est très compliquée et pourrait en particulier être nulle sur une surface de mesure non nulle ?
Est-ce que ce serait pas une bonne idée de pouvoir rajouter un flag au domaine qui empêcherait ce genre d'optimisation, pour éviter les problèmes de solutions ratées comme sur TI ?
Sinon rien n'empêche de faire une extesion des qui gère les identifiants non complexes, mais dans ce cas, c'est à elle de gérer 0*x qui devient [ 0].
Comment est-ce que ton extension fait pour intercepter ça ?
Pollux (./33) :
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.
Qu'appelles-tu arbre / feuille ?
Par défaut, la commutativité entre classes différentes est obbligatoire (deux classes différentes sont supposées être tout le temps commutative). C'est un choix pour simplifier l'algorithme utilisé, pour qu'il reste efficace, et qui je pense, ne limite pas vraiment en pratique.
Si je veux regarder si (1+[matrice1])*(1+det([matrice2])) commute, les deux arbres sont les arbres des deux expressions (avec pour feuilles les entiers/matrices).
Comment la commutativité est décidée dans mon exemple ?
squalyl (./37) :
(ça m'arrangerait que ce soit 4
)
Sur 32 bits ca peut être 8 (long long / sse)
Sur 64 bits, ca peut être encore plus 
En pratique je crois que même en 32 bits on a besoin d'alignements sur 16 octets pour que les SSE soient efficaces (inversement si on parle d'alignement pour la correction plutôt que pour la performance, c'est possible que 1 octet suffise sur x86 non ?)