11

Re : Hoa_Xyl vient d'apparaître dans le tronc

Hywan a écrit:

Pour la seconde partie de ton message, il faut comprendre une autre chose. Les données sont construites par l'utilisateur. Il ne devrait pas avoir à manipuler des données très compliquées. Les données vont provenir essentiellement des contrôleurs dans le cas d'une architecture n-tiers (MVC par exemple), et donc l'utilisateur devra les présenter facilement pour les exploiter facilement. C'est le rôle de la couche modèle ou contrôleur. La vue ne devrait pas trop travailler. Je fais un parallèle volontaire avec le MVC car ce sera un cas concrêt d'utilisation.

Je me suis interrogé sur la pertinence d'une modélisation à base d'array (data buckets et store) parce que je suis parti du principe que les docs XYL sont, par design, aussi restrictifs que ne le sont des templates de StringTemplate http://www.stringtemplate.org/
J'ai pensé à StringTemplate parce que je me suis souvenu de ce doc: http://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf
Les possibilités de computation de ces templates s'arrêtent aux tests booléens (sur des variables uniques, pas sur des expressions). Tout le reste est purement déclaratif.

Dans les exemples que tu as donné et c'est vérifié au niveau du code de la dernière révision, il n'y a aucune computation qui soit exercée au niveau des nodes XYL. Pas de notion de boucles, conditions etc. Tout est reporté sur la nature des "data sources".

Si tel est le cas, comment un utilisateur va-t-il construire ses arrays pour exprimer quelque chose proche de ceci? :

  // if user_is_logged
  <h1 value="?foo" />
  // else  
  <h2 value="?foo" />

Ou, une variante:

  // if user_is_logged
  <h1 value="?foo" />
  // else  
  <h1 value="?bar" />

Donc, on pourrait dire, faisons juste:

  <h1 value="?foo" />

On aura toujours un h1 (et pas de h2) et les data de ?foo seront pré définies avec la bonne valeur.
S'il s'agit de simples valeurs scalaires, OK, ça va. Mais si ?foo est de type array, j'imagine que la construction des data buckets va rapidement devenir complexe et redondante. Une redondance rendue nécessaire par la nature "data driven" du système.

A ce problème, j'envisage plusieurs solutions. Tu en as d'ailleurs esquissé certaines ici et je ne doute pas que tu as déjà songé à tout ça. Il n'y a d'ailleurs peut être pas de problème du tout! Je suis toute ouïe!

Dans tes plans, souhaites-tu que XYL se rapproche de XUL dans la mesure où certains éléments auraient pour rôle de "modifier" le XYL post-processed (je pense à des trucs comme <rule>, <where> etc). Tu as parlé de <overlap> ou de yielding, mais il s'agit d'une autre catégorie de modifications: quelque chose qui se rapprocherait du pre-processing. Je ne sais pas si je me fais bien comprendre...

Une autre possibilité serait de mettre le paquet niveau selecteurs (?blah). On a parlé d'xpath pour array. Le choix de l'utilisation des arrays pour leur rapidité et leur faible impacte mémoire ne sera-t-il pas compromis par la possible lourdeur d'un tel système de query maison?

Encore une autre possibilité: ce coup ci, les data buckets sont heu... un doc SimpleXML. Les références sur arrays sont directement des $var pointant sur des SimpleXMLElement. Toute la logique de traversal est dispo avec DOM et on a xpath aussi. Bref, autant utiliser xslt?

Hywan a écrit:

Tes réflexions sont intéressantes et m'évitent de taper bêtement dans des murs. Je devrais plus communiquer sur ce que je fais tiens

Tu l'auras remarqué, XYL m'interesse. Une sorte de porte d'entré dans Hoa? Je t'avais dit que je m'y pencherais un de ces 4. Bon bah voilà, c'est fait! ;)

Dernière fois dit par metagoto (24 Jul. 2010 08:58)

12

Re : Hoa_Xyl vient d'apparaître dans le tronc

Hey smile,

J'ai mis du temps à répondre à ton message, mais je suis assez occupé …

C'est vrai que XYL est avant tout déclaratif. J'ai intuité ce problème et j'avais mis une notion de contexte dans la spécification mais ce n'était pas clair. Tes remarques ont débloqué quelques points mais pas tous.

On pourrait imaginer quelque chose du genre :

<rule name="foo" from="bar" value="?baz">
  <parameter value="?gordon1" />
  <parameter value="?gordon2" />
</rule>

<!-- plus loin dans le code -->

<yield value="?freeman">
  <apply rule="foo">
    <if>

    </if>
    <else>

    </else>
  </apply>
  …
</yield>

J'ai pensé à ça, mais je ne suis pas encore sûr de moi.
On aurait une liste des règles. Chaque règle est en fait définie en PHP :

class Foo extends … {

    public function rule ( $parameter … ) {

        return (bool) …;
    }
}

Quand on donne un nom à la règle, c'est pour l'utiliser dans un élément XYL. Et son attribut @from précise quelle classe on utilise. On peut lui passer des paramètres à partir du data buckets (ou d'autre part). L'idée serait de pouvoir combiner plusieurs classes dans l'attribut @from :

<rule name="foo" from="A B C D">
  <parameters>
    <parameter />
  </parameters>
  …
</rule>

Mais ça ne permet pas des combinaisons logiques : (A ou B), (A et B) ou (C et D) etc. Donc ça reste imprécis. On peut toujours construire cette combination logique dans une classe PHP et l'utiliser directement. C'est plus rapide, plus puissant mais j'aimerais avoir la même expressivité en PHP qu'avec XYL.

Pour l'application de la règle, je trouve ça verbeux. Le <apply>, <if>, <else>, … j'aime pas, pas du tout. C'est là que ma spéc' s'arrêtait. Je n'avais pas trouvé de moyen efficace pour faire ça.

Une idée ?

Enfin, tu proposes de remplacer les tableaux par des éléments SimpleXML c'est ça ? Comme ça on aurait directement les expressions XPath dessus (et CSS Query Selector au passage si on utilise un Hoa_Xml_Element) ? Ce serait en interne … hmm, oui mais si le bonhomme utilise du JSON, faudrait le convertir vers du XML. C'est un peu chiant (on passe par le tableau forcément). Pas plus léger d'avoir un tableau tu crois ?

En fait, je me suis dit que si j'arrivais déjà à coder le liage des données et la balise <yield>, j'aurai une base très solide. Ensuite, ajouter des règles ou ce genre de chose, ce ne sont que des éléments et des traitements supplémentaires. Mais si ma base est solide et très facilement manipulable, ce serait déjà pas mal.
Toi tu parles de modifier un document XYL. Pourquoi ? On en aurait besoin ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

13

Re : Hoa_Xyl vient d'apparaître dans le tronc

Hywan a écrit:

Toi tu parles de modifier un document XYL. Pourquoi ? On en aurait besoin ?

J'ai mis des guillemets autour de modifier car il s'agit plus d'une vue de l'esprit.
Je vois deux catégories distinctes:

- Le yielding enrichit le XYL en y apportant des fragments DOM qui pourront être ré-utilisés à divers endroits lors du rendu. Ce n'est probablement pas l'exact reflet de ton implémentation, mais je pense qu'on peut le voir comme cela.

- Les éventuels <rule>, <where>, <if> sont quant à eux d'une autre catégorie: ils opèrent en fonction des données. Les choses seraient, je suppose, en partie pre-computées lors du liage, mais il faut attendre le rendu et la lecture des données pour que ces derniers entrent en action. Par exemple en activant la branche <else> plutôt que la branche <if>.

Le rendu final s'opère donc sur un XYL potentiellement enrichit (par les yield) et possiblement simplifié/élagué par l'activation des rules selon les données. Cependant, aucun node n'est réellement supprimé.

Enfin, tu proposes de remplacer les tableaux par des éléments SimpleXML c'est ça ?

C'est une éventualité, juste une éventualité. Si le code pour manipuler les array/store devient trop complexe, je me dis que SimpleXML pourrait être interessant. Mais une telle décision remettrait beaucoup de choses en question.
Le code du store est pour l'instant simple, mais ne crains-tu pas que cela devienne trop fastidieux à faire évoluer/maintenir?
Alors que si on a un doc SimpleXML, le store pourrait être fusionné avec les data: ça ne serait plus qu'une seule et même entité.

14

Re : Hoa_Xyl vient d'apparaître dans le tronc

Une entité ou deux, ça ne gêne pas des masses.
Je voulais rester sur des structures simples que PHP saurait optimiser de lui-même en fait. Est-ce que tu penses que ça pourrait être gênant par la suite ?

Le but ne serait pas d'avoir un xpath dans les @value, mais un chemin vers une idée. Ce serait un chemin genre une arborescende d'un système de fichier tu vois : ?a/b/c/d. Peut-être le support de certains wildcards mais pas plus. Bien sûr, si la valeur commence par « ? », alors on fera ça. J'avais imaginé d'autres choses : database://, ! (pour du CSS), xpath://, json://, rdf://, yaml:// etc.

Tes idées sont intéressantes. J'aime bien.
Est-ce que tu vois quelque chose de bloquant dans le système actuellement ? Car si nos avis peuvent être divergeants sur la structure des data buckets, on est d'accord sur le reste me semble-t-il ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

15

Re : Hoa_Xyl vient d'apparaître dans le tronc

J'ai parlé d'un problème avec spl_object_hash(). J'ai fouillé plus en profondeur et voici mon problème : http://bugs.php.net/bug.php?id=52458.

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

16

Re : Hoa_Xyl vient d'apparaître dans le tronc

Concernant le data/store, mon avis ne diverge pas nécessairement du tien. J'ai juste fait part de mes reflexions en me projetant dans la suite du development par rapport aux attentes et use cases que les simples utilisateurs seraient en droit d'attendre.

Il se peut fortement que ce qui est actuellement en gestation soit tout à fait suffisant.
A part peut-être les histoires de conditions/rules. Et là peut être que StringTemplate (voir les liens plus haut) et son désuet support des conditions sous leur formes la plus simple suffira à avoir un truc qui tienne la route pour la plupart des besoins. Je me place dans le cas souhaitable où, comme tu l'as suggéré, les @value seraient juste des "pathes".

J'ai ajouté un commentaire sur la page du bug pour spl_object_hash().
J'ai bien peur que cela soit compliqué. Je n'avais pas du tout pensé à ce problème initialement.
Dériver des classes standard (SimpleXMLElement, PDO etc) c'est toujours un peu risqué big_smile

17

Re : Hoa_Xyl vient d'apparaître dans le tronc

J'ai conscience des problèmes des StringTemplate comme tu l'as souligné. J'avais des solutions avec des règles/contextes mais je n'ai pas résolu totalement ces problèmes. Aurais-tu des idées ?

Concernant le bug, si on a un tableau qui fait référence à tous les éléments de notre arbre, on ne devrait pas perdre le zval.handle ni zval.handler, donc résoudre notre conflit. J'ai pensé que c'était ça, mais je pensais que c'était un comportement anormal de SimpleXML qui ne devrait pas recréer de structure zval à chaque fois … Il a des tables de hashes, il pourrait bien s'en servir un peu plus.
Donc avec mon idée de tableau, est-ce que ça poserait des problèmes mémoires à ton avis ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

18

Re : Hoa_Xyl vient d'apparaître dans le tronc

Je ne sais pas si ton idée de tableau poserait des problèmes de mémoire. C'est clair que ça va consommer plus de mémoire que si on n'avait rien du tout, mais j'imagine que le prob principal sera plutôt de garantir qu'il n'y a pas d'oublis ou de double référençages etc. Une difficulté pour le code de la librairies en quelque sorte.
L'implémentation actuelle utilise aussi de la mémoire pour le map/array_search donc l'un dans l'autre ça devrait se valoir...
Il faudrait mesurer plus précisément. Je pense que ta priorité est les perfs d'abord et en second la mémoire.

Pour SimpleXML (le "bug"), ça ne me parait pas simple. L'api a une sémantique de valeur et non de référence au niveau des zvals (pour les structures de libxml en interne, c'est une autre histoire). SimpleXML ne semble pas du tout avoir été conçu pour storer les zvals qu'il expose par ailleurs sur demande au user. Pour que cela fonctionne à peu près comme attendu, il faudrait offrir au user des var liées par références à la var initialement créée lors d'un premier accès. Ca serait source d'ennuis (décidément!) pour les histoires de ref counting (une fois créée, son ref count serait toujours supérieur ou égal à 1) et de manipulations dans d'autres parties du code (php n'aime pas trop les vars liées par ref).

En fait je pense que c'est plutôt spl_object_hash qui est trop archaique pour ce cas bien particulier. La représentation "php" (le zval) ne suffit pas à identifier de manière unique la structure sous jacente, qui en l'occurence provient d'une lib tierce (libxml).

Pour XYL et les règles/contexts, franchement, je ne sais pas wink
Ma crainte (qui est somme toute modérée;) est que le doc XYL en lui-même devienne trop complexe. Le challenge serait quand même, je pense, que le truc soit plus simple de xslt et xul tant sur la forme que sur le fond (qui dit fond, dit perfs qui vont se dégrader).

Donc en fait, je n'apporte aucune solution ni idée wink
Est-ce que tu as envisagé de manière concrete le type d'utilisation "finale" de la part d'un simple user? De quoi a-t-il besoins pour faire ses docs (documents après rendus, html etc) ? Les rules/contexts sont peut être superflus. Seule la notion de "condition simple" (à la StringTemplate) suffit.

Dernière fois dit par metagoto (28 Jul. 2010 15:00)

19

Re : Hoa_Xyl vient d'apparaître dans le tronc

Pour l'instant, je conserve mon map/array_search. On verra bien. Faudra que je regarde comment est coder array_search pour voir si ce performant pour de gros documents.

Pour spl_object_hash(), je laisse tomber pour l'instant. Faire un workaround devient vite compliqué car :

$a = spl_object_hash($sxe->foo[0]->bar[0]);
$b = $sxe->foo[0];
$c = spl_object_hash($b->bar[0]);
var_dump($a === $c); // false

Comme tu l'as dit sur le rapport de bug, l'accès à un élément à travers une dimension (->) génère un nouveau zval. Donc on aura toujours un zval possible … Et je ne parle pas encore de xpath() qui sorte des collections de zval … Bref. On va voir à l'usage.

Pour XYL, j'en suis à gérer les yields. On verra pour les règles et contextes plus tard. J'ai ajouté le support des chemins aussi. Ah oui, @value est remplacé par @bind ; moins éléguant mais sémantiquement plus juste. Par exemple :

<page>
  <yield bind="?main/foo">
    <ul>
        <li bind="?li" />
    </ul>
  </yield>
</page>

Ça, ce sont les yielders anonymes. Il ne créé pas de « DOM fragments » (aïe, va falloir trouver des exemples pour expliquer tout ça à des débutants, je me régale d'avance …). Il ne font que « binder » un sous-ensemble dans le data bucket et va itérer sur ce sous-ensemble. En gros, c'est comme un élément vide/sans rendu qui va se répéter. Ah, bel exemple tiens tongue.

Et là j'attaque les yielders nommés. C'est une autre paire de manche. Je vais tous les extraire, et remplacer leurs appels par les extraits. En gros :

<page>
  <yield name="foo">
    <ul>
      <li bind="?li" />
    </ul>
  </yield>

  <p>
    <foo bind="?main/foo" />
  </p>
</page>

devrait devenir :

<page>
  <p>
    <yield bind="?main/foo">
      <ul>
        <li bind="?li" />
      </ul>
    </yield>
  </p>
</page>

C'est une façon naïve de procéder. Je demande si le yielder nommé est très gros (comprendre qu'il représente un très gros arbre), ça n'aurait pas de mauvais effet sur les performances. En gros, le chercher remplacer-partout pourrait vite devenir source de ralentissement ou de surcharge mémoire. Il faudrait peut-être trouver un nouveau système de liens … Je cherche. Une idée ?

« Un handicap est le résultat d'une rencontre entre une déficience ou différence et une incapacité de la société à répondre à celle-ci. »

20

Re : Hoa_Xyl vient d'apparaître dans le tronc

OK pour les yields anonymes. J'ai compris (je pense). J'aurai nommé ça "block" (en tout cas, conceptuellement)

Toi tu voudrais dupliquer+merger sur place les fragments DOM à chaque fois qu'un <foo> est rencontré dans le doc? (je prends <foo> en exemple)
J'aurai plutôt imaginé ne rien dupliquer du tout mais juste switcher de node lors du rendu, uniquement lors du rendu. Quand le renderer arrive sur <foo>, il "saute" sur le bon et unique fragment correspondant.
Le premier inconvénient que je perçois par rapport à ce que je viens de dire, c'est que le data binding devra se faire lors du rendu pour les yields, et non pas en amont. Peut être pas forcément au niveau du rendu, mais différemment en tout cas des éléments classiques puisque les stores des fragments se retrouvent paramètrés par les appels concrets <foo bind=...>

Sinon je m'interroge sur un truc: comment choisis-tu les éléments qui ne doivent contenir que des PCDATA? Pourquoi eux? <li> par exemple pourrait très bien avoir des children (Renderer_Html5_Li).