<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Le nid de dodo &#187; Intro</title>
	<atom:link href="https://blog.developpez.com/dodo/pcategory/intro/feed" rel="self" type="application/rss+xml" />
	<link>https://blog.developpez.com/dodo</link>
	<description></description>
	<lastBuildDate>Sat, 19 Oct 2024 00:29:26 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.1.42</generator>
	<item>
		<title>Le numéro de l&#8217;enum</title>
		<link>https://blog.developpez.com/dodo/p12021/intro/le-numero-de-lenum</link>
		<comments>https://blog.developpez.com/dodo/p12021/intro/le-numero-de-lenum#comments</comments>
		<pubDate>Wed, 05 Jun 2013 19:32:24 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[ensemble]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[enumeration]]></category>
		<category><![CDATA[identifiant]]></category>
		<category><![CDATA[label]]></category>
		<category><![CDATA[syntaxe]]></category>
		<category><![CDATA[table]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/dodo/?p=85</guid>
		<description><![CDATA[En langage C, la déclaration d&#8217;un enum énumère une liste d&#8217;identifiants associés avec cet enum (d&#8217;où son nom) et affecte une valeur numérique unique pour chacun d&#8217;entre eux. En Java, l&#8217;idée est la même mais les identifiants appartiennent au namespace de l&#8217;Enum et les valeurs peuvent être non-numériques. Exemple d&#8217;enum en C: &#40;C&#41; enum style &#123; plan, relief, creux, cadre &#125;; Le type enum de dodo est différent. En fait, il correspond au type des [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>En langage C, la déclaration d&rsquo;un enum énumère une liste d&rsquo;identifiants associés avec cet enum (d&rsquo;où son nom) et affecte une valeur numérique unique pour chacun d&rsquo;entre eux. En Java, l&rsquo;idée est la même mais les identifiants appartiennent au namespace de l&rsquo;Enum et les valeurs peuvent être non-numériques.</p>
<p>Exemple d&rsquo;enum en C:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#40;</span>C<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">enum</span> style <span style="color: #009900;">&#123;</span> plan<span style="color: #339933;">,</span> relief<span style="color: #339933;">,</span> creux<span style="color: #339933;">,</span> cadre <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></div>
<p>Le type enum de dodo est différent. En fait, il correspond au type des identifiants tels que &laquo;&nbsp;plan&nbsp;&raquo;; la différence est qu&rsquo;il n&rsquo;y a pas de liste d&rsquo;identifiants définie. Donc dodo permet de faire:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">enum</span> jour <span style="color: #339933;">=</span> creux &nbsp;<span style="color: #339933;"># euh, c'est un jour de la semaine ça?</span></div></div>
<p>Heureusement il y a moyen de définir quels enums peuvent être affectés à une variable.</p>
<p>Cela se fait à l&rsquo;aide d&rsquo;une variable d&rsquo;ensemble ou de table associative. Par exemple:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">enum</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#93;</span> style <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span>plan<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>relief<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>creux<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>cadre<span style="color: #009900;">&#93;</span></div></div>
<p>Dans cet exemple, style est un ensemble qui a quatre éléments. Un élément de cet ensemble est de type style.member, qui de par la déclaration est un enum&#8230; Mais dodo s&rsquo;assure que l&rsquo;élément est bien listé dans l&rsquo;ensemble!</p>
<p>On peut donc déclarer une variable comme un enum appartenant à l&rsquo;ensemble &laquo;&nbsp;style&nbsp;&raquo;:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">style.<span style="color: #202020;">member</span> s <span style="color: #339933;">=</span> creux &nbsp;<span style="color: #339933;"># ok, creux est un enum appartenant à l'ensemble</span></div></div>
<p>C&rsquo;est un concept puissant qui peut s&rsquo;appliquer à d&rsquo;autres types qu&rsquo;enum, par exemple si l&rsquo;on veut limiter la valeur d&rsquo;une chaîne de caractères à un ensemble de chaînes bien défini.</p>
<p>Pour associer une valeur numérique à chaque identifiant, il faut utiliser une table associative plutôt qu&rsquo;un ensemble:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">int</span><span style="color: #009900;">&#91;</span><span style="color: #000000; font-weight: bold;">enum</span> label<span style="color: #009900;">&#93;</span> jours <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span>lundi<span style="color: #339933;">:</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">,</span> mardi<span style="color: #339933;">:</span> <span style="color: #0000dd;">2</span><span style="color: #339933;">,</span> mercredi<span style="color: #339933;">:</span> <span style="color: #0000dd;">3</span><span style="color: #339933;">,</span> jeudi<span style="color: #339933;">:</span> <span style="color: #0000dd;">4</span><span style="color: #339933;">,</span> vendredi<span style="color: #339933;">:</span> <span style="color: #0000dd;">5</span><span style="color: #009900;">&#93;</span><br />
jours.<span style="color: #202020;">label</span> jour <span style="color: #339933;">=</span> mardi &nbsp;<span style="color: #339933;"># ok, mardi est associé avec l'entier 2 dans la table</span></div></div>
<p>Un enum qui appartient à deux ensembles peut être utilisé pour les deux. Mais un type d&rsquo;enum n&rsquo;est compatible que si l&rsquo;ensemble est inclus dans l&rsquo;autre. On pourrait faire:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">enum</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span><span style="color: #009900;">&#93;</span> semaine <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span>lundi<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>mardi<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>mercredi<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>jeudi<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>vendredi<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>samedi<span style="color: #339933;">,</span> <span style="color: #339933;">:</span>dimanche<span style="color: #009900;">&#93;</span><br />
semaine.<span style="color: #202020;">member</span> m <span style="color: #339933;">=</span> jour.<span style="color: #202020;">value</span> &nbsp;<span style="color: #339933;"># ok, l'ensemble de jours.label est inclus dans semaine</span></div></div>
<p>Dodo associe une valeur interne à chaque enum qu&rsquo;il rencontre pour pouvoir comparer les enums entre eux. Mais deux programmes dodo n&rsquo;utilisent pas la même valeur interne pour le même enum. Par exemple, &laquo;&nbsp;plan&nbsp;&raquo; dans un programme peut être associé avec la même valeur que &laquo;&nbsp;creux&nbsp;&raquo; dans l&rsquo;autre. Cela pose problème si ces programmes veulent échanger des données.</p>
<p>Pour pallier à cela, dodo demande que les enums échangés fassent toujours partie d&rsquo;un ensemble (on peut utiliser style.member mais pas directement enum), et les deux programmes s&rsquo;échangent la position d&rsquo;un élément dans l&rsquo;ensemble plutôt que sa valeur interne. De cette façon &laquo;&nbsp;plan&nbsp;&raquo; reste &laquo;&nbsp;plan&nbsp;&raquo; et ne se transfome pas en &laquo;&nbsp;creux&nbsp;&raquo; quand il est envoyé par message.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Langage à prototypes</title>
		<link>https://blog.developpez.com/dodo/p11940/langage/langage-a-prototypes</link>
		<comments>https://blog.developpez.com/dodo/p11940/langage/langage-a-prototypes#comments</comments>
		<pubDate>Fri, 26 Apr 2013 14:21:49 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>

		<guid isPermaLink="false">http://blog.developpez.com/dodo/?p=62</guid>
		<description><![CDATA[Une particularité intéressante de dodo est qu&#8217;il s&#8217;agit d&#8217;un langage prototypes, à l&#8217;instar de Javascript, qui est aussi fortement typé. Comment résoudre cet antagonisme? Nous y avons déjà touché dans l&#8217;article Le Modèle Objet de Dodo. En dodo, l&#8217;appartenance à un type implique que la variable dérive d&#8217;un prototype donné, et l&#8217;interface du type permet d&#8217;accéder ou manipuler la variable sur cette base. Dans cet épisode nous allons nous intéresser particulièrement aux prototypes. La façon [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Une particularité intéressante de dodo est qu&rsquo;il s&rsquo;agit d&rsquo;un langage prototypes, à l&rsquo;instar de Javascript, qui est aussi fortement typé. Comment résoudre cet antagonisme?</p>
<p>Nous y avons déjà touché dans l&rsquo;article <a href="http://blog.developpez.com/dodo/p6433/langage/le_modele_objet_de_dodo_partie_1" title="Le modèle objet de dodo – Partie 1">Le Modèle Objet de Dodo</a>. En dodo, l&rsquo;appartenance à un type implique que la variable dérive d&rsquo;un prototype donné, et l&rsquo;interface du type permet d&rsquo;accéder ou manipuler la variable sur cette base.</p>
<p>Dans cet épisode nous allons nous intéresser particulièrement aux prototypes.</p>
<p>La façon la plus directe d&rsquo;ajouter des fonctionnalités à une variable est d&rsquo;étendre son prototype.</p>
<p>Par exemple:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def point <span style="color: #339933;">=</span> new <span style="color: #993333;">struct</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">double</span> x<span style="color: #339933;">,</span> y<br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Nous allons décomposer cela.</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def point</div></div>
<p>Cela commence une déclaration de variable. Tous les noms de type commencent avec une majuscule, ce qui n&rsquo;est pas le cas de <em>point</em> donc il s&rsquo;agit d&rsquo;un nom de variable. Le mot <em>def</em> indique l&rsquo;inférence de type (ou plutôt de prototype) locale, comme &laquo;&nbsp;auto&nbsp;&raquo; en C++11. On s&rsquo;attend donc à une valeur d&rsquo;initialisation.</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #339933;">=</span> new <span style="color: #993333;">struct</span></div></div>
<p>Comme attendu, voici l&rsquo;initialisation de la variable introduite par &laquo;&nbsp;=&nbsp;&raquo;. Le mot-clef <em>new</em> veut dire que l&rsquo;expression étend un prototype, dans ce cas <em>struct</em>. Toute variable ou constante peut être utilisée comme prototype.</p>
<p>La variable <em>struct</em> est juste une structure vide, elle occupe zéro octet de mémoire et n&rsquo;a aucun attribut membre. Je vais noter sa valeur <strong>{}</strong> à la façon de Javascript.</p>
<p>Vu la nature de <em>struct</em>, il n&rsquo;y a pas vraiment d&rsquo;utilité à l&rsquo;utiliser comme prototype si l&rsquo;on n&rsquo;ajoute aucun membre. On s&rsquo;attend donc à ce qu&rsquo;un bloc de déclaration suive.</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">double</span> x<span style="color: #339933;">,</span> y<br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Voici le bloc de déclaration comme prévu. Celui-ci étend le prototype <em>struct</em> et par cela ajoute les attributs <em>x</em> et <em>y</em> en tant que membres de la variable <em>point</em>.</p>
<p>La variable <em>double</em> est utilisée comme prototype de <em>x</em> et <em>y</em>, qui prennent sa valeur (normalement <strong>0.0</strong>) puisque ils n&rsquo;ont pas de valeur d&rsquo;initialisation. C&rsquo;est l&rsquo;équivalent de <em>&laquo;&nbsp;def x = double; def y = double&nbsp;&raquo;</em>. L&rsquo;effet et la syntaxe sont les mêmes qu&rsquo;une déclaration de variable en C++ avec une valeur par défaut.</p>
<p>Quand un prototype est étendu avec de nouveaux attributs membres, l&rsquo;espace mémoire alloué est la somme de la taille du prototype et la taille des nouveaux attributs. Le prototype est copié au début de l&rsquo;espace mémoire, suivi par les attributs.</p>
<p>Dans le cas de <em>point</em> la valeur d&rsquo;initialisation est donc:</p>
<blockquote><p>{ {}, 0.0, 0.0 }</p></blockquote>
<p>Ceci occupe l&rsquo;espace de deux double puisque <em>struct</em> n&rsquo;occupe aucun espace mémoire.</p>
<p>Cette représentation en mémoire sert de guide à ce que l&rsquo;on peut faire avec la variable <em>point</em>. Par exemple, on peut lui assigner une nouvelle valeur comme <strong>(2.0, -1.33)</strong> puisque c&rsquo;est la notation de dodo pour une structure avec deux valeurs de (proto)type <em>double</em>, donc la représentation en mémoire est la même:</p>
<blockquote><p>{ {}, 2.0, -1.33 }</p></blockquote>
<p>Une propriété intéressante d&rsquo;avoir le prototype en tête de la structure est qu&rsquo;une variable ainsi structurée est compatible avec son prototype, et le prototype de son prototype, etc&#8230; Il suffit de se limiter aux premiers octets de la structure.</p>
<p>Par exemple, si l&rsquo;on étend le prototype <em>double</em> avec de nouveaux attributs membres pour une variable, cette variable peut être utilisée partout où un <em>double</em> est attendu. Cependant les attributs supplémentaires peuvent être perdus dans l&rsquo;opération.</p>
<p>Par exemple si l&rsquo;on fait:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">struct</span> struct_p <span style="color: #339933;">=</span> point</div></div>
<p>La variable <em>struct_p</em> n&rsquo;a pas d&rsquo;attributs <em>x</em> et <em>y</em> car son (proto)type est <em>struct</em> qui ne les a pas définis.</p>
<p>Ce qui est aussi intéressant de voir est quel est le type de retour d&rsquo;un fonction retournant plusieurs valeurs. En programmation classique, une fonction ne retourne qu&rsquo;une valeur:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def droite_1<span style="color: #009900;">&#40;</span>point p<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-&gt;</span> <span style="color: #b1b100;">return</span> point<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span> new p<span style="color: #009900;">&#40;</span>x<span style="color: #339933;">:</span> p.<span style="color: #202020;">x</span> <span style="color: #339933;">+</span> <span style="color:#800080;">1.0</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Ici la valeur retournée par <em>droite_1(point)</em> est représentée en mémoire par:</p>
<blockquote><p>{ {}, 1.0, 0.0 }</p></blockquote>
<p>Mais dodo permet aussi de retourner plus d&rsquo;une valeur. Cette notation révèle une autre caractéristique du langage dodo, le passage de continuations, qui n&rsquo;a pas de limitation:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def pos_droite_1<span style="color: #009900;">&#40;</span>point p<span style="color: #009900;">&#41;</span> <span style="color: #339933;">-&gt;</span> <span style="color: #b1b100;">return</span><span style="color: #009900;">&#40;</span><span style="color: #993333;">double</span><span style="color: #339933;">,</span> <span style="color: #993333;">double</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #b1b100;">return</span><span style="color: #009900;">&#40;</span>p.<span style="color: #202020;">x</span> <span style="color: #339933;">+</span> <span style="color:#800080;">1.0</span><span style="color: #339933;">,</span> p.<span style="color: #202020;">y</span><span style="color: #009900;">&#41;</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>La représentation en mémoire de ce que retourne <em>pos_droite_1(point)</em> est:</p>
<blockquote><p>{ 1.0, 0.0 }
</p></blockquote>
<p>D&rsquo;après ce que l&rsquo;on a vu auparavant, le premier élément de la structure est le prototype. Ici c&rsquo;est un <em>double</em>, donc on peut assigner la valeur de retour à une variable de (proto)type <em>double</em> de par la compatibilité avec le prototype:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #993333;">double</span> x1 <span style="color: #339933;">=</span> pos_droite_1<span style="color: #009900;">&#40;</span>point<span style="color: #009900;">&#41;</span></div></div>
<p>Mais dodo est aussi prêt à convertir la valeur de retour en <em>struct</em> étendue où toutes les valeurs retournées sont attributs membres, comme <em>x</em> et <em>y</em> dans <em>point</em>. On peut donc faire:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">point point1 <span style="color: #339933;">=</span> pos_droite_1<span style="color: #009900;">&#40;</span>point<span style="color: #009900;">&#41;</span></div></div>
<p>Où la représentation en mémoire de <em>point1</em> est la même que pour <em>droite_1(point)</em>:</p>
<blockquote><p>{ {}, 1.0, 0.0 }
</p></blockquote>
<p><!--next page--><br />
Il y a aussi des variables dont la représentation en mémoire dépend de l&rsquo;état d&rsquo;un ou plusieurs attributs membres. C&rsquo;est le cas en particulier de <em>class</em>, le prototype des objets, qui a pour seul attribut une lien vers l&rsquo;interface de l&rsquo;objet:</p>
<blockquote><p>{ Object }</p></blockquote>
<p>L&rsquo;interface de <em>class</em> est <em>Object</em>.</p>
<p>Toute classe d&rsquo;objets qui étend ce prototype a un lien vers sa propre interface, ce qui permet à dodo de connaître sa représentation en mémoire.</p>
<p>Par exemple:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">class Figure<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; point centre<br />
<span style="color: #009900;">&#125;</span></div></div>
<p>L&rsquo;instance par défaut de cette classe, l&rsquo;objet <em>Figure.instance</em>, est représenté en mémoire par:</p>
<blockquote><p>{ Figure, { {}, 0.0, 0.0 } }</p></blockquote>
<p>On peut définir la classe d&rsquo;objets <em>Cercle</em> qui étend <em>Figure</em>:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">def Cercle <span style="color: #339933;">=</span> new Figure<br />
<span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #993333;">double</span> rayon <span style="color: #339933;">=</span> <span style="color:#800080;">1.0</span><br />
<span style="color: #009900;">&#125;</span></div></div>
<p>Comme auparavant, le prototype est le premier membre de la structure pour <em>Cercle.instance</em>:</p>
<blockquote><p>{ { Cercle, { {}, 0.0, 0.0 } }, 1.0 }</p></blockquote>
<p>Mais si on assigne ceci à une variable de (proto)type <em>Figure.instance</em>, la valeur du lien (attribut dont dépend la représentation en mémoire) doit être changé en <em>Figure</em>:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Figure.<span style="color: #202020;">instance</span> figure <span style="color: #339933;">=</span> Cercle.<span style="color: #202020;">instance</span></div></div>
<p>Si ce n&rsquo;était pas le cas la variable figure mentirait sur son état, ce qui cause des problèmes. Dodo utilise la relation entre <em>Cercle</em> et <em>Figure</em> pour déterminer la valeur à utiliser pour le lien. En fin de compte la variable est représentée par:</p>
<blockquote><p>{ Figure, { {}, 0.0, 0.0 } }
</p></blockquote>
<p>Cela illustre bien que les prototypes ne se prêtent pas bien au polymorphisme. Si l&rsquo;on veut préserver la nature de <em>Cercle</em> de l&rsquo;objet, il faut utiliser le nom de la classe plutôt que son instance comme type:</p>
<div class="codecolorer-container c default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="c codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Figure figure_cercle <span style="color: #339933;">=</span> Cercle.<span style="color: #202020;">instance</span></div></div>
<p>Cette fois-ci, la représentation en mémoire de l&rsquo;objet <em>figure_cercle</em> reste inchangée car il n&rsquo;y a pas de contrainte sur la façon dont il est représenté:</p>
<blockquote><p>{ { Cercle, { {}, 0.0, 0.0 } }, 1.0 }
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gestion des chaînes de caractères</title>
		<link>https://blog.developpez.com/dodo/p11127/langage/gestion_des_chaines_de_caracteres</link>
		<comments>https://blog.developpez.com/dodo/p11127/langage/gestion_des_chaines_de_caracteres#comments</comments>
		<pubDate>Mon, 02 Jul 2012 01:44:13 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Représentation Une chaîne de caractères en dodo peut simplement s&#8217;écrire entre double guillemets. "Bonjour" Par défaut, le programme utilise le même encodage de caractères que le fichier source. Le compilateur détermine l&#8217;encodage du fichier à sa lecture. Cependant la détection d&#8217;encodage de fichier n&#8217;est pas une science exacte et dépend souvent de la configuration du système. Le compilateur doit permettre de fournir le nom d&#8217;un encodage de caractères au moment de la compilation. Pour choisir [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><strong>Représentation</strong></p>
<p>Une chaîne de caractères en dodo peut simplement s&rsquo;écrire entre double guillemets.</p>
<pre>   "Bonjour"
</pre>
<p>Par défaut, le programme utilise le même encodage de caractères que le fichier source. Le compilateur détermine l&rsquo;encodage du fichier à sa lecture. Cependant la détection d&rsquo;encodage de fichier n&rsquo;est pas une science exacte et dépend souvent de la configuration du système. Le compilateur doit permettre de fournir le nom d&rsquo;un encodage de caractères au moment de la compilation.</p>
<p>Pour choisir l&rsquo;encodage des caractères d&rsquo;une chaîne pour le programme il est possible de précéder les guillemets ouvrants avec un code. Par exemple, &laquo;&nbsp;x&nbsp;&raquo; est le code qui indique un encodage de caractères en UTF-16.<br />
Le compilateur traduit de l&rsquo;encodage du fichier en celui spécifié pour la chaîne de caractères.</p>
<p><strong>Contenu</strong></p>
<p>En fonction de l&rsquo;encodage sélectionné, les caractères qui composent la chaîne peuvent occuper un octet ou plus. Par exemple en BIG5 les caractères chinois occupent deux octets et les caractères latins n&rsquo;en occupent qu&rsquo;un.<br />
En Unicode il est même possible d&rsquo;utiliser plusieurs caractères &#8211; ou codepoints &#8211; pour écrire une lettre, par exemple un accent aigu et &laquo;&nbsp;e&nbsp;&raquo; font un &laquo;&nbsp;é&nbsp;&raquo;.</p>
<p><span id="more-22"></span></p>
<p>Au vu de ces considérations, on ne peut pas toujours faire correspondre une position absolue dans la chaîne avec un caractère. Cela signifie que pour obtenir, par exemple, le cinquième caractère de la chaîne il faut soit partir du premier caractère et avancer caractère par caractère, ou il faut utiliser une représentation interne différente pour les caractères.</p>
<p>Dodo considère que le choix d&rsquo;encodage du programmeur prend précédence, et n&rsquo;impose pas sa propre représentation interne des chaînes de caractères.<br />
En cela dodo est différent de Java et autres langages qui sont standardisés avec UTF-16 ou un autre encodage de caractères. Pour les opérations telles qu&rsquo;obtenir le cinquième caractère, une chaîne de caractères peut être convertie en un tableau de caractères de façon efficace.</p>
<p><strong>Caractères spéciaux</strong></p>
<p>En dodo il n&rsquo;y a pas de caractère d&rsquo;échappement prédéfini. Donc les caractères spéciaux peuvent simplement être insérés dans la chaîne, sans les précéder d&rsquo;un caractère d&rsquo;échappement. Cela implique aussi qu&rsquo;une chaîne de caractères ne peut pas contenir de double guillemet.</p>
<pre>
   "antislash: \, dollar: $, apostrophe: ', pourcent: %"</pre>
<p>Pour exprimer le double guillemet, les caractères de contrôle et les caractères qui ne peuvent pas être représentés à l&rsquo;aide de l&rsquo;encodage de caractères courant, dodo a une syntaxe pour un seul caractère:</p>
<pre>
   \"
   \n
   \u2030</pre>
<p>Un tel caractère peut être ajouté à une chaîne de caractères par concaténation. De plus, rien n&rsquo;empêche les fonctions comme sprintf() d&rsquo;interpréter certaines séquences de caractères comme des caractères échappés.</p>
<p><strong>Texte multi-ligne</strong></p>
<p>Dodo aide le programmeur à se rappeler de fermer une chaîne de caractères en rejetant une ligne qui a des guillemets ouvrants mais pas de guillemets fermants. A moins que la ligne suivante commence avec des guillemets.<br />
Si la ligne suivante commence avec des guillemets alors la chaîne de caractères continue à la ligne suivante, et ainsi de suite jusqu&rsquo;à une ligne qui contient des guillemets fermants.</p>
<pre>
   "ligne 1
   "ligne 2"</pre>
<p>L&rsquo;inconvénient est que cela fait un nombre impair de double-guillemets sur une ligne, ce qui ne plaît pas aux éditeurs de texte. Pour pallier à cela, on peut utiliser trois double-guillemets pour indiquer que la chaîne continue sur la ligne suivante.</p>
<pre>
   "ligne 1"""
   "ligne 2"</pre>
<p>
Cette syntaxe a aussi l&rsquo;avantage de révéler s&rsquo;il y a des espaces en fin de ligne.</p>
<p><strong>Conclusion</strong></p>
<p>En attribuant un encodage à chaque chaîne de caractères et en convertissant automatiquement de l&rsquo;encodage système vers l&rsquo;encodage spécifié, dodo permet un grand contrôle sur la représentation des chaînes de caractères dans le programme.</p>
<p>La gestion des chaînes de caractères dans dodo s&rsquo;efforce d&rsquo;apporter des réponses aux problèmes courants. Par exemple, les opérations sur les caractères et les opérations sur les codes sont clairement séparées.</p>
<p>
Si certains choix de syntaxe peuvent porter à débat (notamment l&rsquo;absence de caractère d&rsquo;échappement) ils ont leurs avantages et ne sont pas difficiles à s&rsquo;habituer.</p>
<p>A propos de la syntaxe, je vais refermer ce chapitre avec une proposition de syntaxe pour la concaténation de chaînes de caractères.<br />
Si une expression est une chaîne de caractères entre double guillemets, elle peut être suivie d&rsquo;une expression entre parenthèses et du reste de la chaîne de caractères. Il n&rsquo;est pas nécessaire de spécifier l&rsquo;encodage pour le reste de la chaîne.</p>
<pre>
   x"Utilisateur = "(\")(nom)(\")(\n)"Age = "(age)(\n)</pre>
<p>Qu&rsquo;en dites-vous?</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La programmation parallèle en dodo &#8211; Partie 3 &#8211; Les tâches et les variables partagées</title>
		<link>https://blog.developpez.com/dodo/p8238/langage/la_programmation_parallele_en_dodo_parti_2</link>
		<comments>https://blog.developpez.com/dodo/p8238/langage/la_programmation_parallele_en_dodo_parti_2#comments</comments>
		<pubDate>Mon, 26 Oct 2009 10:07:53 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>
		<category><![CDATA[Théorie]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le modèle de programmation parallèle basé sur les tâches et la mémoire partagée est le plus répandu aujourd&#8217;hui, on le retrouve en particulier dans Java, C# et C avec OpenMP. Variables partagées Pour utiliser une variable dans plusieurs fonctions en parallèle, il faut la déclarer partagée. De cette façon elle peut être modifiée de façon atomique (sans état intermédiaire) par ces fonctions. Un exemple de déclaration est: Share(&#60;this: Personne&#62;) externe Il faut utiliser le service [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le modèle de programmation parallèle basé sur les tâches et la mémoire partagée est le plus répandu aujourd&rsquo;hui, on le retrouve en particulier dans Java, C# et C avec OpenMP.<br />
<span id="more-19"></span><br />
<strong>Variables partagées</strong></p>
<p>Pour utiliser une variable dans plusieurs fonctions en parallèle, il faut la déclarer partagée. De cette façon elle peut être modifiée de façon atomique (sans état intermédiaire) par ces fonctions. Un exemple de déclaration est:</p>
<pre>Share(&lt;this: Personne&gt;) externe
</pre>
<p>Il faut utiliser le service <code class="codecolorer text default"><span class="text">share</span></code> (voir <a href="http://blog.developpez.com/dodo/p7842/langage/dodo/la-programmation-parallele-en-dodo-parti-1">passage de message</a>) pour modifier la variable, par exemple:</p>
<pre>.share!externe = inspecteur
share!externe.Visite(site)
</pre>
<p>Il faut comprendre cela comme si le programme envoie des commandes à la variable partagée, en fait il n&rsquo;attend pas que l&rsquo;opération soit effectuée (ou cause une erreur).</p>
<p>L&rsquo;envoi de commande peut produire un ou plusieurs résultats. Ces résultats deviennent disponibles au plus tard quand la méthode correspondante termine. D&rsquo;ici là l&rsquo;accès aux résultats est une opération bloquante.</p>
<p>Si une commande fait intervenir plusieurs variables dont la valeur n&rsquo;est pas encore connue, elle commence à être évaluée seulement après que la valeur pour chacune d&rsquo;elles est renseignée (progression en tout ou rien).</p>
<p>Les attributs de la variable partagée peuvent être accédés comme une variable normale. Si la variable a plusieurs états possibles, et son état courant ne donne pas accès à l&rsquo;attribut en question, alors la tâche courante bloque en attendant que la variable change d&rsquo;état.</p>
<p>Par exemple:</p>
<pre>def Inspecteur = new Personne
{
   __state incognito =&gt;
      # On ne révèle rien ici

   __state officiel =&gt;
      Matricule matricule
}
...
.share!externe = Inspecteur()
...
Matricule m = externe.matricule
</pre>
<p>La tâche courante bloque jusqu&rsquo;à ce que l&rsquo;inspecteur sorte de son incognito et devienne officiel. Pour une variable normale, on obtiendrait immédiatement une erreur.</p>
<p>Le service <code class="codecolorer text default"><span class="text">share</span></code> garantit que les opérations qu&rsquo;il gère s&rsquo;exécutent dans l&rsquo;ordre où elles apparaissent dans le programme (ordre séquentiel) pour une tâche donnée.</p>
<p><strong>Le bloc fork</strong></p>
<p>Si l&rsquo;on veut poursuivre d&rsquo;autres tâches en attendant qu&rsquo;une variable soit renseignée, il faut mettre l&rsquo;opération bloquante dans un bloc <code class="codecolorer text default"><span class="text">sync</span></code> ou <code class="codecolorer text default"><span class="text">fork</span></code> (les instructions d&rsquo;un <code class="codecolorer text default"><span class="text">fork</span></code> sont comprises dans un block <code class="codecolorer text default"><span class="text">sync</span></code> implicite):</p>
<pre>fork
{
   Matricule m = externe.matricule
   # utilise m...
}
# reste des opérations...
</pre>
<p>Cela permet en particulier de créer des gestionnaires d&rsquo;événement, dans le cas ci-dessus pour le changement d&rsquo;état de l&rsquo;inspecteur. Notez qu&rsquo;un bloc <code class="codecolorer text default"><span class="text">fork</span></code> ne commence à s&rsquo;exécuter que lorsque toutes les variables qu&rsquo;il utilise sont renseignées. Si l&rsquo;on ne veut pas attendre d&rsquo;avoir une valeur pour une variable particulière, il faut utiliser un bloc <code class="codecolorer text default"><span class="text">fork</span></code> (ou <code class="codecolorer text default"><span class="text">sync</span></code>) imbriqué. Par exemple:</p>
<pre>def _approuvé = share!principal.Approuve("Vérification du matricule inspecteur")
fork
{
   Matricule m = externe.matricule
   case:
      registre.contains(m) =&gt;
         def data = registre[m]
         # utilise data...
      else =&gt;
         fork: # Regarder si vérif approuvée ici seulement
            case if (_approuvé)
            {
               # Pas sur le registre! Faire quelque chose...
            }
         .
      }
   .
}
</pre>
<p>On peut écrire un gestionnaire d&rsquo;événements multiples avec la forme spéciale <code class="codecolorer text default"><span class="text">fork select</span></code>, qui s&rsquo;apparente à un bloc <code class="codecolorer text default"><span class="text">case</span></code> où les instructions correspondantes s&rsquo;exécutent dans un <code class="codecolorer text default"><span class="text">fork</span></code> quand la condition (garde) devient vraie. Le bloc <code class="codecolorer text default"><span class="text">fork select</span></code> continue de s&rsquo;exécuter jusqu&rsquo;à ce que le système devienne stable, c&rsquo;est-à-dire que toutes les variables ont une valeur connue.</p>
<p>La variable qui signale la fin du programme est <code class="codecolorer text default"><span class="text">runtime.process.exit</span></code>. Si celle-ci est utilisée comme garde d&rsquo;un <code class="codecolorer text default"><span class="text">fork select</span></code>, le gestionnaire d&rsquo;événements s&rsquo;exécute jusqu&rsquo;à la fin du programme.</p>
<p><a href="/dodo/p7793/langage/dodo/la-programmation-parallele-en-dodo-parti/">Partie 1 &#8211; Présentation</a><br />
<a href="/dodo/p7842/langage/dodo/la-programmation-parallele-en-dodo-parti-1/">Partie 2 &#8211; Le passage de messages</a><br />
<a href="/dodo/p8395/langage/dodo/la-programmation-parallele-en-dodo-parti-3/">Partie 4 &#8211; Les transactions</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dernières nouvelles</title>
		<link>https://blog.developpez.com/dodo/p10249/intro/dernieres_nouvelles</link>
		<comments>https://blog.developpez.com/dodo/p10249/intro/dernieres_nouvelles#comments</comments>
		<pubDate>Sun, 04 Sep 2011 00:48:13 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Flânerie]]></category>
		<category><![CDATA[Intro]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Quoi de neuf dans l&#8217;univers de dodo? Malgré les apparences, je ne suis pas resté complètement oisif. Documentation Pour une part j&#8217;ai commencé à mettre à jour la documentation du langage. Dites-moi ce que vous en pensez! Dodo &#8211; Introduction (anglais) Implémentation J&#8217;ai aussi fait des tentatives d&#8217;implémentation de dodo en d&#8217;autres langages. Je reparlerai de la version C une autre fois. Pour le moment, je vous invite à regarder cette adaptation du modèle objet [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Quoi de neuf dans l&rsquo;univers de dodo?</p>
<p>Malgré les apparences, je ne suis pas resté complètement oisif.</p>
<p><strong>Documentation</strong><br />
Pour une part j&rsquo;ai commencé à mettre à jour la documentation du langage. Dites-moi ce que vous en pensez!</p>
<p><a href="http://dodo.sourceforge.net/doc/Dodo-Introduction.html">Dodo &#8211; Introduction</a> (anglais)</p>
<p><strong>Implémentation</strong><br />
J&rsquo;ai aussi fait des tentatives d&rsquo;implémentation de dodo en d&rsquo;autres langages. Je reparlerai de la version C une autre fois. Pour le moment, je vous invite à regarder cette adaptation du modèle objet de dodo à Javascript (incomplet):<br />
<span id="more-27"></span><br />
<a href="https://gist.github.com/1170337">Source de la page</a></p>
<p>Si vous regardez tout en bas du source, vous verrez un petit programme d&rsquo;exemple qui fait appel à ce modèle objet adapté de dodo.</p>
<p>Je donne ici les correspondances de terme:</p>
<pre>
             Dodo                |            Javascript
_________________________________|________________________________
                                 |
 struct                          | struct
                                 |
 self                            | this
                                 |
 new var0(x: 1) {def z = 36}     | copy(var0, 'x', 1, {z: 36})
                                 |
 ^fonc                           | $fonc
                                 |
 class A {def coul="bleu"}       | var A = new Class({coul: "bleu"});
                                 |
 class B {B(n) {print(n)}}       | var B = new Class({}, {1: function(n)
                                 |         {print(n);}});
                                 |
                                 |   NOTE: "1" est le nombre d'arguments
                                 |   du constructeur
                                 |
 def C = new A {def p = 0}       | var C = new A.constructor({p: 0});
                                 |
 B(1000)                         | new B(1000)
                                 |
</pre>
<p>J&rsquo;ai bien tenté de rendre les variables construites par ce modèle non éditables comme en dodo mais celà fait appel au nouveau standard ECMAScript et mes connaissances de Javascript sont limitées.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>La programmation parallèle en dodo &#8211; Partie 4 &#8211; Les transactions</title>
		<link>https://blog.developpez.com/dodo/p8395/langage/la_programmation_parallele_en_dodo_parti_3</link>
		<comments>https://blog.developpez.com/dodo/p8395/langage/la_programmation_parallele_en_dodo_parti_3#comments</comments>
		<pubDate>Tue, 24 Nov 2009 11:24:47 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>
		<category><![CDATA[Théorie]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le concept de transaction est bien connu des utilisateurs de base de données, où il sert à grouper des opérations pour permettre l&#8217;accès concurrent et consistant aux données de la base. La programmation parallèle peut faire appel à la notion de transaction pour manipuler les variables partagées. Le principal intérêt de ce modèle est la simplicité d&#8217;utilisation et une efficacité meilleure que d&#8217;autres modèles comparables. Les transactions Une transaction en dodo est délimitée par un [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le concept de transaction est bien connu des utilisateurs de base de données, où il sert à grouper des opérations pour permettre l&rsquo;accès concurrent et consistant aux données de la base.</p>
<p>La programmation parallèle peut faire appel à la notion de transaction pour manipuler les variables partagées. Le principal intérêt de ce modèle est la simplicité d&rsquo;utilisation et une efficacité meilleure que d&rsquo;autres modèles comparables.</p>
<p><span id="more-20"></span></p>
<ol>
<li><strong>Les transactions</strong></p>
<p>Une transaction en dodo est délimitée par un bloc <code class="codecolorer text default"><span class="text">sync</span></code> qui contient les instructions qui font partie de la transaction. Ces instructions sont exécutées comme si il n&rsquo;y avait pas de parallélisme et nulle autre tâche n&rsquo;interfère avec son exécution.</p>
<p>En réalité ce n&rsquo;est pas tout à fait vrai, par défaut dodo triche pour éviter le rollback des transactions. En effet si le système détecte qu&rsquo;une transaction ne peut pas être complétée &laquo;&nbsp;comme si nulle autre tâche n&rsquo;interfère&nbsp;&raquo;, pour bien faire il faut annuler tout ce que la transaction a fait jusqu&rsquo;ici et recommencer du début! C&rsquo;est ce qu&rsquo;on appelle un rollback.</p>
<p>Nous verrons plus tard comment changer les options pour autoriser à nouveau les rollbacks et se conformer au principe d&rsquo;isolation. Voyons maintenant un exemple de bloc <code class="codecolorer text default"><span class="text">sync</span></code>:</p>
<pre>
sync
{
   .a = a + b
}
</pre>
<p>Pourquoi veut-on créer une transaction juste pour ajouter deux variables?</p>
<p> Eh bien si on y pense, il se pourrait qu&rsquo;une autre tâche intervienne entre le moment où les variables sont lues et le moment où <code class="codecolorer text default"><span class="text">a</span></code> est mise à jour, ce qui fait que la valeur finale ne sera pas vraiment <code class="codecolorer text default"><span class="text">a + b</span></code>. L&rsquo;utilisation d&rsquo;une transaction permet de protéger le bloc de code des influences extérieures.
</p>
<p>Pour prendre en compte la possibilité de rollback, il convient d&rsquo;indiquer à dodo comment annuler les changements déjà faits. Si par exemple f(a) cause un rollback on peut écrire:</p>
<pre>
sync
{
   .a = a + b ...&gt; __undo .a = a - b
   f(a)
}
</pre>
<p><em>Note:</em> Les instructions précédées de <code class="codecolorer text default"><span class="text">__undo</span></code> sont aussi exécutées en cas d&rsquo;exception, sauf si le gestionnaire d&rsquo;événements convertit l&rsquo;exception en <code class="codecolorer text default"><span class="text">return</span></code>. Un bloc <code class="codecolorer text default"><span class="text">sync</span></code> définit son propre gestionnaire d&rsquo;événements.</p>
</li>
<li><strong>Les variables versionnées</strong>
<p>Les variables partagées ordinaires ne sont pas de grande utilité dans le cadre des transactions, car leurs modifications sont généralement problématiques à annuler en cas de rollback. C&rsquo;est pourquoi on fait appel aux variables versionnées. Les modifications d&rsquo;une variable versionnée sont automatiquement annulées en cas de rollback.</p>
<p>Une variable versionnée a une partie commune, partagée entre toutes les tâches, et une partie locale qui est utilisée dans le cadre d&rsquo;une transaction. Quand la variable est lue dans une transaction, la partie partagée est copiée dans la partie locale ainsi que son numéro de version. C&rsquo;est ce qui permet à sa valeur de rester consistante tout au long de la transaction, même si une autre tâche intervient.</p>
<p>Quand la transaction a copié la valeur partagée de la variable dans sa partie locale, la variable est dans l&rsquo;état <code class="codecolorer text default"><span class="text">synchronized</span></code>.</p>
</li>
<li><strong>Les options de synchronisation</strong>
<p>Par défaut, dodo garantit que la transaction a une vue cohérente des données: il existe un moment dans le temps où toutes les variables de la transaction ont la valeur que la transaction a lue. C&rsquo;est la seule garantie des options par défaut (<code class="codecolorer text default"><span class="text">use: newest</span></code>). Pour l&rsquo;exemple précédent, si <code class="codecolorer text default"><span class="text">a</span></code> vaut <code class="codecolorer text default"><span class="text">0</span></code> et <code class="codecolorer text default"><span class="text">b</span></code> vaut <code class="codecolorer text default"><span class="text">3</span></code> au départ, et il y a trois tâches qui exécutent la transaction en parallèle, la valeur finale de <code class="codecolorer text default"><span class="text">a</span></code> peut être <code class="codecolorer text default"><span class="text">9, 6</span></code> ou bien <code class="codecolorer text default"><span class="text">3</span></code>. Il se peut même qu&rsquo;elle aille de <code class="codecolorer text default"><span class="text">6</span></code> à <code class="codecolorer text default"><span class="text">3</span></code> (inversion temporelle).</p>
<blockquote><p>Exemples d&rsquo;exécution<br />
<em>Valeur lue par la troisième tâche en <ins>vert</ins>, valeur écrite par la troisième tâche en <strong>gras</strong><br />
</em><br />
temps &#8212;&#8211;&gt;<br />
<strong>a</strong>: 0 , 3 , <ins>6</ins> , <strong>9</strong><br />
temps &#8212;&#8211;&gt;<br />
<strong>a</strong>: 0 , <ins>3 </ins>, 6 , <strong>6</strong><br />
temps &#8212;&#8211;&gt;<br />
<strong>a</strong>: <ins>0</ins> , 3 , 6 , <strong>3</strong>
</p></blockquote>
<p>Si l&rsquo;on veut assurer la consistence temporelle, et s&rsquo;assurer que la variable a des valeurs qui se suivent de façon logique dans le temps, on peut choisir l&rsquo;option suivante:</p>
<pre>
__handle (use: first)
</pre>
<p>Cela indique à dodo que la valeur ne devrait pas être remplacée si la version utilisée par la transaction n&rsquo;est plus celle que contient la variable partagée. Une fois encore, cette option ne cause pas de rollbacks.</p>
<p>Cependant, avec ceci il se peut qu&rsquo;une variable soit mise à jour alors qu&rsquo;une autre ne l&rsquo;est pas &#8212; la transaction n&rsquo;assure pas vraiment la cohérence des données mises à jour. C&rsquo;est pourquoi dodo ne garantit pas une vue cohérente des données avec cette option.</p>
<blockquote><p>
<em>Effet de l&rsquo;option </em>use: first<em> sur les conflits de version avec une transaction parallèle (en <ins>vert</ins>)</em></p>
<pre>
sync
{
   .a *= b
   ++.b
}

Val. lue/écrite     a  b  |  a  b  |  a  b
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -
Début transaction   3  2  |  3  2  |  3  2  
Fin transaction     <ins>5</ins>  2  |  3  <ins>4</ins>  |  3  2
Valeur locale       <ins>6</ins>  3  |  6  <ins>3</ins>  |  6  3
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -
<strong>Valeur partagée     5  3  |  6  4  |  6  3</strong>
-  -  -  -  -  -  -  -  -  -  -  -  -  -  -
</pre>
</blockquote>
<p>Pour obtenir davantage de garanties il faut autoriser les rollbacks. Le premier exemple de transaction avec rollback est avec les options:</p>
<pre>
__handle (use: newest, action: fail)
</pre>
<p>Ces options sont similaires aux options par défaut, mais si dodo détecte une inversion temporelle les opérations sont annulées et la transaction s&rsquo;exécute à nouveau. Dans les exemples d&rsquo;exécution précédents le dernier ne serait pas possible.</p>
<p>Finalement, ces options apportent toutes les garanties que l&rsquo;on peut attendre d&rsquo;une transaction:</p>
<pre>
__handle (use: first, action: fail)
</pre>
<p>Cela indique à dodo que la transaction doit être réexécutée si la version utilisée par la transaction n&rsquo;est plus celle que contient la variable partagée quand elle est mise à jour. De plus ces options assurent une vue cohérente des données. Dès lors la seule exécution possible est:</p>
<blockquote><p><strong>a</strong>: 0 3 <ins>6</ins> <strong>9</strong></p></blockquote>
<p>Les options de synchronisation peuvent s&rsquo;appliquer à une variable particulière avec la notation <code class="codecolorer text default"><span class="text">__handle variable</span></code>.</p>
</li>
<li><strong>Bloc <code class="codecolorer text default"><span class="text">sync</span></code> conditionnel</strong>
<p>Le bloc <code class="codecolorer text default"><span class="text">sync</span></code> conditionnel s&rsquo;écrit:</p>
<pre>
sync select
{
   condition1 =&gt;
      ...transaction1...
   condition2 =&gt;
      ...transaction2...
   ...
}
</pre>
<p>Les variables utilisées dans la condition font partie de la transaction. Si les conditions sont réunies mais par la suite, la transaction sélectionnée fait un rollback, alors dodo teste les conditions de la transaction suivante. Si nulle transaction n&rsquo;a de succès, alors le bloc <code class="codecolorer text default"><span class="text">sync</span></code> entier fait un rollback. Une erreur est signalée si aucune transaction n&rsquo;a été tentée dans un bloc <code class="codecolorer text default"><span class="text">sync</span></code> conditionnel.</p>
<p>La condition spéciale <code class="codecolorer text default"><span class="text">default</span></code> indique qu&rsquo;aucune autre condition n&rsquo;est remplie; de fait, la condition <code class="codecolorer text default"><span class="text">default</span></code> n&rsquo;est pas remplie si l&rsquo;exécution d&rsquo;une autre transaction a été tentée mais s&rsquo;est soldée par un rollback. L&rsquo;utilisation de <code class="codecolorer text default"><span class="text">default</span></code> permet d&rsquo;assurer qu&rsquo;au moins une transaction est tentée.</p>
</li>
<li><strong>Transaction à l&rsquo;intérieur d&rsquo;une transaction</strong>
<p>Si le bloc <code class="codecolorer text default"><span class="text">sync</span></code> se trouve à l&rsquo;intérieur d&rsquo;un autre bloc <code class="codecolorer text default"><span class="text">sync</span></code>, cela définit une sous-transaction. Les changements faits dans la sous-transaction ne sont effectifs que quand la transaction englobante termine avec succès. En cas de rollback de la sous-transaction, la transaction englobante fait aussi l&rsquo;objet d&rsquo;un rollback. Le reste dépend des options de synchronisation.</p>
<p>Avec les options de synchronisation par défaut (<code class="codecolorer text default"><span class="text">use: newest</span></code>), dodo assure une vue cohérente des données de la sous-transaction à un moment dans le temps. Mais celle-ci peut différer de la vue de la transaction englobante.</p>
<p>Avec l&rsquo;option de consistance temporelle (<code class="codecolorer text default"><span class="text">use: first</span></code>), la vue de la transaction englobante est réutilisée.</p>
<p>Si les rollbacks sont autorisés en cas d&rsquo;inversion temporelle (<code class="codecolorer text default"><span class="text">use: first, action: fail</span></code>), l&rsquo;inversion temporelle est détectée quand une variable est lue ou mise à jour dans la sous-transaction.</p>
<p>Finalement avec toutes les garanties en place (<code class="codecolorer text default"><span class="text">use: first, action: fail</span></code>), la vue de la transaction englobante est réutilisée. La version des variables de la sous-transaction est testée quand elles sont mises à jour.</p>
<p><em>Note:</em> Une variable versionnée est synchronisée avant d&rsquo;être passée en paramètre à une fonction contenant potentiellement une transaction.</p>
</li>
</ol>
<p>Les blocs <code class="codecolorer text default"><span class="text">sync</span></code> conditionnels et emboîtés permettent la composition de transactions.</p>
<p><a href="/dodo/p7793/langage/dodo/la-programmation-parallele-en-dodo-parti/">Partie 1 &#8211; Présentation</a><br />
<a href="/dodo/p7842/langage/dodo/la-programmation-parallele-en-dodo-parti-1/">Partie 2 &#8211; Le passage de messages</a><br />
<a href="/dodo/p8238/langage/dodo/la-programmation-parallele-en-dodo-parti-2/">Partie 3 &#8211; Les tâches et les variables partagées</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La gestion d&#8217;exception de dodo en action</title>
		<link>https://blog.developpez.com/dodo/p9311/intro/la_gestion_d_exception_de_dodo_en_action</link>
		<comments>https://blog.developpez.com/dodo/p9311/intro/la_gestion_d_exception_de_dodo_en_action#comments</comments>
		<pubDate>Thu, 23 Sep 2010 02:09:14 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour introduire le système d&#8217;exceptions de dodo (je préfère parler d&#8217;événements) je propose de s&#8217;atteler à une tâche simple, la traduction d&#8217;une méthode Java gérant les exceptions dans le langage dodo. Sans plus d&#8217;ambages, voici la méthode en question: private void openStore() { try { store = RecordStore.openRecordStore("CALCULATOR", true); for (int recordId = 1, last = store.getNextRecordID(); recordId &#60; last; recordId++) { byte[] record = null; try { record = store.getRecord(recordId); } catch (InvalidRecordIDException x) [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Pour introduire le système d&rsquo;exceptions de dodo (je préfère parler d&rsquo;<em>événements</em>) je propose de s&rsquo;atteler à une tâche simple, la traduction d&rsquo;une méthode Java gérant les exceptions dans le langage dodo.</p>
<p>Sans plus d&rsquo;ambages, voici la méthode en question:</p>
<pre>private void openStore() {
    try {
        store = RecordStore.openRecordStore("CALCULATOR", true);
        for (int recordId = 1, last = store.getNextRecordID(); recordId &lt; last; recordId++) {
            byte[] record = null;
            try {
                record = store.getRecord(recordId);
            } catch (InvalidRecordIDException x) {
                // record was deleted
            }
            if (record == null) {
                continue;
            }
            Statement stmt = new Statement(recordId, record);
            try {
                Compiler compiler = new Compiler(stmt.text);
                Compiler.Expression expr = compiler.compile();
                if (expr instanceof Compiler.Declaration) {
                    ((Compiler.Declaration)expr).declare(bindings);
                }
                stmt.state = Statement.COMPILED;
            } catch (CompileError x) {
                stmt.state = Statement.ERROR;
            }

            statements.addElement(stmt);
        }
    } catch(Exception x) {
    }
}
</pre>
<p><span id="more-4"></span><br />
On note trois blocs <code class="codecolorer text default"><span class="text">try</span></code>, le plus extérieur d&rsquo;entre eux se bornant à avaler toutes les exceptions qui pourraient échapper la partie intérieure.</p>
<p>Commençons par créer une méthode dodo. Cette méthode a des effets de bord, on ne peut donc pas recourir à la création d&rsquo;une fonction ordinaire.</p>
<p>Pour mémoire une méthode dodo commence par <code class="codecolorer text default"><span class="text">method</span></code>, suivi de son nom qui doit commencer en majuscule car l&rsquo;on déclare un nouveau type. Dans notre cas on n&rsquo;a pas besoin de variables ou de fonctions auxiliaires, alors le constructeur n&rsquo;est pas défini dans le bloc de la méthode.</p>
<p>On écrit donc:</p>
<pre>method OpenStore()
{
    ...
}
</pre>
<p>Maintenant écrivons le corps de la méthode. En première approximation nous allons essayer de reproduire exactement le code Java.</p>
<pre>method OpenStore()
{
    try {
        .store = RecordStore.OpenRecordStore("CALCULATOR", true)
        loop for (int recordId, last = (1, store.getNextRecord);
                  recordId &lt; last; ++.recordId) {
            byte[] record = null
            try {
                .record = store.getRecord(recordId)
            }
    ...
}
</pre>
<p>Pour affecter une valeur à la variable store, il faut en prendre sa référence; cela est marqué par un point devant son nom. Dans un effort pour réduire le nombre de noms réservés en dodo, toutes les boucles commencent par <code class="codecolorer text default"><span class="text">loop</span></code>.<br />
<br />
<hr />
<p></p>
<p>À ce point on arrive au premier bloc <code class="codecolorer text default"><span class="text">catch</span></code> du programme. Mais dodo n&rsquo;autorise pas à écrire un bloc <code class="codecolorer text default"><span class="text">catch</span></code> à l&rsquo;intérieur d&rsquo;un autre bloc. Comment traduire le programme en dodo?</p>
<p>Regardons encore ce que fait le bloc catch en question dans le programme original:</p>
<pre>            } catch (InvalidRecordIDException x) {
                // record was deleted
            }
</pre>
<p>Ce bloc ne fait rien, il se contente d&rsquo;avaler silencieusement une exception InvalidRecordIDException. En assumant que <code class="codecolorer text default"><span class="text">getRecord</span></code> ne jette pas une exception différente, on peut considérer tout ce qui suit comme faisant part d&rsquo;un bloc <code class="codecolorer text default"><span class="text">finally</span></code>.</p>
<p>Cela tombe bien, en dodo ce qui suit un bloc <code class="codecolorer text default"><span class="text">try</span></code> est l&rsquo;équivalent d&rsquo;un bloc <code class="codecolorer text default"><span class="text">finally</span></code>. Donc on peut continuer en ignorant le bloc <code class="codecolorer text default"><span class="text">catch</span></code>:</p>
<pre>method OpenStore()
{
    try {
        .store = RecordStore.OpenRecordStore("CALCULATOR", true)
        loop for (int recordId, last = (1, store.getNextRecord);
                  recordId &lt; last; ++.recordId) {
            byte[] record = null
            try {
                .record = store.getRecord(recordId)
            }
            case if (record = null) {
                continue()
            }
            def stmt = Statement(recordId, record)
    ...
}
</pre>
<p>Ici on construit un nouveau <em>Statement</em> avec les paramètres de constructeur <em>(recordId, record)</em>. Notez que l&rsquo;on utilise pas <code class="codecolorer text default"><span class="text">new</span></code> devant un constructeur. C&rsquo;est ce qui permet aux méthodes d&rsquo;être appelées comme des fonctions ordinaires, même si elles sont déclarées comme des types. De plus je n&rsquo;ai pas spécifié le type de <code class="codecolorer text default"><span class="text">stmt</span></code>. Si ce type correspond au type de retour de l&rsquo;expression, il suffit d&rsquo;utiliser &laquo;&nbsp;<code class="codecolorer text default"><span class="text">def</span></code>&nbsp;&raquo; et dodo se charge de donner le type approprié à la variable.</p>
<p>On arrive maintenant à un nouveau bloc <code class="codecolorer text default"><span class="text">try</span></code>. Cela ne devrait pas poser de difficulté particulière:</p>
<pre>method OpenStore()
{
    try {
        .store = RecordStore.OpenRecordStore("CALCULATOR", true)
        loop for (int recordId, last = (1, store.getNextRecord); 
                  recordId &lt; last; ++.recordId) {
            byte[] record = null
            try {
                .record = store.getRecord(recordId)
            }
            case if (record = null) {
                continue()
            }
            def stmt = Statement(recordId, record)
            try {
                def compiler = Compiler(stmt.text)
                def expr = compiler.compile
                case if (expr ~ ?Compiler.Declaration):
                    expr.Declare(bindings).
                .stmt.state = Statement.compiled
            }
    ...
}
</pre>
<p>On retrouve à nouveau le motif <code class="codecolorer text default"><span class="text">def variable = Constructeur(...)</span></code>, une notation à la simplicité bienvenue par rapport à Java. Le mot-clef <code class="codecolorer text default"><span class="text">case</span></code> est utilisé pour tous les branchements conditionnels comme <code class="codecolorer text default"><span class="text">loop</span></code> pour les boucles. Dodo a aussi la forme <code class="codecolorer text default"><span class="text">if ( ) ... else</span></code> mais elle ne s&rsquo;utilise que pour les expressions, l&rsquo;équivalent de <code class="codecolorer text default"><span class="text">( )? ... :</span></code> en Java.</p>
<p>Le test du type de la variable se fait par correspondance de patron (<em>pattern matching</em>), où le patron est ici introduit par &laquo;&nbsp;<code class="codecolorer text default"><span class="text">?</span></code>&nbsp;&raquo; suivi du nom du type. On peut aussi insérer d&rsquo;autres critères avant le point d&rsquo;interrogation, par exemple pour tester la valeur d&rsquo;un attribut de la variable.<br />
<br />
<hr />
<p></p>
<p>Nous voici donc à nouveau devant un bloc <code class="codecolorer text default"><span class="text">catch</span></code> qui suit un bloc <code class="codecolorer text default"><span class="text">try</span></code>. Cette fois-ci peut-on l&rsquo;ignorer comme s&rsquo;il n&rsquo;existait pas? Pas vraiment, cette fois-ci le bloc contient une instruction. Mais comme on arrive à la fin de la fonction il est peut-être raisonnable de décaler le bloc <code class="codecolorer text default"><span class="text">catch</span></code> un peu plus bas, en-dehors des autres blocs. Voici ce que cela donne:</p>
<pre>method OpenStore()
{
    try {
        .store = RecordStore.OpenRecordStore("CALCULATOR", true)
        loop for (int recordId, last = (1, store.getNextRecord);
                  recordId &lt; last; ++.recordId) {
            byte[] record = null
            try {
                .record = store.getRecord(recordId)
            }
            case if (record = null) {
                continue()
            }
            def stmt = Statement(recordId, record)
            try {
                def compiler = Compiler(stmt.text)
                def expr = compiler.compile
                case if (expr ~ ?Compiler.Declaration):
                    expr.Declare(bindings).
                .stmt.state = Statement.compiled
            }
            statements.AddElement(stmt)
        }
    }
    catch (event: ?CompileError) {
        .stmt.state = Statement.error
    }
    ...
}
</pre>
<p>L&rsquo;exception est comparée au patron fourni à <code class="codecolorer text default"><span class="text">catch</span></code>, et si elle correspond le bloc est exécuté.</p>
<p>On voit un problème ici: l&rsquo;instruction du <code class="codecolorer text default"><span class="text">catch</span></code> fait appel à la variable <code class="codecolorer text default"><span class="text">stmt</span></code>, qui n&rsquo;est pas déclarée au plus haut niveau de la méthode. Mais dodo ne s&rsquo;en formalise pas; si l&rsquo;exception se produit là où la variable <code class="codecolorer text default"><span class="text">stmt</span></code> est déclarée, alors l&rsquo;instruction est valide. Ailleurs l&rsquo;instruction produit une nouvelle exception. Si nécessaire, on peut restreindre le bloc <code class="codecolorer text default"><span class="text">catch</span></code> aux exceptions jetées après une étiquette de notre choix ce qui permet d&rsquo;éviter les variables non déclarées.<br />
<br />
<hr />
<p></p>
<p>Il ne manque plus qu&rsquo;à ajouter le bloc <code class="codecolorer text default"><span class="text">catch</span></code> du <code class="codecolorer text default"><span class="text">try</span></code> englobant qui avale toutes les exceptions. On obtient:</p>
<pre>method OpenStore()
{
    try {
        .store = RecordStore.OpenRecordStore("CALCULATOR", true)
        loop for (int recordId, last = (1, store.getNextRecord);
                  recordId &lt; last; ++.recordId) {
            byte[] record = null
            try {
                .record = store.getRecord(recordId)
            }
            case if (record = null) {
                continue()
            }
            def stmt = Statement(recordId, record)
            try {
                def compiler = Compiler(stmt.text)
                def expr = compiler.compile
                case if (expr ~ ?Compiler.Declaration):
                    expr.Declare(bindings).
                .stmt.state = Statement.compiled
            }
            statements.AddElement(stmt)
        }
    }
    catch (event: ?CompileError) {
        .stmt.state = Statement.error
    }
    catch {
    }
}
</pre>
<p>Certes ce programme correspond bien au programme Java initial, mais l&rsquo;on a pas profité de toutes les possibilités de dodo en terme de gestion d&rsquo;exception. Pour commencer, à quoi bon écrire un bloc <code class="codecolorer text default"><span class="text">try</span></code> si il n&rsquo;y a pas d&rsquo;instructions à exécuter par la suite? Puisqu&rsquo;un bloc <code class="codecolorer text default"><span class="text">catch</span></code> n&rsquo;est pas attaché à un bloc <code class="codecolorer text default"><span class="text">try</span></code> particulier, la gestion d&rsquo;exception intervient même s&rsquo;il n&rsquo;y a pas de <code class="codecolorer text default"><span class="text">try</span></code>. Enlevons donc ce bloc <code class="codecolorer text default"><span class="text">try</span></code> superflu:</p>
<pre>method OpenStore()
{
    .store = RecordStore.OpenRecordStore("CALCULATOR", true)
    loop for (int recordId, last = (1, store.getNextRecord); 
              recordId &lt; last; ++.recordId) {
        byte[] record = null
        try {
            .record = store.getRecord(recordId)
        }
        case if (record = null) {
            continue()
        }
        def stmt = Statement(recordId, record)
        try {
            def compiler = Compiler(stmt.text)
            def expr = compiler.compile
            case if (expr ~ ?Compiler.Declaration):
                expr.Declare(bindings).
            .stmt.state = Statement.compiled
        }
        statements.AddElement(stmt)
    }
    catch (event: ?CompileError) {
        .stmt.state = Statement.error
    }
    catch {
    }
}
</pre>
<p>Ensuite on voit là un motif intéressant:</p>
<pre>        def stmt = Statement(recordId, record)
        try {
            ...
        }
        statements.AddElement(stmt)
</pre>
<p>Ici on initialise la variable <code class="codecolorer text default"><span class="text">stmt</span></code>, on exécute un bloc <code class="codecolorer text default"><span class="text">try</span></code>, puis finalement on ajoute la variable à une liste à l&rsquo;aide d&rsquo;une seule instruction. Cette dernière s&rsquo;exécute aussi bien en cas de succès qu&rsquo;en cas d&rsquo;exception.<br />
<br />
<hr />
<p></p>
<p>Dodo propose une notation spéciale pour ce motif qui rend le programme plus succinct. L&rsquo;instruction finale remonte au niveau de l&rsquo;instruction d&rsquo;initialisation, et tout ce qui suit fait partie d&rsquo;un bloc <code class="codecolorer text default"><span class="text">try</span></code> implicite. Je l&rsquo;utilise dans le programme ci-dessous.</p>
<pre>method OpenStore()
{
    .store = RecordStore.OpenRecordStore("CALCULATOR", true)
    loop for (int recordId, last = (1, store.getNextRecord);
              recordId &lt; last; ++.recordId) {
        byte[] record = null
        try {
            .record = store.getRecord(recordId)
        }
        case if (record = null) {
            continue()
        }
        def stmt = Statement(recordId, record) ...&gt; statements.AddElement(stmt)
        def compiler = Compiler(stmt.text)
        def expr = compiler.compile
        case if (expr ~ ?Compiler.Declaration):
            expr.Declare(bindings).
        .stmt.state = Statement.compiled
    }
    catch (event: ?CompileError) {
        .stmt.state = Statement.error
    }
    catch {
    }
}
</pre>
<p>Enfin, on peut se débarrasser du dernier <code class="codecolorer text default"><span class="text">try</span></code> en remarquant que le <code class="codecolorer text default"><span class="text">continue</span></code> ne s&rsquo;exécute que si <code class="codecolorer text default"><span class="text">getRecord</span></code> a jeté une exception, auquel cas un bloc <code class="codecolorer text default"><span class="text">catch</span></code> peut intervenir. Au lieu de placer un <code class="codecolorer text default"><span class="text">continue</span></code> dans ce bloc <code class="codecolorer text default"><span class="text">catch</span></code>, je vais utiliser <code class="codecolorer text default"><span class="text">resume</span></code> avec une étiquette judicieusement placée pour passer à l&rsquo;itération suivante de la boucle.</p>
<pre>method OpenStore()
{
    .store = RecordStore.OpenRecordStore("CALCULATOR", true)
    loop for (int recordId, last = (1, store.getNextRecord);
              @cond recordId &lt; last; ++.recordId) {
        def record = store.getRecord(recordId)
        def stmt = Statement(recordId, record) ...&gt; statements.AddElement(stmt)
        def compiler = Compiler(stmt.text)
        def expr = compiler.compile
        case if (expr ~ ?Compiler.Declaration):
            expr.Declare(bindings).
        .stmt.state = Statement.compiled
    }
    catch (event: ?InvalidRecordIDException) {    # record was deleted
        ++.recordId
        resume @cond
    }
    catch (event: ?CompileError) {
        .stmt.state = Statement.error
    }
    catch {
    }
}
</pre>
<p>En obligeant les blocs <code class="codecolorer text default"><span class="text">catch</span></code> à se situer en-dehors des autres blocs, et à l&rsquo;aide d&rsquo;autres astuces de notation, dodo permet d&rsquo;écrire des instructions qui ne se mélangent pas avec la gestion des cas exceptionnels. Le programme y gagne en clarté et en concision.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La programmation parallèle en dodo &#8211; Partie 2 &#8211; Le passage de messages</title>
		<link>https://blog.developpez.com/dodo/p7842/langage/la_programmation_parallele_en_dodo_parti_1</link>
		<comments>https://blog.developpez.com/dodo/p7842/langage/la_programmation_parallele_en_dodo_parti_1#comments</comments>
		<pubDate>Sat, 04 Jul 2009 08:11:18 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le modèle du passage de messages est très simple et il s’apparente au fonctionnement de l’Internet. Le client demande des informations par l’envoi d’un message (requête), et le serveur retourne un message (réponse) avec les informations requises, par exemple une page web. En attendant la réponse, le client peut s’occuper à d’autres tâches. Si les informations demandent du temps à être reçues, le client peut utiliser les données partielles pour commencer son travail, par exemple [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le modèle du passage de messages est très simple et il s’apparente au fonctionnement de l’Internet. Le client demande des informations par l’envoi d’un message (requête), et le serveur retourne un message (réponse) avec les informations requises, par exemple une page web. En attendant la réponse, le client peut s’occuper à d’autres tâches. Si les informations demandent du temps à être reçues, le client peut utiliser les données partielles pour commencer son travail, par exemple pour réserver de la place à une image dans une page.</p>
<p>Je ne vais pas poursuivre l’analogie du navigateur Internet plus loin. Mais vous pouvez la garder en tête quand je vais discuter le passage de message dans dodo, car les deux se rejoignent parfois.<br />
<span id="more-17"></span><br />
Dodo utilise un modèle client-serveur pour la programmation parallèle. Le partage de données se fait par envoi de messages, ce qui évite les problèmes de synchronisation liés à la mémoire partagée.</p>
<p><strong>Le client<br />
</strong><br />
L’envoi d’un message se fait de la façon suivante:</p>
<pre>service!capability.Message(arguments)
</pre>
<p>service est le nom du service requis, par exemple net désigne un service lié au réseau.<br />
capability est un objet qui donne accès à un certain aspect du service, par exemple la communication avec une adresse choisie.<br />
Message est le nom du message envoyé, par exemple Get pour demander le contenu à une adresse.<br />
arguments est une liste de données qui font partie du message, par exemple un nom de page web.</p>
<p>Pour recevoir le contenu de la page d’accueil de dodo, on peut faire:</p>
<pre>def dodohome = net.Connection("<a href="http://dodo.sourceforge.net">http://dodo.sourceforge.net</a>")
def contenu = net!dodohome.Get("index.html")
</pre>
<p>À partir de cet instant, on peut utiliser la variable contenu dans le programme. Cependant, sa valeur est future, ce qui signifie qu’elle n’est connue qu’à partir du moment où le service a répondu au message. Si l’on tente de lire sa valeur avant cela le programme va s’interrompre jusqu’à ce qu’elle soit disponible.</p>
<p>On peut définir un gestionnaire pour la variable à l’aide de handler, qui permet de limiter le délai de réponse, ou demander à dodo de répéter la requête si la réponse n’est pas retournée à temps.<br />
<!--nextPage--><br />
Dans l’exemple précédent, la capability est obtenue juste avant son utilisation. Souvent une capability est reçue en paramètre de la fonction. En effet les fonctions dodo, que l’on distingue des méthodes, n’autorisent pas les effets de bord. L’utilisation d’une capability permet de contourner cette limitation.</p>
<p><strong>Le serveur<br />
</strong><br />
Un serveur est un programme dodo qui est enregistré pour délivrer un certain service. Il offre aussi le moyen d’obtenir des capabilities qui permettent de s’assurer que le message provient d’un client autorisé.</p>
<p>Le serveur est démarré quand un client lui fait une requête, et peut être arrêté ou continuer en fonction des ressources disponibles et de son utilisation.</p>
<p>L’exemple ci-dessous illustre la définition d’un service. Dans cet exemple les possibilités de programmation parallèle apportées par les modèle client-serveur ne sont pas exploitées.</p>
<pre>__Service__ exemple
export capability DireHello:
    String nom

    message Parle(Link(&lt;with: DireHello&gt;) ressource)
    {
        console!Stdout().Puts("Hello, " + ressource.nom)
    }
.

__Module__ program
__Main__
def Main()
{
    def helloworld = new DireHello.instance(nom: "world")
    exemple!helloworld.Parle()
}
</pre>
<p><a href="/dodo/p7793/langage/dodo/la-programmation-parallele-en-dodo-parti/">Partie 1 &#8211; Présentation</a><br />
<a href="/dodo/p8238/langage/dodo/la-programmation-parallele-en-dodo-parti-2/">Partie 3 &#8211; Les tâches et les variables partagées</a><br />
<a href="/dodo/p8395/langage/dodo/la-programmation-parallele-en-dodo-parti-3/">Partie 4 &#8211; Les transactions</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La programmation parallèle en dodo &#8211; Partie 1 &#8211; Présentation</title>
		<link>https://blog.developpez.com/dodo/p7793/langage/la_programmation_parallele_en_dodo_parti</link>
		<comments>https://blog.developpez.com/dodo/p7793/langage/la_programmation_parallele_en_dodo_parti#comments</comments>
		<pubDate>Thu, 25 Jun 2009 00:17:09 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>
		<category><![CDATA[Théorie]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Pour être reconnu aujourd’hui, un nouveau langage se doit d’apporter des nouveautés dans le domaine de la programmation. Certains se distinguent en visant la facilité d’utilisation, ou en étant spécialisé pour une application précise. Mais ce à quoi tout le monde s’intéresse, c’est le parallélisme. En effet, les ordinateurs de bureau ont maintenant en général deux processeurs à leur coeur, voire plus. Pour bénéficier au maximum des avantages de ces processeurs il faut recourir à [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Pour être reconnu aujourd’hui, un nouveau langage se doit d’apporter des nouveautés dans le domaine de la programmation. Certains se distinguent en visant la facilité d’utilisation, ou en étant spécialisé pour une application précise. Mais ce à quoi tout le monde s’intéresse, c’est le parallélisme.<br />
<span id="more-16"></span><br />
En effet, les ordinateurs de bureau ont maintenant en général deux processeurs à leur coeur, voire plus. Pour bénéficier au maximum des avantages de ces processeurs il faut recourir à la programmation parallèle.</p>
<p>Les langages généralistes les plus répandus comme C, C++, Java, Visual Basic ou C# utilisent le modèle des tâches d’exécution (threads) avec mémoire partagée comme base du parallélisme. Ce modèle est en bonne adéquation avec le fonctionnement des processeurs. De plus, ces langages proposent (sous forme de bibliothèque) des outils pour le passage de messages entre processus. Cela peut aussi être utilisé pour la communication entre tâches à l’intérieur d’un même processus.</p>
<p>Le problème de la mémoire partagée c’est qu’elle induit des difficultés pratiquement insolubles aux programmeurs qui veulent l’exploiter. Il y a de bonnes chances de créer des situations ou la performance chute, ou bien deux tâches s’attendent indéfiniment l’une l’autre à cause de verrous mis en place pour protéger l’intégrité de la mémoire partagée. Pour y remédier on a inventé des mécanismes sans verrou, qui ont leurs propres problèmes et ne peuvent être utilisés partout.</p>
<p>Pour dodo j’ai préféré privilégier un autre modèle, celui du passage de messages. Il est toujours possible d’avoir deux tâches qui s’attendent indéfiniment (deadlock) mais ce modèle a la réputation d’être plus facile à utiliser et de causer moins de soucis aux programmeurs.</p>
<p>J’ai aussi prévu d’intégrer un modèle de mémoire partagée qui a l’avantage de détecter les situations de blocage, celui proposé par le projet Athapascan du <a href="http://www-id.imag.fr/">laboratoire ID-Imag</a>. Chaque modèle a ses avantages et je pense que dodo peut bénéficier de la combinaison de ces deux approches.</p>
<p>Je parlerai aussi des variables versionnées et des transactions, des concepts importants pour les applications concurrentes.</p>
<p><a href="/dodo/p7842/langage/dodo/la-programmation-parallele-en-dodo-parti-1/">Partie 2 &#8211; Le passage de messages</a><br />
<a href="/dodo/p8238/langage/dodo/la-programmation-parallele-en-dodo-parti-2/">Partie 3 &#8211; Les tâches et les variables partagées</a><br />
<a href="/dodo/p8395/langage/dodo/la-programmation-parallele-en-dodo-parti-3/">Partie 4 &#8211; Les transactions</a></p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Vers une première implémentation de dodo: la boucle de continuations</title>
		<link>https://blog.developpez.com/dodo/p9236/langage/vers_une_premiere_implementation_de_dodo</link>
		<comments>https://blog.developpez.com/dodo/p9236/langage/vers_une_premiere_implementation_de_dodo#comments</comments>
		<pubDate>Thu, 26 Aug 2010 00:43:23 +0000</pubDate>
		<dc:creator><![CDATA[bredelet]]></dc:creator>
				<category><![CDATA[Dodo]]></category>
		<category><![CDATA[Intro]]></category>
		<category><![CDATA[Langage]]></category>
		<category><![CDATA[Technique]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Le projet dodo a commencé il y a bien longtemps, et l&#8217;idée de mettre ses concepts en pratique me trottait dans la tête depuis un bon moment. Malheureusement je ne voyais pas clairement comment m&#8217;y prendre. Eh bien grâce à une suggestion que l&#8217;on m&#8217;a faite, il semble que j&#8217;aie finalement la solution. Pour pouvoir exécuter un programme dodo, le plus simple serait probablement d&#8217;écrire un interpréteur. Cependant j&#8217;anticipais des difficultés certaines avec cette approche [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Le projet dodo a commencé il y a bien longtemps, et l&rsquo;idée de mettre ses concepts en pratique me trottait dans la tête depuis un bon moment. Malheureusement je ne voyais pas clairement comment m&rsquo;y prendre.</p>
<p>Eh bien grâce à une suggestion que l&rsquo;on m&rsquo;a faite, il semble que j&rsquo;aie finalement la solution.<br />
<span id="more-7"></span><br />
Pour pouvoir exécuter un programme dodo, le plus simple serait probablement d&rsquo;écrire un interpréteur. Cependant j&rsquo;anticipais des difficultés certaines avec cette approche et comme il faudra de toute façon écrire un jour un compilateur pour questions de performance, le jeu n&rsquo;en vaut pas la chandelle.</p>
<p>Donc je voulais écrire un compilateur. Celui-ci va prendre en entrée un programme dodo, et produire en sortie un programme que l&rsquo;ordinateur peut exécuter. L&rsquo;ordinateur exécute les instructions en langage machine, mais on passe généralement par l&rsquo;<em>assembleur</em> pour le générer. Très bien. Seulement je ne suis pas exactement confortable avec l&rsquo;assembleur; la recherche d&rsquo;un expert pour m&rsquo;aider s&rsquo;est conclue en rentrée bredouille.</p>
<p>Il y a d&rsquo;autres solutions. Par exemple, la <em>JVM</em> (le programme qui exécute Java) possède un assembleur simplifié, de même pour <em>LLVM</em>. Cependant ces assembleurs ont l&rsquo;inconvénient de ne pas offrir le GOTO. Certes, l&rsquo;instruction GOTO n&rsquo;est pas appropriée pour un langage de haut niveau qui se doit d&rsquo;être maintenable, mais son absence d&rsquo;un langage de très bas niveau comme un <em>assembleur</em> me chagrine.</p>
<p>J&rsquo;ai découvert que le langage <em>C</em>, dans la version étendue de <em>gcc</em>, permet le GOTO local à une procédure. J&rsquo;ai pu l&rsquo;utiliser pour traduire un petit programme &laquo;&nbsp;<a href="http://dodo.sourceforge.net/examples/HelloWorld.c.html">HelloWorld</a>&nbsp;&raquo; de dodo en C. Il semblait y avoir une possibilité de traduire automatiquement les programmes dodo en C et de les compiler grâce à <em>gcc</em>, ce qui me convenait bien. Cependant le GOTO de <em>gcc</em> est limité à 255 labels ce qui n&rsquo;est pas suffisant pour dodo.</p>
<p>Une autre idée est de remplacer le GOTO par un SWITCH, et en effet on peut aller plus loin de cette façon. Mais à ce point je me préoccupait déjà de la gestion de la mémoire pour les variables et cette approche n&rsquo;était pas des plus prometteuses.</p>
<p>C&rsquo;est alors qu&rsquo;en visite auprès de ma famille, un parent (merci Romain!) à qui je parlais de dodo m&rsquo;a suggéré les pointeurs de fonction. C&rsquo;était suffisant pour m&rsquo;orienter vers une nouvelle solution.</p>
]]></content:encoded>
			<wfw:commentRss></wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
