<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Billets de asmanur — Projets inachevés</title><link href="http://blog.iuwt.fr/"/><id>http://blog.iuwt.fr/</id><updated>2010-02-27T19:25:43Z</updated>
<entry><title>OneSwarm, un système peer-to-peer inspiré des réseaux sociaux.</title><link rel="alternate" href="http://blog.iuwt.fr/articles/oneswarm"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/oneswarm</id><updated>2009-08-29T18:37:11Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="r&#xE9;action"/><category term="p2p"/><category term="social"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"/></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p><a class="extern" href="http://oneswarm.cs.washington.edu/">OneSwarm</a> est un logiciel de
<em>peer-to-peer</em> dont le but est de garantir l’anonymat au contraire des
protocoles du type BitTorrent. Pour cela, l’information sur les
fichiers disponibles sur les réseaux n’est plus centralisée dans des
<em>trackers</em> mais est au contraire décentralisée. Avec BitTorrent, il
suffit de se connecter au <em>tracker</em> d’un fichier pour savoir qui le
possède ; avec OneSwarm cela n’est plus possible. Les transferts de
fichiers se font en effet qu’avec des pairs de confiance choisis par
l’utilisateur. On parle alors d’un système <em>friend-to-friend</em>. Les
avantages au niveau sécurité sont clairs : seuls les gens en qui vous
avez confiance peuvent voir vos données.
</p><p>Le <em>paper</em> en question décrivant l’architecture d’OneSwarm est
disponible <a class="extern" href="http://oneswarm.cs.washington.edu/f2f_tr.pdf">sur leur
site</a>.
</p><p>Deux points sont intéressants dans ce papier sans être trop
technique. D’une part, le <em>design</em> de OneSwarm est basé sur une analyse des
réseaux sociaux et <em>peer-to-peer</em> existants, d’autre part le moyen
démarrer (<em>bootstrap</em>) le réseau est lui aussi intéressant.
</p><h2>L’étude d’un réseau social, lastfm
</h2><p>Le <em>paper</em> commence par une analyse du réseau social
<a class="extern" href="http://www.last.fm">last.fm</a> et notamment étudie la structure du
graphe social. Par exemple, le chemin moyen pour aller d’un
utilisateur A à un utilisateur B passe par 7 utilisateurs ; tandis que
les deux utilisateurs les plus éloignés sont distants de 14
utilisateurs. Il est également déterminé la bande passante utilisé
pendant les deux semaines durant lesquelles les données ont été
récupérées : 4.66 TB. Ce qui ne fait qu’environ 4MB de données
transférées par utilisateur, cela est bien en-dessous de la capacité
des lignes ADSL actuelles.
</p><p>D’autres remarques sur le comportements des utilisateurs sont faites :
</p><ul><li>la majorité des chansons ne sont écoutées que par un seul
utilisateur ;
</li><li>malgré tout, ce sont les chansons les plus populaires qui
représentent la majorité du traffic ;
</li><li>il n’y a pas de corrélation évident entre <em>être intégré socialement</em>
et <em>écouter beaucoup de chansons</em>.
</li></ul><p>La conclusion tirée de cette étude est la suivante : <em>les réseaux p2p
ont largement plus de capacité totale que de demandes</em>. OneSwarm se
fixe donc pour objectif d’utiliser cet excès de capacité au service de l’anonymat.
</p><h2>Présentation de OneSwarm
</h2><p>OneSwarm n’est pas le premier système <em>friend-to-friend</em>, par exemple
<a class="extern" href="http://freenetproject.org">freenet</a> et son mode <em>DarkNet</em> proposait
un p2p privé de ce type. Un des problèmes des réseaux de ce type,
c’est le début : chaque utilisateur étant identifié par sa clé
publique, pour ajouter des utilisateurs il doit connaître leur clé
publique et les ajouter. C’est là la solution retenue par freenet :
l’ajout manuel de clés.
</p><p>OneSwarm propose une solution originale : au final avec un système
d’ami, on dote le système d’une structure de réseau social. Or les
utilisateurs sont déjà inscrits dans d’autres réseaux, et il est
fatiguant pour eux de toujours reconstruire ce graphe. Ainsi OneSwarm
permet d’utiliser un réseau déjà existant pour importer les amis. Pour
l’instant ils n’ont l’air que de supporter Google Talk au moyen d’un
bot auquel OneSwarm fait des requêtes régulières.
</p><p>S’en suit une description (étonnamment assez peu technique) du
protocole et du fonctionnement interne de OneSwarm.
</p><h2>Avis</h2><p>Le papier en lui même est très accessible et finalement ce n’est pas
tant les connaissances réseaux qui manquent mais plutôt les
connaissances en théorie des graphes. Cependant, une question reste,
bien que partiellement résolue à la fin du papier. Qu’est-ce
qu’apporte au point de vue sécurité et anonymat OneSwarm sur les
réseaux type freenet ? À mon avis OneSwarm repose un peu trop sur le
concept de friend-to-friend pour assurer l’anonymat (en tout cas la
sécurité des transferts en eux-même est très peu évoquée dans le
papier). La réponse apportée par les auteurs est la possibilité
d’avoir des permissions plus fine. À mon avis, OneSwarm représente un
bon compromis entre les performances des réseaux p2p traditionnels et
la sécurité des réseaux p2p anonymes.

</p></div></content></entry>
<entry><title>Le fonctionnel, c'est bien aussi pour les jeux </title><link rel="alternate" href="http://blog.iuwt.fr/articles/jeu-fonctionnel"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/jeu-fonctionnel</id><updated>2009-07-25T17:04:19Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="OCaml"/><category term="jeu"/><category term="novendiales"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Cet article a pour but d’exposer les avantages de la programmation
fonctionelle dans le cadre dans la création de jeux vidéos. Cet
article se base un peu (sinon beaucoup) sur l’expérience personnelle
obtenue avec <a class="extern" href="http://iuwt.fr/~asmanur/novendiales">(un)faithful</a>, un
hack&amp;slash tour par tour (un rogue-like en fait), ainsi les exemples
en sont tirés.
</p></div></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Cet article a pour but d’exposer les avantages de la programmation
fonctionelle dans le cadre dans la création de jeux vidéos. Cet
article se base un peu (sinon beaucoup) sur l’expérience personnelle
obtenue avec <a class="extern" href="http://iuwt.fr/~asmanur/novendiales">(un)faithful</a>, un
hack&amp;slash tour par tour (un rogue-like en fait), ainsi les exemples
en sont tirés.
</p><p>Cet article a pour but d’exposer les avantages de la programmation
fonctionelle dans le cadre dans la création de jeux vidéos. Cet
article se base un peu (sinon beaucoup) sur l’expérience personnelle
obtenue avec <a class="extern" href="http://iuwt.fr/~asmanur/novendiales">(un)faithful</a>, un
hack&amp;slash tour par tour (un rogue-like en fait), ainsi les exemples
en sont tirés.
</p><h1>Le dessin
</h1><p>La solution que l’on utilise pour éviter des appels à des routines de
dessins un peu partout dans le code est pure et permet de factoriser
les dépendances à la bibliothèque chargée du sale boulot.
</p><p>L’idée est de caractériser ce que l’on affiche ; ainsi on construit un
type <code>dessin</code> qui contient toute l’information nécessaire à
l’affichage du jeu, un <code>dessin</code> peut être un morceau de texte à
afficher, un rectangle à dessiner, tout dépend du type de jeu. Un
<code>dessin</code> inclut aussi la position à laquelle il doit être dessiné ; il
suffit ensuite d’écrire une fonction <code>dessiner</code> qui sera la seule à
faire appel aux routines graphiques.
</p><p>Ainsi une fonction de dessin retourne une liste de dessins (le fonctionnel
c’est aussi l’art d’énoncer les bonnes tautologies) et zou il suffit
d’itérer sur les dessins et on a l’affichage de la scène.
</p><p>Cette méthode possède un avantage assez conséquent, on peut effectuer
du <em>post-processing</em> sur les dessins générés — c’est le mécanisme de
base utilisé dans les fondus de (un)faithful — autant pour les
déplacer à l’écran que pour modifier leur couleur ou le texte
affiché. Déplacer la caméra ? Il suffit de décaler tous les dessins
d’une fonction linéaire du temps pendant le fondu. Pour ce faire, on
préferera utiliser, à la place d’une boucle, des combinateurs sur les
listes qui permettent d’exprimer les traitements les plus communs sur
les listes de façon plus concise. Ici on utiliserait <code>map</code> qui
applique une fonction sur tous les éléments d’une liste et retourne la
liste des résultats.
</p><h1>Un monde immuable
</h1><p>En programmation fonctionelle, on préfère ne pas modifier l’état du
monde par effet de bord mais plutôt par mise à jour. Cela possède un certain
nombre d’avantages. Premièrement, il est très facile de mettre de coté
les états pour retourner dans le passé de la partie ou pour faire un
<em>replay</em>. Ensuite cela permet d’éviter que n’importe quelle fonction
touche au monde, là on sait que chaque fonction ne pourra rien
modifier autrement qu’au travers de sa valeur de retour, ça permet de
vite retrouver l’origine d’un bug.
</p><p>On s’en sert également pour organiser la transition graphique entre
deux tours, avec une fonction prenant en argument le monde à la fin du
tour précédant et le monde au début du tour suivant génère un <em>diff</em>
qui sert à une partie des fondus. Bien sûr pour éviter que ce soit une
usine à gaz, les <a class="extern" href="http://fr.wikipedia.org/wiki/Ramasse-miettes_(informatique)">garbage
collector</a>
sont <a class="extern" href="http://alaska-kamtchatka.blogspot.com/2009/05/is-immutable-data-slow.html">prévus pour
ça</a>(en).
</p><h1>Gestion d’événements
</h1><p>Pour gérer les évènements, un des moyens les plus adaptés au
fonctionnel est probablement l’utilisation de <em>callbacks</em>. On associe
donc à chaque type d’évenements une fonction différente. Ce moyen
est très répandu aussi en impératif et en orienté objet. Le
fonctionnel rend ça encore plus attrayant en permettant la création de
<em>callbacks</em> dynamiquement.
</p><p>Par exemple, dans (un)faithful, on a une fonction <code>move</code> qui prend
deux arguments, le premier est un vecteur désignant la direction du
mouvement, le second est le monde, et cette fonction renvoie le monde
modifié — on note le type d’une telle fonction <code>vecteur -&gt; monde
-&gt; monde</code>. En fait on peut voir cette fonction comme prenant en
argument un vecteur et renvoyant une opération sur le monde (<code>monde -&gt;
monde</code>) — on écrit alors <code>vecteur -&gt; (monde -&gt; monde)</code>. Cette
fonction, dite <a class="extern" href="http://fr.wikipedia.org/wiki/Curryfication">curryfiée</a>,
peut alors être appliquée partiellement. Ainsi <code>move (0, 1)</code> est une
opération sur le monde qui déplacera le personage d’une case vers le
haut.
</p><p>Cela permet de créer une liste associant des touches appuyées à des
opérations sur le monde. Cette liste peut ressembler à :
</p><pre><code>[(Left, move (1, 0)); (Right, move (-1, 0)); …]
</code></pre><h1>Un compromis à établir : équilibre entre données et fonctions
</h1><p>Il ne faut pas tomber dans un extrémisme du « tout fonction » ; le
problème de la fonction c’est que c’est une boîte noire aux yeux de
l’appelant, il n’y a aucun moyen de savoir ce qui est fait durant or
l’appelant peut vouloir avoir des détails. Si on modélise un effet
affectant un joueur par une fonction de type <code>monde -&gt; monde</code>, on va
peut être se retrouver à coder des systèmes pour gérer la durée dans
chaque effets, etc. Parfois il est intéressant de restreindre les
possibilités pour pouvoir automatiser une partie des effets.
</p><p>Un autre problème des fonctions est la sauvegarde ; il est très
difficile (sinon impossible) de sauvegarder une fonction telle quelle,
une solution est d’associer à chaque effet une clé, et de stocker une
liste constante <code>(clé, effet)</code>, ainsi il suffit de stocker la clé (on
perd une partie de l’extensibilité offerte par l’application
partielle, en pratique on adopte donc un système plus sophistiqué).
</p><h1>Conclusion
</h1></div></content></entry>
<entry><title>Novendiales - Jour 6</title><link rel="alternate" href="http://blog.iuwt.fr/articles/noven-jour-six"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/noven-jour-six</id><updated>2009-07-18T11:05:22Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="projets inachev&#xE9;s"/><category term="novendiales"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Deux jours avant l'échéance, la productivité est à son maximum.</p></div></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Deux jours avant l'échéance, la productivité est à son maximum.</p><p>Deux jours avant l'échéance, la productivité est à son maximum.</p><p>Le moteur de jeu est quasiment terminé, il ne nous reste que quelques
choses à fignoler pour avoir terminé (encore et toujours les maps). On
a maintenant un donjon de dix niveaux (qui sont sauvegardés à
l'arrache dans des fichiers, sinon caml est à genoux), on peut acheter
des armes, des sorts, on peut choisir sa destinée (true story), et
bien plus encore.</p><p>Est implémentée aussi, la gestion de l'alignement, ce qui détermine la
foi obtenue en tuant des personnes ; plus elle est grande et plus vous
êtes fidèles à votre Dieu qui vous récompense ; plus elle est faible
et votre Dieu vous rejette (attention à ne pas trop l'énerver !).</p><p>Il nous reste principalement à faire des donjons de difficulté
croissante, rajouter des objets / sorts / effets, bref du contenu, et
le boss de fin aussi.</p><p>Voici un screenshot de l'interface des autels pour acheter des sorts
ou des objets :</p><img src="screen6.png"/></div></content></entry>
<entry><title>Novendiales - Jour 4</title><link rel="alternate" href="http://blog.iuwt.fr/articles/noven-jour-quatre"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/noven-jour-quatre</id><updated>2009-07-16T09:53:55Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="projets inachev&#xE9;s"/><category term="novendiales"/><category term="L'informatique mystique"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>And the Lord spoke saying...</p><p align="center">
  <i>« Three shall be the number, thou shalt count... »</i>
</p></div></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>And the Lord spoke saying...</p><p align="center">
  <i>« Three shall be the number, thou shalt count... »</i>
</p><p>And the Lord spoke saying...</p><p align="center">
  <i>« Three shall be the number, thou shalt count... »</i>
</p><p>
Il a fallu attendre trois jours pour voir le PC d'haveo
ressuciter. Mais tout est bien qui finit bien, on peut de nouveau être productifs.
  <span align="center">
    <img src="screen4.png"/>
  </span>
</p></div></content></entry>
<entry><title>Novendiales - Jour 3</title><link rel="alternate" href="http://blog.iuwt.fr/articles/noven-jour-trois"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/noven-jour-trois</id><updated>2009-07-15T02:13:43Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="projets inachev&#xE9;s"/><category term="novendiales"/><category term="Zombie Holocauste"/><category term="RP"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Ça fait deux jours que les morts se sont réveillés. </p></div></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Ça fait deux jours que les morts se sont réveillés. </p><p>Ça fait deux jours que les morts se sont réveillés. </p><p>Une lueur malsaine
d'intelligence semble briller dans leurs orbites vides. Dans ce dédale
de couloirs, la plupart sans issue, je dois leur échapper si je veux
me maintenir en vie. Je ne sais combien de temps je vais pouvoir
encore survivre, les salles s'enchaînent sans que je puisse en garder
une image claire. Paranoïaque, ça fait des nuits que je vis dans la
peur.</p><p>Mon seul but est de m'enfoncer toujours davantage dans ce donjon pour
trouver la cause de ce mal — existe-t-elle seulement ? En tout cas la
sortie est maintenant hors d'atteinte et je ne saurais jamais
retrouver la lumière du jour, toutes ces salles à peine éclairées sont
indiscernables, les corps putréfiés en pleine chaleur me donnent la
nausée.</p><p>Mon épée, ma seule amie encore fidèle, m'a sauvé des mains de ces
êtres dénués de pitié. J'espère seulement que la corruption qui les
anime ne m'atteindra pas et que jamais je ne les rejoindrai.</p><p>Aidez-moi.</p><img src="noven3.png"/></div></content></entry>
<entry><title>Les types existentiels (2/2)</title><link rel="alternate" href="http://blog.iuwt.fr/articles/type-existentiel2"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/type-existentiel2</id><updated>2009-07-14T17:15:00Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="types existentiels"/><category term="OCaml"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Maintenant que l'on sait comment implémenter des types existentiels en caml, je vais vous montrer les quelques usages que l'on en fait dans le code pour notre projet pour les novendiales.</p></div></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Maintenant que l'on sait comment implémenter des types existentiels en caml, je vais vous montrer les quelques usages que l'on en fait dans le code pour notre projet pour les novendiales.</p><p>Maintenant que l'on sait comment implémenter des types existentiels en caml, je vais vous montrer les quelques usages que l'on en fait dans le code pour notre projet pour les novendiales.</p><p>Maintenant que l'on sait comment implémenter des types existentiels en caml, je vais vous montrer les quelques usages que l'on en fait dans le code pour notre projet pour les novendiales.</p><h2 id="State,_l'&#xE9;tat_du_jeu_&#xE0;_tout_instant">State, l'état du jeu à tout instant</h2><p>Dans un jeu il y a principalement trois choses à faire :</p><ul><li><p>dessiner le monde ;</p></li><li><p>réagir lors de l'appui d'une touche ;</p></li><li><p>prendre en compte l'influence du temps.</p></li></ul><p>Supposons que notre type représentant l'état du monde soit <code>'a</code>, cela nous donne le type suivant :</p><div class="highlight"><pre><span class="k">type</span> <span class="k">'</span><span class="n">a</span> <span class="err">é</span><span class="n">tat</span> <span class="o">=</span> <span class="o">{</span>
  <span class="n">dessiner</span> <span class="o">:</span> <span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">dessin</span> <span class="kt">list</span><span class="o">;</span> 
  <span class="n">temps</span> <span class="o">:</span> <span class="kt">float</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span><span class="o">;</span>
  <span class="n">touche_appuy</span><span class="err">é</span><span class="n">e</span> <span class="o">:</span> <span class="n">touche</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span><span class="o">;</span>
<span class="o">}</span>
</pre></div><p>Quelques commentaires :</p><ul><li><p>seul <code>temps</code> et <code>touche_appuyée</code> sont susceptibles de modifier le</p></li></ul><p> monde,  <code>dessiner</code> s'occupe juste de représenter le monde ;</p><ul><li><p><code>dessiner</code> retourne une liste de <code>dessin</code>, cela permet d'avoir tout</p></li></ul><p> le code de dessin complètement pur et indépendant de la bibliothèque  utilisée  et une fonction <code>dessiner_dessin :  dessin -&gt; unit</code> qui varie selon la bibliothèque utilisée. Les  avantages de cette méthode seront présentés dans un article ultérieur</p><ul><li><p>il n'est pas dit qu'on ait qu'un seul type de monde tout au long de</p></li></ul><p> notre programme, notamment avec les menus ce type peut varier.</p><p>Le problème de ce type c'est qu'il ne permet pas de changer d'état. Il faut donc changer le type de retour de <code>temps</code> et <code>touche_appuyée</code>. Cependant, remplacer <code>'a</code> par quelque chose du genre de</p><div class="highlight"><pre><span class="nc">Continuer</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="o">|</span> <span class="nc">Changement_d_</span><span class="err">é</span><span class="n">tat</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="err">é</span><span class="n">tat</span>
</pre></div><p>ne résoud pas le problème — et si on veut changer de type d'état ? L'intérêt des types existentiels arrive ici, si on a un type <code>état_quantifié</code> on peut écrire simplement</p><div class="highlight"><pre><span class="k">type</span> <span class="k">'</span><span class="n">a</span> <span class="n">retour</span> <span class="o">=</span> <span class="nc">Continuer</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="o">|</span> <span class="nc">Changement_d_</span><span class="err">é</span><span class="n">tat</span> <span class="k">of</span> <span class="k">'</span><span class="n">a</span> <span class="err">é</span><span class="n">tat_quantifi</span><span class="err">é</span>

<span class="k">type</span> <span class="k">'</span><span class="n">a</span> <span class="err">é</span><span class="n">tat</span> <span class="o">=</span> <span class="o">{</span>
  <span class="n">dessiner</span> <span class="o">:</span> <span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="n">dessin</span> <span class="kt">list</span><span class="o">;</span> 
  <span class="n">temps</span> <span class="o">:</span> <span class="kt">float</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="n">retour</span><span class="o">;</span>
  <span class="n">touche_appuy</span><span class="err">é</span><span class="n">e</span> <span class="o">:</span> <span class="n">touche</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="n">retour</span><span class="o">;</span>
<span class="o">}</span>
</pre></div><p>Quelques exemples d'état actuellement implémenté (en plus de celui du jeu) :</p><ul><li><p>un état pour les transition graphique entre deux états (l'état est un flottant compris entre 0 et 1) ;</p></li><li><p>un état pour récupérer une touche (désignant un objet) au joueur, l'état est ici le monde (mais ça n'est pas nécéssaire)</p></li><li><p>un état pour sélectionner un ennemi, l'état est ici l'index du monstre sélectionné (qui varie quand l'utilisateur change de monstre).</p></li></ul><h2 id="Des_effets_en_pagaille_!">Des effets en pagaille !</h2><p>Autre utilité des types existentiels : permettre d'avoir une grande variété d'effet.</p><p>En tant que roguelike, notre jeu est en tour par tour et ainsi un effet est grosso modo une fonction qui est appelé à chaque fin de tour pour agir sur le monde d'une façon ou d'une autre. Sauf qu'un effet peut maintenir un état — par exemple le nombre de tour avant qu'il disparaisse, ou plus élaboré si l'effet est moins conventionnel — et donc un type existentiel résoud ce problème.</p><p>Pour appliquer les effets, il suffit ensuite d'itérer sur les effets. En pratique ça pose quelques problèmes de récursivité car le monde dépend des effets et vice-versa or notre effet quantifié est construit via un module … Bref c'est pas la joie.</p></div></content></entry>
<entry><title>Les types existentiels (1/2)</title><link rel="alternate" href="http://blog.iuwt.fr/articles/type-existentiel1"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/type-existentiel1</id><updated>2009-07-13T19:22:31Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="types existentiels"/><category term="OCaml"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>
Pour les novendiales, notre code utilise ce qu'on appelle les 
  <i>types existentiels</i>
. C'est un aspect assez peu connu et assez délicat des langages fonctionnels et donc assez peu répandu. Pourtant, cette technique a des ressemblances avec ce qui peut se faire du coté de l'orienté de l'objet (en fait cela permet une encapsulation).
</p></div></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>
Pour les novendiales, notre code utilise ce qu'on appelle les 
  <i>types existentiels</i>
. C'est un aspect assez peu connu et assez délicat des langages fonctionnels et donc assez peu répandu. Pourtant, cette technique a des ressemblances avec ce qui peut se faire du coté de l'orienté de l'objet (en fait cela permet une encapsulation).
</p><p>
Pour les novendiales, notre code utilise ce qu'on appelle les 
  <i>types existentiels</i>
. C'est un aspect assez peu connu et assez délicat des langages fonctionnels et donc assez peu répandu. Pourtant, cette technique a des ressemblances avec ce qui peut se faire du coté de l'orienté de l'objet (en fait cela permet une encapsulation).
</p><h2 id="G&#xE9;n&#xE9;ralit&#xE9;s">Généralités</h2><p>Le quantifieur universel est le plus utilisé et le plus facilement compréhensible, il est d'ailleurs implicite dans la plupart des langages fonctionnels. Par exemple, le type de <code>map</code>,</p><div class="highlight"><pre><span class="o">(</span><span class="k">'</span><span class="n">a</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">b</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="o">(</span><span class="k">'</span><span class="n">a</span> <span class="kt">list</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">b</span> <span class="kt">list</span><span class="o">)</span>
</pre></div><p>si il devait être quantifié, donnerait</p><pre>forall 'a 'b, ('a -&gt; 'b) -&gt; ('a list -&gt; 'b list)
</pre><p>Le quantifieur universel permet donc une généricité à travers le <i>polymorphisme paramétrique</i>.</p><p>Formellement, si on écrit <code>type t = forall 'a. 'a -&gt; 'a</code>, le type des fonctions acceptant un paramètre de n'importe quel type et renvoyant une valeur de ce même type (<code>t</code> est habité uniquement par la fonction identité), on voit bien que <code>t</code> ne dépend plus de <code>'a</code>.</p><p>Le but serait donc de pouvoir écrire par analogie <code>type t = exists 'a. 'a -&gt; 'a</code>. Que représente ce type ? Il représente les fonctions telles qu'il existe un type <code>'a</code> tel que la fonction soit de type <code>'a -&gt; 'a</code>, la fonction n'est donc pas générique. Par exemple, <code>(fun n -&gt; n + 1)</code> est un membre de type <code>t</code>.</p><p>L'avantage d'un tel type c'est qu'il ne dépend pas de <code>'a</code> donc on peut en construire une liste.</p><p>On peut imaginer avoir un <code>type t = exists 'a. ('a * ('a -&gt; 'a))</code>. Ainsi ce type représente les couples de la forme <code>(état, transition)</code> avec <code>état</code> n'importe quel type. Par exemple on pourrait avoir une liste de ce type </p><div class="highlight"><pre><span class="o">[(</span><span class="mi">4</span><span class="o">,</span> <span class="n">succ</span><span class="o">);</span> <span class="o">(</span><span class="s2">"foo"</span><span class="o">,</span> <span class="o">(</span> <span class="o">(^)</span> <span class="s2">"f"</span> <span class="o">)]</span> <span class="o">:</span> <span class="n">t</span> <span class="kt">list</span>
</pre></div><p>Ensuite, on pourrait définir une fonction <code>update : t list -&gt; t list</code> qui à chaque couple <code>(état, transition)</code> associe <code>(transition état, transition)</code>.</p><p>Cela permet ainsi de mettre à jour plusieurs chose complètement différente d'un coup — des personnages, des objets, etc. — et tout mettre à jour tout d'un coup sans se préoccuper de rien.</p><h2 id="Impl&#xE9;mentation">Implémentation</h2><p>OCaml ne dispose pas de base de ces types existentiels mais il est possible de de les implémenter (avec une légère surcharge syntaxique).</p><p>En fait, en logique, on peut exprimer le quantifieur existentiel à l'aide de la négation et du quantifieur universel. On a l'identité ∃x. P(x) ≣ ¬ (∀x. ¬ P(x)) (¬ étant la négation) (il s'agit simplement d'une trivialité facile à se représenter). Si on sait trouver une représentation sympathique de la négation, en exploitant l'<a href="http://da-bhm.org/see.yaws?id=21">analogie de Curry-Howard</a>, on pourra trouver une représentation du type <code>exists 'a. P a</code>. La définition usuelle de ¬P est P ⇒ ⊥ (⊥ se lisant « faux »). Sachant que la proposition fausse implique toute proposition <sup><a id="footnotes1"/><a href="#footnotes_1">1</a></sup>, on a ¬P ≣ ∀Q. P ⇒ Q.</p><p>On finit par aboutir à un encodage du type ∀R. (∀x. P(x) ⇒ R) ⇒ R (pas strictement équivalent à l'existence ceci dit).</p><p>Intéressons nous tout d'abord, à (∀x. P(x) ⇒ R) pour un certain R. Le type équivalent serait <code>forall 'a. 'a P -&gt; R</code>. Il s'agit ici du type des <i>opérateurs</i> agissant sur n'importe <code>'a P</code> et renvoyant un <code>R</code> <i>indépendant</i> de <code>'a</code>. Pour définir un tel type polymorphe en caml, une des façons de procéder est d'utiliser des <i>records</i>. Ainsi le type des opérateurs est </p><div class="highlight"><pre><span class="k">type</span> <span class="k">'</span><span class="nc">R</span> <span class="n">op</span><span class="err">é</span><span class="n">rateur</span> <span class="o">=</span> <span class="o">{</span> <span class="n">op</span> <span class="o">:</span> <span class="k">'</span><span class="n">x</span><span class="o">.</span> <span class="k">'</span><span class="n">x</span> <span class="nc">P</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="nc">R</span> <span class="o">}</span>
</pre></div><p>Le <code>'x.</code> signifie <code>forall x.</code>.</p><p>Maintenant, on peut trouver un équivalent du type complet :</p><pre>(forall R. R operateur) -&gt; R
</pre><p>Soit en caml :</p><div class="highlight"><pre><span class="k">type</span> <span class="n">t</span> <span class="o">=</span> <span class="o">{</span> <span class="n">app</span> <span class="o">:</span> <span class="k">'</span><span class="nn">R</span><span class="p">.</span> <span class="err">'</span><span class="nc">R</span> <span class="n">op</span><span class="err">é</span><span class="n">rateur</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="nc">R</span> <span class="o">}</span>
</pre></div><p>Un objet de ce type est un élément qui prend un opérateur en argument et l'appelle sur une donnée qui est ici cachée. On peut ainsi écrire une fonction <code>pack</code> qui convertit un <code>'x P</code> en un type <code>t</code> (cachant la valeur dans une closure) :</p><div class="highlight"><pre><span class="k">let</span> <span class="n">pack</span> <span class="err">é</span><span class="n">l</span><span class="err">é</span><span class="n">ment</span> <span class="o">=</span> <span class="o">{</span> <span class="n">app</span> <span class="o">=</span> <span class="o">(</span><span class="k">fun</span> <span class="o">{</span><span class="n">op</span> <span class="o">=</span> <span class="n">op</span><span class="err">é</span><span class="n">rateur</span><span class="o">}</span> <span class="o">-&gt;</span> <span class="n">op</span><span class="err">é</span><span class="n">rateur</span> <span class="err">é</span><span class="n">l</span><span class="err">é</span><span class="n">ment</span><span class="o">)</span> <span class="o">}</span>
</pre></div><p>Il y a là le principe des types existentiels ; cacher un type dans une closure pour offrir une interface commune. C'est une possibilité  également offerte par les langages orientés objets (et elle est nettement plus utilisée dans les langages OO ceci dit).</p><p>Rappelons que notre type que l'on veut quantifier est <code>'a * ('a -&gt; 'a)</code>. Imaginons que nous souhaitons écrire une fonction <code>next</code> qui retourne l'état suivant. Il s'agit ici d'un opérateur que l'on peut définir ainsi :</p><div class="highlight"><pre><span class="k">let</span> <span class="n">suivant</span> <span class="o">=</span> <span class="o">{</span> <span class="n">op</span> <span class="o">=</span> <span class="o">(</span><span class="k">fun</span> <span class="o">(</span><span class="err">é</span><span class="n">tat</span><span class="o">,</span> <span class="n">transition</span><span class="o">)</span> <span class="o">-&gt;</span> <span class="n">pack</span> <span class="o">(</span><span class="n">transition</span> <span class="err">é</span><span class="n">tat</span><span class="o">,</span> <span class="n">transition</span><span class="o">)</span> <span class="o">}</span>
</pre></div><p>Il ne faut pas oublier d'empaqueter le résultat au risque de rencontrer une vive réaction de caml. Pour l'appliquer il suffit de faire :</p><div class="highlight"><pre><span class="o">(</span><span class="n">pack</span> <span class="o">(</span><span class="mi">4</span><span class="o">,</span> <span class="n">succ</span><span class="o">)).</span><span class="n">app</span> <span class="n">suivant</span>
</pre></div><p>À propos de l'exemple : si on est sûr que l'interface ne bougera pas, on peut extrêment simplifier le problème en identifiant un objet à son interface — en faisant un record de fonctions par exemple — ceci dit si l'interface est amenée à évoluer ce n'est pas forcément pratique.</p><p>Voici le code au complet, avec une petite variation au niveau des opérateurs, afin de leur permettre de prendre un paramètre en plus, c'est bien utile.</p><div class="highlight"><pre><span class="k">module</span> <span class="nc">Make</span> <span class="o">(</span><span class="nc">T</span> <span class="o">:</span> <span class="k">sig</span> <span class="k">type</span> <span class="k">'</span><span class="n">a</span> <span class="n">t</span> <span class="k">end</span><span class="o">)</span> <span class="o">:</span> <span class="k">sig</span>
  <span class="k">type</span> <span class="o">(</span><span class="k">'</span><span class="n">b</span><span class="o">,</span> <span class="k">'</span><span class="n">c</span><span class="o">)</span> <span class="n">op</span> <span class="o">=</span> <span class="o">{</span> <span class="n">op</span><span class="o">:</span> <span class="k">'</span><span class="n">a</span><span class="o">.</span> <span class="k">'</span><span class="n">b</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="nn">T</span><span class="p">.</span><span class="n">t</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">c</span> <span class="o">}</span>
  <span class="k">type</span> <span class="n">t</span>
  <span class="k">val</span> <span class="n">pack</span> <span class="o">:</span> <span class="k">'</span><span class="n">a</span> <span class="nn">T</span><span class="p">.</span><span class="n">t</span> <span class="o">-&gt;</span> <span class="n">t</span>
  <span class="k">val</span> <span class="n">exec</span> <span class="o">:</span> <span class="o">(</span><span class="k">'</span><span class="n">b</span><span class="o">,</span> <span class="k">'</span><span class="n">c</span><span class="o">)</span> <span class="n">op</span> <span class="o">-&gt;</span> <span class="o">(</span><span class="k">'</span><span class="n">b</span> <span class="o">-&gt;</span> <span class="n">t</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">c</span><span class="o">)</span>
<span class="k">end</span> 
<span class="o">=</span> <span class="k">struct</span>
  <span class="k">type</span> <span class="o">(</span><span class="k">'</span><span class="n">b</span><span class="o">,</span> <span class="k">'</span><span class="n">c</span><span class="o">)</span> <span class="n">op</span> <span class="o">=</span> <span class="o">{</span> <span class="n">op</span><span class="o">:</span> <span class="k">'</span><span class="n">a</span><span class="o">.</span> <span class="k">'</span><span class="n">b</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">a</span> <span class="nn">T</span><span class="p">.</span><span class="n">t</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">c</span> <span class="o">}</span>

  <span class="k">type</span> <span class="n">t</span> <span class="o">=</span> <span class="o">{</span> <span class="n">obj</span><span class="o">:</span> <span class="k">'</span><span class="n">b</span> <span class="k">'</span><span class="n">c</span><span class="o">.</span> <span class="k">'</span><span class="n">b</span> <span class="o">-&gt;</span> <span class="o">(</span><span class="k">'</span><span class="n">b</span><span class="o">,</span> <span class="k">'</span><span class="n">c</span><span class="o">)</span> <span class="n">op</span> <span class="o">-&gt;</span> <span class="k">'</span><span class="n">c</span> <span class="o">}</span>
  
  <span class="k">let</span> <span class="n">pack</span> <span class="n">obj</span> <span class="o">=</span> <span class="o">{</span>
    <span class="n">obj</span> <span class="o">=</span> <span class="o">(</span><span class="k">fun</span> <span class="n">x</span> <span class="o">{</span><span class="n">op</span><span class="o">=</span><span class="n">op</span><span class="o">}</span> <span class="o">-&gt;</span> <span class="n">op</span> <span class="n">x</span> <span class="n">obj</span><span class="o">)</span>
  <span class="o">}</span>

  <span class="k">let</span> <span class="n">exec</span> <span class="n">f</span> <span class="n">x</span> <span class="o">{</span><span class="n">obj</span> <span class="o">=</span> <span class="n">o</span><span class="o">}</span> <span class="o">=</span> <span class="n">o</span> <span class="n">x</span> <span class="n">f</span>
<span class="k">end</span>
</pre></div><p>Au programme de demain : des exemples d'applications dans notre projet. Stay tuned !</p><hr/><p>Notes :</p><p>[<a id="footnotes_1"/><a href="#footnotes1">1</a>] Il n'est pas évident que ce soit à la seule à vérifier cette propriété, mais étant donné les propriétés de ⇒, si A vérifie également cette propriété, on a immédiatement, ⊥ ⇔ A</p></div></content></entry>
<entry><title>Capitalist Tetris : W4</title><link rel="alternate" href="http://blog.iuwt.fr/articles/W4"/><id>tag:iuwt.fr,2009:http://blog.iuwt.fr/articles/W4</id><updated>2009-03-29T00:00:00Z</updated><link rel="tag:huoc.org,2009:atom/parent" href="tag:iuwt.fr,2009/"/><author><name>asmanur</name></author><category term="W4"/><summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"/></summary><content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>
Comme vous le savez, pour 
  <em>Capitalist Tetris</em>
, haveo et moi suivons un
mode de développement à la semaine. Grosso modo pendant la semaine on
réfléchit à ce qu’on va implémenter et comment on va le faire et le
week-end on code.
</p><p>Ça mérite donc un petit changelog.</p><h2>Coté serveur</h2><p>
À la base je devais ajouter au protocole la possibilité de choisir une
pièce pour un adversaire ainsi qu’envoyer aux clients leur score
lorsqu’il y a modification (lignes ou choix de pièces). Mais bon,
comme le serveur c’est un peu l’endroit où j’expérimente des trucs
louches et que le code commençait à être un peu lourd à écrire, j’ai
décidé d’implémenter une state monad dans le serveur (on va peut-être
s’en servir dans le client du coup parce que ça serait ptait encore
plus pratique :-°), et donc on dépend maintenant de
  <a class="extern" href="http://www.cas.mcmaster.ca/~carette/pa_monad/">pa_monad</a>
 (mais c’est dans le
repo).
</p><p>Résultat : le code est un peu plus long mais largement plus
maintenable et plus agréable à écrire.</p><h2>Coté client</h2><p>(c’est haveo qui parle là)
Le client tel qu’il était durant la W3 était difficilement
utilisable. Il fallait entrer ses commandes via stdin, les timers
n’étaient pas gérés et une grande partie du protocole n’était pas
gérée. La W4, en ce qui concerne le client, visait donc à résoudre ces
problèmes là.</p><p>Coté protocole, le client met maintenant à jour le score des joueurs
sur requête du serveur. Il est aussi capable de modifier les fields
des autres joueurs lorsque le serveur lui signale qu’une pièce est
tombée. Il peut aussi changer les pièces de ses adversaires.</p><p>Au niveau des commandes, l’interface clavier est opérationelle. Vous
pouvez enfin bouger votre pièce, la faire tomber, comme dans tout
Tetris.</p><p>En plus, vous avez de la chance, le timer qui fait descendre votre
pièce a aussi été mis en service. L’interface stdin est maintenant
obsolète mais devrait être conservée pour pouvoir faire du debug.</p><p>Enfin, j’ai fait quelques retouches graphiques, affichage de votre
field et de celui de votre adversaire ou, un peu plus anecdotique,
changement du background des fields pour le noir (après des tests très
poussés, j’ai décidé que ça faisait moins mal aux yeux).</p><p>
Pour les curieux, voici 
  <a class="extern" href="http://iuwt.fr/tetris/W4_Changelog.txt">le changelog darcs</a>
.
</p><h2>Vers le futur et l’au-delà</h2><p>Bon comme vous le voyez, plus le temps passe, plus le jeu devient
jouable. Bon là c’est pas encore jouable mais bon on y travaille.</p><p>Au programme de W5 :</p><ul>
  <li>des bugfixes, encore et toujours (peut-être même une buglist %) ;</li>
  <li>une amélioration du protocole, là c’est vraiment évident pour un
client de tricher, y’a quasiment aucun contrôle du coté du serveur
(et qu’on puisse savoir la prochaine pièce des gens pour comploter
toujours plus) ;</li>
  <li>une amélioration de l’interface du client ? (genre du texte par
exemple :-’)</li>
  <li>des vrais bindings clavier (ouais nan parce que hjkl ça pue,
vraiment).</li>
</ul></div></content></entry></feed>
