Erlang
Dans les deux codes erlang, la bibliothèque est un processus, ce qui équivaut à un objet. Quand tu l'instancies via la fonction
Ton objet est représenté par la fonction
Le second code présente la même fonction, sauf qu'elle peut recevoir un nouveau type de message (dans la définition classique de la POO, les objets communiquent entre-eux à l'aide de messages) de type
Quand l'utilisateur appelle la fonction
Dans la "classe" biblio, celle-ci reçoit la fonction et la wrappe à l'intérieur de la fonction
Ansi, quand on applique cette fonction à l'ensemble de nos bouquins via un pli (
Au final, l'utilisateur de notre objet n'a a sa disposition que l'API définie au dessus du commentaire
Bien sûr que cela revient à traiter le conteneur dans son ensemble, n'est-ce pas ce que tu prônes depuis le début ? Tu voulais sûrement dire que cela revient à traiter le conteneur élément qu'il contient par élément qu'il contient, et, bien que ce soit le but au final, cette possibilité n'est jamais donnée à l'utilisateur. Il peut seulement proposer un nouveau livre en remplacement d'un autre via une fonction, et demander à la bibliothèque de bien vouloir le faire pour chacun de ses bouquins.
J'aime bien faire de la théorie OO avec un langage fonctionnel, c'est rafraîchissant .
PHP
Ensuite, au sujet du pattern Adapter. Si j'ai bien suivi, oxman voudrait qu'on injecte à la bibliothèque son type de conteneur. (dans le premier code de Xenos, car dans le second, il n'y a que deux classes et on ne fait pas d'adapter avec deux classes). Mais comme on n'utilise pas un stockage en DB ou autre, je trouve que la Bibliothèque est libre de choisir le composant qu'elle veut pour stocker ses bouquins vu que ça ne "sort" pas, ça reste interne à cette classe.
Au sujet de la pureté : L'objet que je définis en erlang est pur, dans le sens ou il n'expose aucune variable publique, ou il ne communique avec l'extérieur qu'avec des messages, et ou il est impossible de l'extérieur d'influer sur l'exécution de son code privé ou quoi que ce soit. Il interargit avec des données de type livre et les stocke pleinement. Le second code PHP s'approche de cette pureté mais il stocke les livres en les découpant en titre et texte. Si l'objet livre change son implémentation "personnelle", par exemple en ajoutant une nouvelle donnée auteur, et ce sans changer son API jsque alors utilisée (membres titre et texte) alors la bibliothèque n'est plus en mesure de stocker proprement ces livres, ce qui est son seul et unique but, et devra avoir son code modifié.
putain j'a réussi à faire une tartine de 50 pages sur un code de 20 lignes ...
Dans les deux codes erlang, la bibliothèque est un processus, ce qui équivaut à un objet. Quand tu l'instancies via la fonction
new/0
, on 'spawn' la fonction biblio/1
avec une liste vide (biblio([])
).Ton objet est représenté par la fonction
biblio/1
qui se rappelle elle-même indéfiniment : tu constates que la fonction biblio/1
se termine par un appel à biblio(NewBooks)
.Le second code présente la même fonction, sauf qu'elle peut recevoir un nouveau type de message (dans la définition classique de la POO, les objets communiquent entre-eux à l'aide de messages) de type
{replace_all_books, function(), pid()}
.replace_all_books
est le tag qui permet de différencier la méthode d'une autre, son nom en somme. pid()
représente l'identifiant de processus de l'appelant de la méthode, vois-ça comme une référence vers l'objet appelant pour pouvoir lui répondre, ce dernier l'obtenant en appelant la fonction self/0
.Quand l'utilisateur appelle la fonction
replace_all_books/2
avec en arguments la référence de la biblio et la fonction permettant de remplacer chaque bouquin, il ne sait pas comment va être appliqué cette fonction. Tout ce qu'il sait, c'est que pour chaque livre contenu dans la bibliothèque, il voudrait bien que cette fonction lui soit appliquée. Dans notre exemple, il envoie la fonction traduire_livre/1
qui reçoit un livre en argument.Dans la "classe" biblio, celle-ci reçoit la fonction et la wrappe à l'intérieur de la fonction
ReplaceBooks/3
qui va recevoir chaque livre un par un. Elle reçoit chaque livre dans son argument Book
, puis elle lui applique la fonction transmise par l'utilisateur Fn
en effectuant un case
sur le résultat : si le résultat est de type #livre{}
alors elle ajoute ce livre au nouveau set de bouquins (orddicttore/...
), sinon elle retourne error
. À l'itération suivante, soit on reçoit en argument NewBooks
ce nouveau set de bouquins, soit on reçoit error
. Si on reçoit error
alors on retourne error
indéfiniment.Ansi, quand on applique cette fonction à l'ensemble de nos bouquins via un pli (
orddict:fold/...
), soit on reçoit effectivement un nouveau set de bouquins SomeBooks
, tout s'est alors bien passé, et on définit NewBooks
comme étant ce nouveau set de bouquins SomeBooks
(via NewDict
) pour la prochaine itération de boucle biblio/1
, soit on garde Books
, nos bouquins actuels comme livres et on envoie à l'utilisateur un message comme quoi il a chié dans la colle (Reply
étant défini à error
).Au final, l'utilisateur de notre objet n'a a sa disposition que l'API définie au dessus du commentaire
%% Internal ---
. Comme le montre la fonction de test (située en deça de ce commentaire, malheur à moi). À aucun moment il n'a accès aux livres stockés directement, il ne traite pas l'objet biblio élément par élément. Il le considère toujours dans son ensemble comme un ensemble de livres. Il définit simplement une fonction qu'il aimerait voir appliquée à l'ensemble des livres contenus par la bibliothèque. C'est une simple nuance mais c'est toute la différence. La bibliothèque à tout loisir d'utiliser la fonction utilisateur diféremment, tant qu'elle l'applique bien aux livres. En tout cas, si la fonction ne se plie pas à l'exigence simple de récupérer un livre en sortie de fonction utilisateur, la bibliothèque refuse en bloc le changement. Il serait aisé de refuser uniquement les retours de fonctions qui ne donnent pas un livre tout en gardant ceux pour lesquels la fonction a ... fonctionné.Citation :Bibliothèque a une méthode qui itère sur chacun des objets qu'elle contient, et qui exécute la fonction de traduction pour chaque objet... Or, à mon sens, cela revient donc à traiter (depuis le code utilisateur qui appelle le "replace_all_book") le conteneur dans son ensemble
Bien sûr que cela revient à traiter le conteneur dans son ensemble, n'est-ce pas ce que tu prônes depuis le début ? Tu voulais sûrement dire que cela revient à traiter le conteneur élément qu'il contient par élément qu'il contient, et, bien que ce soit le but au final, cette possibilité n'est jamais donnée à l'utilisateur. Il peut seulement proposer un nouveau livre en remplacement d'un autre via une fonction, et demander à la bibliothèque de bien vouloir le faire pour chacun de ses bouquins.
J'aime bien faire de la théorie OO avec un langage fonctionnel, c'est rafraîchissant .
PHP
Ensuite, au sujet du pattern Adapter. Si j'ai bien suivi, oxman voudrait qu'on injecte à la bibliothèque son type de conteneur. (dans le premier code de Xenos, car dans le second, il n'y a que deux classes et on ne fait pas d'adapter avec deux classes). Mais comme on n'utilise pas un stockage en DB ou autre, je trouve que la Bibliothèque est libre de choisir le composant qu'elle veut pour stocker ses bouquins vu que ça ne "sort" pas, ça reste interne à cette classe.
Au sujet de la pureté : L'objet que je définis en erlang est pur, dans le sens ou il n'expose aucune variable publique, ou il ne communique avec l'extérieur qu'avec des messages, et ou il est impossible de l'extérieur d'influer sur l'exécution de son code privé ou quoi que ce soit. Il interargit avec des données de type livre et les stocke pleinement. Le second code PHP s'approche de cette pureté mais il stocke les livres en les découpant en titre et texte. Si l'objet livre change son implémentation "personnelle", par exemple en ajoutant une nouvelle donnée auteur, et ce sans changer son API jsque alors utilisée (membres titre et texte) alors la bibliothèque n'est plus en mesure de stocker proprement ces livres, ce qui est son seul et unique but, et devra avoir son code modifié.
putain j'a réussi à faire une tartine de 50 pages sur un code de 20 lignes ...