<?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>Blog Arolla</title>
	<atom:link href="http://www.arolla.fr/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.arolla.fr/blog</link>
	<description>les douze travaux d&#039;Arolla</description>
	<lastBuildDate>Wed, 13 Mar 2013 12:26:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Callbacks strike Back</title>
		<link>http://www.arolla.fr/blog/2013/03/callbacks-strike-back/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=callbacks-strike-back</link>
		<comments>http://www.arolla.fr/blog/2013/03/callbacks-strike-back/#comments</comments>
		<pubDate>Wed, 13 Mar 2013 09:56:00 +0000</pubDate>
		<dc:creator>Arnauld</dc:creator>
				<category><![CDATA[Fonctionnel]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[callback]]></category>
		<category><![CDATA[continuation]]></category>
		<category><![CDATA[deferred]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[nodeJS]]></category>
		<category><![CDATA[non-blocking]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[promise]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1469</guid>
		<description><![CDATA[Cet article se place dans la continuité de l&#8217;article précédent: Il y a peut être une option pour continuer ¡¿. Avant de présenter de nouvelles techniques &#8211; les promises / deferred / future &#8211; nous commencerons par transposer les techniques vues précédement en javascript. En poussant le bouchon un peu plus loin, nous verrons les [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image-3.jpg"><img class="alignright size-full wp-image-1472" src="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image-3.jpg" alt="" width="320" height="490" /></a></p>
<p>Cet article se place dans la continuité de l&#8217;article précédent: <a title="Il y a peut être une option pour continuer ¡¿ (réflexion sur la programmation par continuation)" href="http://www.arolla.fr/blog/2012/12/option-maybe-continuation/" target="_blank">Il y a peut être une option pour continuer ¡¿.</a><br />
Avant de présenter de nouvelles techniques &#8211; les <em>promises</em> / <em>deferred</em> / <em>future</em> &#8211; nous commencerons par transposer les techniques vues précédement en javascript. En poussant le bouchon un peu plus loin, nous verrons les limites de <a href="http://www.youtube.com/watch?v=ASc40_mpZjU">Maurice</a> et comment, à force de promesses, des alternatives se proposent. A l&#8217;issu de cet article TL;TR, les fonctions de rappel ne devraient plus avoir de secret pour vous!</p>
<h2>Preambule: Javascript ça <code>function-ne</code> pas mal!</h2>
<p>L&#8217;une des richesses de Javascript par rapport à d&#8217;autres langages (comme &laquo;&nbsp;Java&nbsp;&raquo;) est que la <code>function</code> est <span style="color: #b80f07">un objet de première classe</span>: <strong>Une fonction est un objet et il est possible de l&#8217;affecter à une variable</strong>.</p>
<pre class="brush: jscript; title: ; notranslate">
var add = function(a,b) { return a + b; }
</pre>
<p>Il est même possible de définir des fonctions qui renvoient d&#8217;autres fonctions, on parle alors de fonction d&#8217;ordre supérieur:</p>
<pre class="brush: jscript; title: ; notranslate">
var adder = function(a) {
  return function(b) {
    return add(a, b);
  }
};

var add7 = adder(7);
assert(add7(0) === 7);
assert(add2(35) === 42);
</pre>
<p>Enfin, on peux même définir des fonctions qui prennent d&#8217;autres fonctions en paramètres et renvoient des fonctions:</p>
<pre class="brush: jscript; title: ; notranslate">
var curry = function(func, a) {
  return function(b) {
    return func(a,b);
  }
}

var add7 = curry(add, 7);
assert(add7(0) === 7);
assert(add7(35) === 42);
</pre>
<p>Un autre exemple, que l&#8217;on rencontre sans doute plus fréquement, en <code>jquery</code> :</p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;#login&quot;).on('click', function (event) {
    $(&quot;#login-pane&quot;).show();
});
</pre>
<p>Une fonction de rappel est invoquée lorsqu&#8217;un clic est détecté sur l&#8217;élément <code>login</code>; elle affiche alors l&#8217;élément <code>login-pane</code>.</p>
<p>Notes:</p>
<ul>
<li>J&#8217;invite le lecteur à lire l&#8217;excellent article: <a title="Les fonctions et les fonctions d’ordre supérieur" href="http://www.arolla.fr/blog/2013/01/les-fonctions-et-les-fonctions-d%e2%80%99ordre-superieur/">Les fonctions et les fonctions d&#8217;ordres supérieur</a> si ce n&#8217;est pas déjà fait.</li>
<li><a href="http://fr.wikipedia.org/wiki/Fonction_d%27ordre_sup%C3%A9rieur">Fonction d&#8217;ordre supérieur</a></li>
<li><a href="http://fr.wikipedia.org/wiki/Curryfication">Curryfication</a></li>
</ul>
<h2>Les techniques vu précédemment</h2>
<blockquote><p>
 <span style="color: #b80f07">Première technique</span> :</p>
<p> <strong>Ajouter une fonction supplémentaire comme paramètre lors de l&#8217;appel d&#8217;une méthode. Cette fonction pourra alors être appellée avec le résultat du calcul lorsque celui sera disponible.</strong></p></blockquote>
<p>Reprenons le code Java de notre première technique et transposons le en <strong>un</strong> équivalent javascript:</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
 ...
 public void create(String quizContent, Effect&lt;Quiz&gt; effect) {
 Quiz quiz = quizFactory.create(nextId(), quizContent);
 effect.e(quiz);
 }
}
</pre>
<p>devient:</p>
<pre class="brush: jscript; title: ; notranslate">
QuizService.prototype.create = function(quizContent, callback)
{
  var factory = this.quizFactory;
  var quiz = factory.create(this.nextId(), quizContent);
  callback(quiz);
}
</pre>
<p>La transposition est relativement claire. Illustrons cela par un exemple d&#8217;appel:</p>
<pre class="brush: jscript; title: ; notranslate">
quizService.create(&quot;&lt;question4aChampion&gt;...&quot;, function(quiz) {
  displayQuiz(quiz);
});
</pre>
<p>Une fois le quiz créé, il est passé en paramètre à notre fonction qui se contente de demander son affichage. Comme les arguments sont identiques cela peux même se réduire à (n&#8217;oubliez pas qu&#8217;une fonction est un objet de première classe):</p>
<pre class="brush: jscript; title: ; notranslate">
quizService.create(&quot;&lt;question4aChampion&gt;...&quot;, displayQuiz);
</pre>
<p>Passons rapidement à la deuxième technique:</pre>
<blockquote><p>
 <span style="color: #b80f07">Deuxième technique</span> :</p>
<p> <strong>La fonction de rappel est définie comme prenant un résultat dont le type peut varier en fonction du déroulement du calcul...</strong></p></blockquote>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void create(String quizContent,
                     Effect&lt;Either&lt;Quiz,Failure&gt;&gt; effect) {
    if(quizIsUnique(quizContent)) {
      Quiz quiz = quizFactory.create(nextId(), quizContent);
      Either&lt;Quiz,Failure&gt; left = Eithers.left(quiz);
      effect.e(left);
    }
    else {
      // Failure is a Pojo but could
      // also be an UniqueConstraintException
      Failure failure = new Failure(Code.NonUniqueQuiz);
      Either&lt;Quiz,Failure&gt; right = Eithers.right(failure);
      effect.e(right);
    }
  }
}
</pre>
<p>Là, les choses vont commencer à se simplifier:</p>
<pre class="brush: jscript; title: ; notranslate">
QuizService.prototype.create = function(quizContent, callback)
{
  if(this.quizIsUnique(quizContent)) {
    var factory = this.quizFactory;
    var quiz = factory.create(this.nextId(), quizContent);
    callback(null, quiz);
    // or callback.apply(null, [null, quiz]);
  }
  else {
    var failure = new Failure(Code.NonUniqueQuiz);
    callback(failure);
    // or callback.apply(null, [failure]);
  }
}
</pre>
<div style="margin-left: 1em;margin-bottom: 1em;padding-left: 0.5em;font-style: italic;border: 1px solid #e5e5e5;background: #f8f8f8">
<h4>Pour aller plus loin: le Rituel d'invocation</h4>
<p><strong>du direct, un peu d'<code>apply</code>, un zeste de <code>call</code> et une pincée de <code>this</code></strong> Il existe plusieurs façon d'invoquer une fonction lorsque l'on dispose d'une reference sur celle-ci. Il est possible de l'invoquer directement lorsque l'on connait les arguments exacts auxquels elle s'attend: <code>callback(null, quiz)</code>. Dans ce cas tout se passe bien tant que l'on ne se soucie guère de la notion de <code>this</code>. L'instance référencée par <code>this</code> au moment de l'execution du callback est alors non maitrisé, ce qui dans la plupart des cas ne pose pas de réel problème tant qu'on ne l'utilise pas. En revanche quand on est amené à utiliser le <code>this</code> il devient alors indispensable de connaitre ce qu'il référence. Ce qui est typiquement le cas en JQuery: </p>
<pre class="brush: jscript; title: ; notranslate">
$(&quot;.button&quot;).click(function() {
 var buttonId = $(this).attr(&quot;id&quot;);
 console.log( &quot;Button clicked: &quot; + buttonId);
});
</pre>
<p>Ligne 2, le <code>this</code> référence l'élément qui a été cliqué. C'est JQuery qui se charge d'invoquer la fonction de rappel en lui associant en <code>this</code> l'élément qui vient d'être cliqué. Cette association se fait par l'intermédiaire des fonctions <code>apply</code> et <code>call</code> (<strong>Eh oui une fonction est un objet à part entière et dispose elle-même de fonctions!</strong>). </p>
<p>Il existe enfin une petite subtilité, en définissant le <code>this</code> on ne définit pas seulement la valeur d'une variable, mais aussi l'objet sur lequel la fonction est invoquée. Les plus curieux pourront donc consulter les articles <em>"8.7.3 The call() and apply() Methods - Javascript: The Definitive Guide"</em> et <a href="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply">Function.prototype.apply method</a> pour plus d'informations sur les subtilités de ces fonctions. On pourra aussi consulter (<em>8.3.2 Variable-Length Argument Lists: The Arguments Object - Javascript: The Definitive Guide</em>) sur leur usages conjointement avec la variable spéciale <code>arguments</code>, ce qui permet de traiter efficacement les fonctions dont le nombre de paramètres peut varier d'une invocation à l'autre.</div>
<p>Qu'avons-nous fait? Eh bien notre fonction de rappel peut prendre deux paramètres: le premier, s'il est non <code>nul</code> (voir aussi <a href="http://oreilly.com/javascript/excerpts/javascript-good-parts/awful-parts.html#the_many_falsy_values_of_javascript">Falsy values in javascript</a>) désigne une erreur, tandis que le second désigne le résultat en cas de succès.<br />
Par convention, on place généralement l'erreur comme premier paramètre.</p>
<p>Voyons alors le code appellant:</p>
<pre class="brush: jscript; title: ; notranslate">
quizService(&quot;...&quot;, function(err, quiz) {
  if(err) {
    displayErrorFeedback(err);
  }
  else {
    displyFlashFeedback(quiz);
  }
})
</pre>
<p>Allez hop, on enchaine avec la troisième technique:</pre>
<blockquote><p>
 <span style="color: #b80f07">Troisième technique</span> :</p>
<p> <strong>La fonction de rappel est définie comme prenant un résultat dont le contenu est optionnel</strong></p></blockquote>
<p>Avant:</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void save(Quiz quiz, Effect&amp;lt;Option&amp;gt; effect) {
    try {
      repository.save(quiz);
      effect.e(Options.none());
    }
    catch(RepositoryException re) {
      Failure failure = new Failure(re);
      effect.e(Options.some(failure));
    }
  }
}
</pre>
<p>Après:</p>
<pre class="brush: jscript; title: ; notranslate">
QuizService.prototype.save = function(quiz, callback) {
  try {
    this.repository.save(quiz);
    callback();
  }
  catch(e) {
    callback(e);
  }
}
</pre>
<p>Bon... en pratique on verra (ou ecrira) très rarement du code comme ça! mais plutôt:</p>
<pre class="brush: jscript; title: ; notranslate">
QuizService.prototype.save = function(quiz, callback) {
  this.repository.save(quiz, function(err,res) {
    callback(err);
  });
}
</pre>
<p>ou même beaucoup plus simplement:</p>
<pre class="brush: jscript; title: ; notranslate">
QuizService.prototype.save = function(quiz, callback) {
  this.repository.save(quiz, callback);
}
</pre>
<p>Illustrons cela par un exemple d'utilisation:</p>
<pre class="brush: jscript; title: ; notranslate">
quizService.save(quiz, function(err) {
  if(typeof err !== &quot;undefined&quot;) {
    displayErrorFeedback(err);
  }
  else {
    displayFlashFeedback(Code.QuizSaved);
  }
}
});
</pre>
<p><a href="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image.jpg"><img class="alignleft size-full wp-image-1473" src="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image.jpg" alt="" width="320" height="490" /></a></p>
<p>Que pouvons-nous constater? Qu'il est possible d'invoquer la même fonction javascript avec ou sans un nombre variable de paramètres. C'est à la charge de la fonction invoquée de vérifier le nombre de paramètres passés, éventuellement leurs types, afin de choisir le comportement qu'elle doit adopter.<br />
Dans notre cas, on vérifie l'existence d'un paramètre qui, le cas échéant, sera référencé par la variable <code>err</code>. En l'absence de paramètre, cette variable sera considérée comme indéfinie.</p>
<p>Pourquoi ne pas utiliser <code>if(err)</code> puisque <code>undefined</code> est évaluée comme <code>false</code> (rappel: <a href="http://oreilly.com/javascript/excerpts/javascript-good-parts/awful-parts.html#the_many_falsy_values_of_javascript">Falsy values in javascript</a>)? Uniquement au cas où l'instance décrivant l'erreur serait évaluée à false (se serait maladroit mais bon... sait-on jamais). Les tatillons pourraient dire: "mais pourquoi tout à l'heure on ne s'est pas préoccupé de ça?" hummm... et bien tout simplement parce qu'il faut y aller petit à petit et donner différentes techniques au fur et à mesure.</p>
<p>Passons très vite sur la quatrième technique:</p>
<blockquote><p><span style="color: #b80f07">Quatrième technique</span> :</p>
<p><strong>La fonction de rappel est définie comme une fonction ne prenant aucun paramètre, elle est invoquée pour signaler que l'action désirée est effectuée</strong></p></blockquote>
<pre class="brush: jscript; title: ; notranslate">
QuizService.prototype.save = function(quiz, onceSaved) {
  this.repository.save(quiz, function(err,res) {
    onceSaved();
  });
}
</pre>
<h2>Et pourquoi parler de Javascript maintenant?</h2>
<p><a href="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image-1.jpg"><img class="alignright size-full wp-image-1470" src="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image-1.jpg" alt="" width="332" height="508" /></a></p>
<p>Eh bien parce qu'il devient difficile de ne pas voir que son utilisation devient de plus en plus présente avec des interfaces utilisateur de plus en plus riches. Il suffit de voir l'approche RIA et son nombre croissant de framework: Backbone.js, AngularJS, Ember.js, KnockoutJS, ... et même Batman.js! (voir <a href="http://addyosmani.github.com/todomvc/">Todo MVC</a> pour la comparaison d'une TODO list réalisée avec les différents frameworks).<br />
Et malgré ce que peuvent en dire certains, sa présence côté serveur - popularisée par la plateforme NodeJs -a de quoi nous interpeller. D'ailleurs une grande partie du succès de NodeJs réside dans son approche non bloquante, et toute son API est tournée autour des techniques que nous venons de voir: des appels asynchrones auxquels on passe des fonctions de rappel.</p>
<h2>Reveille le Numérobis qui sommeille en toi!</h2>
<p>Voyons à quoi ressemblerait une application prenant en compte à chaque appel cette notion de fonction de rappel:</p>
<pre class="brush: jscript; title: ; notranslate">
checkUniqueness(data, function(err) {
  if(err)
    displayError(err);
  else
    createQuiz(data, function(err, quiz) {
      if(err)
        displayError(err);
      else
        saveQuiz(quiz, function(err, quizId) {
          if(err)
            displayError(err);
          else
            lookupQuiz(quizId, function(err, quiz) {
              if(err)
                displayError(err);
              else
                sendQuiz(quiz)
            })
        })
    })
})
</pre>
<p>Mouais... c'est un bien bel escalier qui se dessine; certains parlnte même de pyramide funeste:</p>
<blockquote><p>As we all know, asynchronous I/O leads to callback API’s, which lead to nested lambdas, which lead to... the pyramid of doom</p>
<p><a href="http://calculist.org/blog/2011/12/14/why-coroutines-wont-work-on-the-web/">Why coroutines won't work on the web</a></p></blockquote>
<p>Le code devient difficile à lire, à comprendre et par conséquent à maintenir et à faire évoluer!</p>
<p>Pour la petite histoire, c'est justement en arrivant à ce constat en écrivant le code implémentant les différents motifs vus dans <a href="http://www.arolla.fr/blog/2012/11/amqp-101-part-1/">AMQP 101 - Part 1</a> que j'ai cherché une alternative plus élégante pour écrire la même fonctionalité. Il me fallait trouver une manière plus lisible d'écrire et donc de comprendre les exemples, tout ça pour toi cher lecteur! (On vous bichone bien non?)</p>
<h2>Des promesses, des promesses et encore des promesses</h2>
<p>Que ce cache sous ce titre? Et bien une nouvelle technique: les <code>Promises</code></p>
<p>Voyons tout d'abord le résultat auquel on souhaite arriver en reprenant l'example précédent:</p>
<pre class="brush: jscript; title: ; notranslate">
checkUniqueness(data)
  .then(displayError, function(data) {
    return createQuiz(data);
  })
  .then(displayError, function(quiz) {
    return saveQuiz(quiz);
  })
  .then(displayError, function(quizId) {
    return lookupQuiz(quizId);
  })
  .then(displayError, sendQuiz);
</pre>
<p>que l'on peut alléger en (souvenez-vous: une fonction est un objet de première classe - hummm je radote là?):</p>
<pre class="brush: jscript; title: ; notranslate">
checkUniqueness(data)
  .then(displayError, createQuiz)
  .then(displayError, saveQuiz)
  .then(displayError, lookupQuiz)
  .then(displayError, sendQuiz);
</pre>
<p>On retrouve alors notre enchainement d'appels, mais cette fois chaque appel est lié au précédent via la méthode <code>then</code>. Cette methode enregistre alors deux fonctions de rappel: une pour le traitement d'erreur et une pour le traitement du résultat.<br />
Ces fonctions de rappel seront alors invoquées lorsque l'appel précédent sera terminé en fonction de son échec ou de son résultat. L'erreur ou le résultat est alors automatiquement transmis en paramètre aux fonctions de rappel enregistrées.</p>
<p>Il s'agit là du principe des <code>Promises</code> en gros: tu m'invoques, je te renvoie un accusé de reception sur lequel tu peux t'enregistrer, quand j'aurai fini mon traitement je te promets que je te passe son résultat.</p>
<p>L'interêt est alors de pouvoir enchainer ces <code>promises</code> et ainsi de décrire tout l'enchainement du traitement qui devra être effectué à mesure que les résultats passent d'une étape à l'autre. Le découplage entre les étapes apparait clairement, et il devient plus facile d'insérer ou de modifier des étapes.</p>
<p>Afin de faire apparaitre les <code>promises</code>, le code précédent pourrait être réécrit de la manière suivante (il s'agit strictement du même code, la seule différence est de faire apparaitre explicitement les variables intermédiaires au lieu de chainer les appels directement):</p>
<pre class="brush: jscript; title: ; notranslate">
var promise0 = checkUniqueness(data);
var promise1 = promise0.then(displayError, function(data) {
                  return createQuiz(data);
                });
var promise2 = promise1.then(displayError, function(quiz) {
                  return saveQuiz(quiz);
                });
var promise3 = promise2.then(displayError, function(quizId) {
                  return lookupQuiz(quizId);
                });
promise3.then(displayError, sendQuiz);
</pre>
<p>A quoi pourrait ressembler une implémentation très <strong>simpliste</strong> (voir <a href="https://github.com/kriskowal/q">q</a> pour une implémentation plus complète et beaucoup plus robuste):</p>
<pre class="brush: jscript; title: ; notranslate">
var Promise = function () {
  this.resolved = false;
  this.callbacks = [];
};

Promise.prototype.resolve = function(error, data) {
	this.data = data;
  this.error = error;
	this.callbacks.forEach(function(cb) {
    if(error)
      cb[0](error);
    else
      cb[1](data);
  });
	this.callbacks = [];
	this.resolved = true;
}

Promise.prototype.then = function(errCallback, okCallback) {
	if(this.resolved) {
        if(this.error)
          errCallback(this.error);
        else
          okCallback(this.data);
    }
    else {
    	this.callbacks.push([errCallback, okCallback]);
	}
}
</pre>
<p>Ok... et comment on transforme nos méthodes précédentes pour intégrer cela? Et bien cela nécessite d'adapter légèrement nos API afin qu'elles intègrent directement les <code>Promises</code>:</p>
<pre class="brush: jscript; title: ; notranslate">
var checkUniqueness = function(data) {
  var promise = new Promise();
  db.checkUniqueness(function(error) {
    promise.resolve(error, data);
  });
  return promise;
}

var createQuiz = function(data) {
  var promise = new Promise();
  service.createQuiz(data, function(error, quiz) {
    promise.resolve(error, quiz);
  });
  return promise;
}

...
</pre>
<p>Biensûr tout cela a encore plus d'interêt lorsque les appels <code>db.checkUniqueness(...)</code> et <code>service.createQuiz(...)</code> sont asynchrones:<br />
Les deux méthodes précédentes sont invoquées et avant même que le résultat ne soit disponible la <code>promise</code> correspondante est retournée afin de continuer à définir le traitement à effectuer. La chaine de traitement est définie en même temps que la base de données ou que notre service travaille.</p>
<p>Quelques explications?</p>
<p><code>checkUniqueness</code> est invoquée avec les données à vérifier <code>data</code>. Une <code>promise</code> est instancié spécialement pour l'occasion afin d'être notifiée lorsque le traitement sera terminé. La vérification d'unicité est alors déléguée à la base de donnée (fallait bien trouver un responsable!) et en attendant son verdict, la <code>promise</code>est retournée telle quelle.<br />
Il est alors possible d'enregistrer plusieurs <code>callback</code> dessus en utilisant la méthode <code>then(cbErr,cbOut)</code> (exemple: <code>.then(displayError, function() { return createQuiz(data); })</code>).<br />
Les <code>callback</code> ainsi enregistrés seront alors notifiés dès que le résultat sera disponible, c'est à dire lorsque la méthode <code>promise.resolve(err,out)</code> est invoquée avec le résultat du traitement.</p>
<p>Le public averti pourra s'appercevoir qu'une <code>promise</code> est - elle-même - basée sur le mécanisme de callback et se place elle-même en fonction de rappel sur le traitement effectué.</p>
<p>L'exemple précédent nous a montré comment transformer des appels imbriqués en des déclarations séquentielles.<br />
Exploitons désormais quelques possibilités offertes par les librairies autour de ces promises (nous baserons notre discours sur la librairie <a href="https://github.com/kriskowal/q">q</a>).</p>
<p>Voyons comment nous pouvons étendre les mêmes techniques à des traitements effectués en parallèle, et plus particulièrement ceux nécessitant des points de "synchronisation": une fois que mes sous-tâches sont terminées alors seulement la suite de mon traitement peut continuer.</p>
<p>Par exemple si nous souhaitons générer tout un recueil de quiz:</p>
<p>Commençons par définir une fonction utilitaire de création de quiz, regroupant ce que nous avons pu voir jusqu'à présent. La fonction retourne une <code>promise</code> sur la création du quiz:</p>
<pre class="brush: jscript; title: ; notranslate">
function generateQuiz(errorHandler) {
  var promise =
        generateData()
          .then(errorHandler, checkUniqueness)
          .then(errorHandler, createQuiz)
          .then(errorHandler, saveQuiz);
  return promise;
}
</pre>
<p>Une fonction utilitaire qui génèrera <code>nbQuiz</code> en invoquant la fonction précédente:</p>
<pre class="brush: jscript; title: ; notranslate">
function generateBook(nbQuiz, errorHandler) {
  var i,
      promises = [];
  for(i=0; i &lt; nbQuiz; i++) {
    var promise = generateQuiz(errorHandler);
    promises.push(promise);
  }

  return return Q.all(promises);
}
</pre>
<p>Le retour de notre méthode <code>generateBook</code> est une <code>promise</code>. Les fonctions de rappels qui seront "branchées" dessus seront alors invoquées lorsque les <code>nbQuiz</code> questionnaires auront été générés, créés et enregistrés.</p>
<pre class="brush: jscript; title: ; notranslate">
generateBook(25, errorHandler)
  .then(errorHandler, generateTableOfContent)
  .then(errorHandler, sendToFrance3)
  ...;
</pre>
<p>En continuant de creuser, on peux trouver beaucoup d'autres techniques. On s'apperçoit que cela ouvre énormément de possibilités quand à la gestion de tâches asynchrones, éventuellement concurrentes, et ce de manière lisible.</p>
<h2>Qui est concerné?</h2>
<p><a href="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image-2.jpg"><img class="alignright size-full wp-image-1471" src="http://www.arolla.fr/blog/wp-content/uploads/2013/02/Pulp-O-Mizer_Cover_Image-2.jpg" alt="" width="332" height="508" /></a></p>
<p>Suis-je concerné? Je pensais que le Javascript était executé par un seul fil d'execution et là on me parle de traitement asynchrone ?</p>
<blockquote><p><strong>One of the fundamental features of client-side JavaScript is that it is single-threaded</strong>: a browser will never run two event handlers at the same time, and it will never trigger a timer while an event handler is running, for example. <strong>Concurrent updates to application state or to the document are simply not possible, and client-side programmers do not need to think about, or even understand, concurrent programming</strong>.</p>
<p>Javascript The Definitive Guide 6th Ed - 22.4 WebWorkers</p></blockquote>
<p>Et en quoi cela nous concerne-t-il si l'on développe sur le navigateur?</p>
<p>Eh bien parce qu'il n'est pas toujours question de traitement effectué sur le navigateur, mais il peut aussi s'agir d'interaction avec des systèmes tierces comme une requête AJAX:</p>
<blockquote><p>A corollary is that client-side JavaScript functions must not run too long: otherwise they will tie up the event loop and the web browser will become unresponsive to user input. <strong>This is the reason that Ajax APIs are always asynchronous and the reason that client-side JavaScript cannot have a simple, synchronous load() or require() function for loading JavaScript libraries.</strong></p>
<p>Javascript The Definitive Guide 6th Ed - 22.4 WebWorkers</p></blockquote>
<blockquote><p><strong>Everything</strong> except network operations happens in a single thread</p>
<p><a href="https://speakerdeck.com/dmosher/so-you-want-to-be-a-front-end-engineer">So, You Want to Be a Front-End Engineer?</a></p></blockquote>
<p>Les bibliothèques JQuery et Dojo fournissent d'ailleurs des API selon le modèle des <code>promises</code> appellé chez eux <code>deferred</code> (<a href="http://dojotoolkit.org/reference-guide/1.7/dojo/Deferred.html">Dojo ~ Deferreds</a> et <a href="http://api.jquery.com/category/deferred-object/">JQuery ~ Deferreds</a>).</p>
<p>De plus, comme l'auront noté les petits malins, HTML5 définit la notion des <code>WebWorkers</code> qui permet d'effectuer des traitements en dehors du fil d'execution Javascript de la page. Il est donc tout à fait possible d'effectuer des traitements asynchrones même sur un navigateur en les déléguant à des WebWorkers (Nous reviendrons sans doute sur eux dans un prochain article).</p>
<p>Quand à la plateforme NodeJs, et bien, elle intègre par construction la nature asynchrone de chaque appel IO (Input/Output). Les spécifications sur lesquelles s'appuient la plateforme prévoit même une API unifiée et standard pour les promises (<a href="http://wiki.commonjs.org/wiki/Promises/A">CommonJS ~ Promises/A</a> pour lequel <a href="https://github.com/kriskowal/q">q</a> est compatible).</p>
<p>Et pour ceux qui <strong>jamais au grand jamais</strong> ne toucheront à du javascript!?</p>
<p>Et bien, tout d'abord, vous avez tort de ne pas vous y interesser. Ensuite, ces notions non-bloquantes deviennent de plus en plus présentes et l'on retrouve tous ces concepts dans les langages intégrant les notions de <a href="http://savanne.be/articles/concurrency-in-erlang-scala/">process/acteur</a> (erlang et scala dont l'excellente librairie <a href="http://akka.io">akka</a>) et du coup dans les frameworks comme <a href="http://www.playframework.com/documentation/2.1.0/ScalaAsync">Play!</a> ou <a href="http://gpars.codehaus.org/">GPars</a>.</p>
<h2>Webographie</h2>
<p>Une très belle présentation:</p>
<ul>
<li><a href="http://news.humancoders.com/t/prog-fonctionnelle/items/2584-futures-et-promesses-en-scala-2-10"> Futures et Promesses en Scala 2.10 (en)</a></li>
</ul>
<ul>
<li><a href="http://fr.wikipedia.org/wiki/Fonction_d%27ordre_sup%C3%A9rieur">Fonction d'ordre supérieur</a></li>
<li><a href="http://fr.wikipedia.org/wiki/Curryfication">Curryfication</a></li>
</ul>
<ul>
<li><a href="https://github.com/kriskowal/q">kriskowal / q</a> : A tool for making and composing asynchronous promises in JavaScript</li>
</ul>
<ul>
<li><a href="http://www.infoq.com/articles/surviving-asynchronous-programming-in-javascript">"How to Survive Asynchronous Programming in JavaScript" on InfoQ</a></li>
</ul>
<ul>
<li><a href="http://wiki.commonjs.org/wiki/Promises/A">CommonJS ~ Promises/A</a></li>
<li><a href="http://dojotoolkit.org/reference-guide/1.7/dojo/Deferred.html">Dojo ~ Deferreds</a></li>
<li><a href="http://api.jquery.com/category/deferred-object/">JQuery ~ Deferreds</a></li>
<li><a href="http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/">Understanding JQuery.Deferred and Promise</a></li>
<li><a href="http://spin.atomicobject.com/2012/03/14/nodejs-and-asynchronous-programming-with-promises/">Node.js and Asynchronous Programming with Promises</a></li>
</ul>
<ul>
<li><a href="http://addyosmani.github.com/todomvc/">Todo MVC</a></li>
</ul>
<ul>
<li><a href="http://akka.io">Akka</a></li>
<li><a href="www.playframework.com/documentation/2.1.0/ScalaAsync">Play!</a></li>
</ul>
<p>Livres</p>
<ul>
<li><a href="http://shop.oreilly.com/product/9780596805531.do">JavaScript: The Definitive Guide</a></li>
<li><a href="http://shop.oreilly.com/product/9780596517748.do">JavaScript: The Good Parts</a></li>
</ul>
<div id="tweetbutton1469" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fbtuzfbl&amp;via=ArollaFr&amp;text=Callbacks%20strike%20Back&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2013%2F03%2Fcallbacks-strike-back%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2013/03/callbacks-strike-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Session ALT.NET “Open-source Web Frameworks”</title>
		<link>http://www.arolla.fr/blog/2013/02/session-alt-net-open-source-web-frameworks/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=session-alt-net-open-source-web-frameworks</link>
		<comments>http://www.arolla.fr/blog/2013/02/session-alt-net-open-source-web-frameworks/#comments</comments>
		<pubDate>Mon, 25 Feb 2013 13:46:25 +0000</pubDate>
		<dc:creator>Pierre Irrmann</dc:creator>
				<category><![CDATA[Evénements]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[ALT.NET]]></category>
		<category><![CDATA[Convention over configuration]]></category>
		<category><![CDATA[craftsmanship]]></category>
		<category><![CDATA[DTO]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[Nancy]]></category>
		<category><![CDATA[REST]]></category>
		<category><![CDATA[Service Stack]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1537</guid>
		<description><![CDATA[Jeudi dernier, je suis allé assister à la session ALT.NET organisée par Rui (@rhwy) et Mathias (@mathiaskluba) autour de deux frameworks web open-source de l’éco-système .NET : ServiceStack et NancyFx. Service Stack et Nancy partent du même besoin de construire des applications et des services REST sans dépendre ni de l’ensemble de l’infrastructure ASP.NET, ni [...]]]></description>
			<content:encoded><![CDATA[<p>Jeudi dernier, je suis allé assister à la session ALT.NET organisée par Rui (<a href="https://twitter.com/rhwy">@rhwy</a>) et Mathias (<a href="https://twitter.com/mathiaskluba">@mathiaskluba</a>) autour de deux frameworks web open-source de l’éco-système .NET : <a href="http://www.servicestack.net/">ServiceStack</a> et <a href="http://nancyfx.org/">NancyFx</a>. Service Stack et Nancy partent du même besoin de construire des applications et des services REST sans dépendre ni de l’ensemble de l’infrastructure ASP.NET, ni du serveur IIS, et sans mettre en œuvre toute la machinerie de WCF. ASP.NET Web API a déjà fait un grand pas dans cette direction, mais ces alternatives se veulent encore plus simples. Leurs principaux points communs sont :</p>
<ul>
<li>leurs approches “convention over configuration”</li>
<li>leur relation étroite avec HTTP (verbes, content-negociation)</li>
</ul>
<p>Rui, toujours partisan de <a href="http://www.meetup.com/paris-software-craftsmanship/">l’artisanat logiciel</a>, expose fièrement un T-shirt “SC with superpowers”, et nous accueille par une présentation des <a href="http://www.meetup.com/altnetfr/">prochains évènements</a> du <a href="http://www.altnetfr.org/">groupe ALT.NET France</a> et un appel au sponsoring des évènements (le mois prochain, présentations de projets OSS sous forme de lightning talks), avant de laisser la parole à Mathias.</p>
<h3>Service Stack</h3>
<p>La première présentation, par Mathias, tourne autour de Service Stack, qui est une alternative aux solutions Microsoft ASP.NET MVC, Web API pour créer des applications REST et des services. Il s’agit d’un ensemble de briques composables, incluant par exemple :</p>
<ul>
<li>une gestion de la sérialisation / désérialisation</li>
<li>un client Redis (stockage sous forme de paires clé / valeur en open-source)</li>
<li>une gestion de cache (dans <a href="http://redis.io/">Redis</a> ou <a href="http://memcached.org/">Memcached</a>)</li>
<li>un mapping objet-relationnel (ORMLite)</li>
</ul>
<p>L’ensemble de cette stack est compatible avec MONO (et peut même tourner sur un iPhone, avec tout l’intérêt que ça comporte mais qu’on n’a pas encore trouvé). L’architecture est très orientée DTO (message), par opposition à une vision traditionnelle plutôt orientée RPC (procédure). Service Stack est toujours activement développé et remporte un succès croissant. Mathias nous indique en particulier que le format <a href="http://developers.helloreverb.com/swagger/">Swagger</a>, qui est une forme de description de contrat pour les services REST, sera bientôt intégré dans Service Stack.</p>
<p>Mathias enchaine avec des démos, avec un exemple de service REST dont on parcourt le code coté serveur. En particulier, on y observe une IoC incorporée et l’absence de configuration. Une grande partie du fonctionnement se fait par respect des conventions, mais celles-ci ne sont pas toujours documentées et il peut être un peu dur de s’y retrouver car le non-respect de la convention ne génère aucun message d’erreur, juste une appli qui ne tient pas compte de ce que l’on a fait&#8230; Le conseil de Mathias : partir de l’exemple qui fonctionne bien et adapter à ses besoins, plutôt qu’essayer de partir “from scratch” et lutter dans le vide. Nous observons la mise en place de l’injection d’un repository, l’ajout de routes (très simple).</p>
<p>Coté client, les appels sont également très clairs. Dans le cas d’un client et serveur tous les deux en .NET, les DTO sont simplement partagés, ce qui permet de retrouver directement ses objets et de gérer sérialisation / désérialisation automatiquement. Au fur et à mesure des démos, on remarque :</p>
<ul>
<li>la gestion de credentials (plusieurs providers d’authentification sont utilisables très simplement),</li>
<li>la notion de validateur de demandes de mises à jour des ressources,</li>
<li>la gestion de rôles&#8230;</li>
</ul>
<p>Les services peuvent être “découverts” par l’intermédiaire d’une page web listant toutes les ressources exposées dans chacun des formats proposés : XML, JSON, CSV, JSV, SOAP (1.1 et 1.2). Visiblement, il n’est pas si facile que ça de sortir du standard, et faire du SOAP consommable depuis un autre client (par exemple WCF) nécessite tout de suite beaucoup plus de configuration.</p>
<p>Service Stack peut aussi être utilisé pour générer du contenu HTML en mode MVC (bien que ce ne soit pas son but premier), et intègre le moteur Razor (qui a été open-sourcé par Microsoft depuis déjà quelque temps). La même URL peut donc être utilisée pour demander différentes représentations d’une même ressource, dont une au format HTML à destination d’utilisateurs humains (parce qu’il n’y a pas que des machines dans la vie !). De la même manière qu’auparavant, la convention doit être respectée : la vue Razor doit porter le même nom que la classe de la ressource.</p>
<p>Pour finir, Mathias insiste sur la quantité de plug-ins disponibles autour de Service Stack. S’en suit une séance de questions / réponses autour des thèmes convention / configuration, REST, Hypermédia, API traversantes…</p>
<h3>Nancy FX</h3>
<p>La deuxième présentation, menée par Rui, traite de NancyFX, qu’il nous vend immédiatement comme “Vachement mieux que Service Stack” !</p>
<p>Rui retrace l’évolution de l’offre web Microsoft ASP.NET dans le passé :</p>
<ul>
<li>ASP.NET Web Forms : on ne peut rien faire (en termes de personnalisation),<em> “Pas assez de contrôle”</em></li>
<li>ASP.NET MVC : on peut tout faire (IoC etc…) mais très verbeux dans la personnalisation, beaucoup de configuration et ça n’est pas facile, <em>“Le cout du contrôle est trop élevé”</em></li>
</ul>
<p>Il résume ses envies de développeurs par :</p>
<ul>
<li>Composition</li>
<li>Injection</li>
<li>Convention over configuration</li>
<li>Comportement par défaut intéressant,</li>
<li>Autant que possible, une connexion automatique (“auto-wire”) des différents éléments</li>
<li>Open-source (si possible)</li>
</ul>
<p>Ses besoins sont simples : “Maitrise, Puissance, Simplicité”. Exigeant, tout de même…</p>
<p>Et bien la réponse qu’il nous propose, c’est Nancy : “un framework léger, low-ceremony, pour construire des services basés sur HTTP, en .NET et Mono”. Nancy est directement affilié à <a href="http://www.sinatrarb.com/intro">Sinatra</a>, un framework web créé par la communauté Ruby. La religion de Nancy est la suppression de la “friction” que l’on peut trouver lorsqu’on met en œuvre un framework. Les concepteurs de Nancy cherchent à nous proposer un “super-duper-happy-path” pour construire nos applications : tout est “sympa” à utiliser.</p>
<p>Nancy peut se résumer dans la formule “DSL over HTTP + IoC”, c’est à dire un langage spécialisé au dessus d’HTTP, avec un mécanisme d’inversion de contrôle inclus. Et en plus, ça tourne partout (puisque ça s’appuie sur <a href="http://owin.org/">OWIN</a>) !</p>
<p>S’ensuivent quelques démos, une installation à base NuGet avec zéro configuration, pas de bootstrap à mettre en place. Bien que la démo reste simple, tout est très lisible et mis en œuvre facilement. De par son inspiration provenant du monde Ruby, l’utilisation des dynamic est intensive. Tout est très isolé et décomposé.</p>
<p>Au fur et à mesure des démos, nous découvrons en action :</p>
<ul>
<li>le moteur de vues intégré par défaut “SuperSimpleViewEngine”, qui permet d’écrire des vues dans une syntaxe rappelant très fortement celle de Razor,</li>
<li>le conteneur d’injection de dépendance par défaut, TinyIoc, qui permet de faire les opérations classiques d’Ioc, qui fonctionne par défaut avec une injection par constructeur et une résolution par convention de nommage,</li>
<li>un exemple de développement en TDD,</li>
<li>la mise en place d’un bootstraper personnalisé,</li>
<li>le système de diagnostique incorporé au framework et un aperçu de l’espace de gestion du site incorporé (consultation des traces, etc.).</li>
</ul>
<p>De ces démos et des questions correspondantes, j’ai retenu quelques citations qui m’on semblées pertinentes : “Un framework web, au fond, ce n’est que de l’infrastructure” et “Non, ce n’est pas de la magie noire” !</p>
<h3>Conclusion</h3>
<p>Ces deux présentations m’ont permis de voir en action des framework dont j’avais déjà entendu parler mais que je n’avais pas eu l’occasion (ni pris le temps) de tester. De mon point de vue, ces projets nous montrent que c’est à la croisée des systèmes, en s’inspirant de ce qui se fait de mieux ailleurs (ici Ruby et le monde des langages dynamiques) que l’on trouve les solutions intéressantes et innovantes. Le public de développeurs .NET (pour la grande majorité) a semblé très inspiré, et chacun est rentré chez soi avec plus d’idées qu’il n’en avait en arrivant… preuve que cette soirée était une belle réussite !</p>
<p>Pour ceux qui souhaitent d’autres informations et qui passent du temps dans les transports, pleins de références de podcasts, choisissez votre programme préféré :</p>
<ul>
<li>Service Stack : <a href="http://www.dotnetrocks.com/default.aspx?showNum=843">Dot Net Rocks 843 avec Demis Bellot</a>, <a href="http://thetabletshow.com/?ShowNum=60">The Tablet Show 60 avec John Sonmez</a>, <a href="http://www.hanselminutes.com/300/framework-series-service-stack-with-demis-bellot">Hanselminutes 300 (Demis Bellot)</a> et <a href="http://www.hanselminutes.com/348/more-on-service-stack-with-john-sonmez">348 (John Sonmez)</a>.</li>
<li>Nancy : <a href="http://herdingcode.com/?p=350">Herding Code 123</a> et <a href="http://herdingcode.com/?p=505">156</a> (Andreas Håkansson and Steven Robbins), <a href="http://www.hanselman.com/blog/HanselminutesPodcast270NancySinatraAndTheExplosionOfNETMicroWebFrameworksWithAndreasH%C3%A5kansson.aspx">Hanselminutes 270 (Andreas Håkansson)</a> et <a href="http://www.hanselminutes.com/351/understanding-nancyfx-with-richard-cirerol">351 (Richard Cirerol)</a></li>
</ul>
<p><a href="https://twitter.com/pirrmann">@pirrmann</a></p>
<div id="tweetbutton1537" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fbl36gzg&amp;via=ArollaFr&amp;text=Session%20ALT.NET%20%E2%80%9COpen-source%20Web%20Frameworks%E2%80%9D&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2013%2F02%2Fsession-alt-net-open-source-web-frameworks%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2013/02/session-alt-net-open-source-web-frameworks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Les fonctions et les fonctions d’ordre supérieur</title>
		<link>http://www.arolla.fr/blog/2013/01/les-fonctions-et-les-fonctions-d%e2%80%99ordre-superieur/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=les-fonctions-et-les-fonctions-d%25e2%2580%2599ordre-superieur</link>
		<comments>http://www.arolla.fr/blog/2013/01/les-fonctions-et-les-fonctions-d%e2%80%99ordre-superieur/#comments</comments>
		<pubDate>Fri, 25 Jan 2013 16:55:51 +0000</pubDate>
		<dc:creator>Nouhoum</dc:creator>
				<category><![CDATA[Fonctionnel]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[filter]]></category>
		<category><![CDATA[fonction]]></category>
		<category><![CDATA[fonctionnel]]></category>
		<category><![CDATA[map]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1411</guid>
		<description><![CDATA[La programmation fonctionnelle a de nombreux attraits dont le traitement réservé aux fonctions. Dans beaucoup de langages de programmation les fonctions ont un statut particulier. Par exemple en Java il est possible de créer un entier, de l’assigner à une variable ou de le passer comme argument à une autre fonction mais on ne peut [...]]]></description>
			<content:encoded><![CDATA[<p>La programmation fonctionnelle a de nombreux attraits dont le traitement réservé aux fonctions. Dans beaucoup de langages de programmation les fonctions ont un statut particulier. Par exemple en Java il est possible de créer un entier, de l’assigner à une variable ou de le passer comme argument à une autre fonction mais on ne peut pas de même avec les fonctions. En revanche les fonctions jouent un rôle central dans la programmation fonctionnelle et ne sont pas traitées comme des citoyens de seconde zone par les langages dits fonctionnels (Haskell, Caml, Clojure etc.). Cela est important pour l’écriture de certains types d’abstractions bien utiles et courantes en développement comme nous le verrons dans la suite mais avant d’aller plus loin définissons une fonction.</p>
<h2>C’est quoi une fonction ?</h2>
<p>Ce qu’on entend par fonction varie selon les langages de programmation mais la définition que je vais donner ici est suffisante pour les propos de l’article. Une fonction est une <strong><em>transformation</em></strong> qui produit une valeur à partir d’un ensemble de paramètres, les arguments de la fonction.<br />
Les choses seront plus claires avec des exemples. Si nous notons par <strong>x</strong> un nombre entier quelconque. <strong>x</strong> peut donc prendre comme valeur <strong>0</strong>, <strong>1</strong>, <strong>2</strong> etc. nous pouvons définir la fonction <strong>f</strong> comme suit :</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-2K5h0CF43rQ/UNDr6ngGs6I/AAAAAAAAAyU/EOMVnocfFoM/s1600/f_double_fn.png"><img src="http://3.bp.blogspot.com/-2K5h0CF43rQ/UNDr6ngGs6I/AAAAAAAAAyU/EOMVnocfFoM/s400/f_double_fn.png" alt="" width="87" height="18" border="0" /></a></div>
<p>Ne vous laissez pas impressionner par la notation. <strong><em>f</em></strong> est le petit nom donné à la fonction, la lettre <strong>x</strong> à gauche de la flèche désigne l’argument de la fonction et à droite se trouve sa définition. En donnant une valeur spécifique au paramètre, par exemple <strong>1</strong> nous obtenons :</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://3.bp.blogspot.com/-TIHMpxooJEs/UNDuY-ARvOI/AAAAAAAAAyo/3hYT7uz3Nh0/s1600/f_double_fn_1.png"><img src="http://3.bp.blogspot.com/-TIHMpxooJEs/UNDuY-ARvOI/AAAAAAAAAyo/3hYT7uz3Nh0/s400/f_double_fn_1.png" alt="" width="120" height="19" border="0" /></a></div>
<p>Si x vaut <strong>3</strong> la valeur retournée par la fonction est :</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-bO7dvC0OMWQ/UNDvY49TArI/AAAAAAAAAy4/KOChqy8kLQg/s1600/f_double_fn_3.png"><img src="http://1.bp.blogspot.com/-bO7dvC0OMWQ/UNDvY49TArI/AAAAAAAAAy4/KOChqy8kLQg/s400/f_double_fn_3.png" alt="" width="124" height="19" border="0" /></a></div>
<p>Au vu de ces valeurs il est aisé de comprendre que cette fonction double la valeur qu’on lui passe en paramètre. Renommons la fonction afin de mieux exprimer cette intention :</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-xF14ET1FYyI/UNDvoSthtHI/AAAAAAAAAzI/6PCyyFsBs30/s1600/double_fn.png"><img src="http://1.bp.blogspot.com/-xF14ET1FYyI/UNDvoSthtHI/AAAAAAAAAzI/6PCyyFsBs30/s400/double_fn.png" alt="" width="122" height="14" border="0" /></a></div>
<p>Le langage Scala est utilisé dans la suite pour illustrer nos propos. Et la fonction double est codée en Scala comme suit :</p>
<pre class="brush: scala; title: ; notranslate">
def double(number: Int) = 2 * number
</pre>
<p>Dans le code ci-dessus le mot clé <strong>def</strong> permet de définir une fonction. Il est suivi du nom de la fonction. J’ai choisi, à la place du paramètre <strong>x</strong>, un nom plus parlant : <strong>number</strong>. L’annotation <strong>Int</strong> (pour Integer) spécifie au compilateur que le paramètre <strong>number</strong> est un entier. Le reste du code est une traduction parfaite du pseudo code.</p>
<p>Les sorties suivantes de la console interactive (REPL) de Scala permettent de tester notre fonction :</p>
<pre class="brush: scala; title: ; notranslate">
$ scala
scala&gt; def double(number: Int) = 2 * number
double: (number: Int)Int
scala&gt; double(3)
res0: Int = 6
scala&gt; double(1)
res1: Int = 2
</pre>
<p>Une fonction peut avoir plusieurs arguments par exemple la fonction faisant la somme de deux nombres entiers prend deux arguments. Soient <strong>x</strong> et <strong>y</strong> les deux entiers dont nous souhaitons faire la somme, la fonction <strong>add</strong> est définie comme suit :</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://1.bp.blogspot.com/-C1FzDY8ZYYc/UND5HbuFCuI/AAAAAAAAAzc/eR-SMu9lb1g/s1600/add_fn.png"><img src="http://1.bp.blogspot.com/-C1FzDY8ZYYc/UND5HbuFCuI/AAAAAAAAAzc/eR-SMu9lb1g/s400/add_fn.png" alt="" width="145" height="19" border="0" /></a></div>
<p>Cette définition se traduit aisément en Scala de la façon suivante :</p>
<pre class="brush: scala; title: ; notranslate">
def add(x:Int, y:Int) = x + y
</pre>
<p>Le test de la fonction donne :</p>
<pre class="brush: scala; title: ; notranslate">
$ scala
scala&gt; def add(x:Int, y:Int) = x + y
add: (x: Int, y: Int)Int
scala&gt; add(1, 2)
res0: Int = 3
</pre>
<p>Et si nous souhaitions définir une fonction qui incrémente un entier nous pouvons réutiliser la fonction <strong>add</strong>. En effet incrémenter un entier revient à lui ajouter <strong>1</strong> :</p>
<pre>def increment(number: Int) = add(number, 1)</pre>
<p>En action cela donne:</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; def increment(number: Int) = add(number, 1)
increment: (number: Int)Int
scala&gt; increment(3)
res1: Int = 4
scala&gt; increment(10)
res2: Int = 11
</pre>
<p class="note"><strong>Note</strong> : Une propriété importante de chacune des fonctions que nous avons vues jusque là est le fait que la valeur de retour est entièrement déterminée par les arguments de la fonction.</p>
<p>Munis de ces informations passions aux fonctions d’ordre supérieur.</p>
<h2>Les fonctions d’ordre supérieur</h2>
<p>Une fonction d’ordre supérieur est une fonction qui a au moins l’une des deux caractéristiques suivantes :</p>
<ul>
<li>prend en paramètre une ou plusieurs fonctions</li>
<li>sa valeur de retour est une fonction</li>
</ul>
<p>Les fonctions d’ordre supérieur aident à l’expressivité du code en mettant l’attention sur la tâche à accomplir plutôt que sur la façon de l’accomplir : le code dévient ainsi plus déclaratif. Cela devient plus clair avec un exemple. Considérons la classe Person ci-dessous :</p>
<pre class="brush: java; title: ; notranslate">
public class Person {
 private final String name;
 private final String email;
 private final int age;

 public Person(String name, String email, int age) {
  this.name = name;
  this.email = email;
  this.age = age;
 }

 public String getName() {
  return name;
 }

 public String getEmail() {
  return email;
 }

 public int getAge() {
  return age;
 }
}
</pre>
<p>Supposons que vous disposez d’une liste d’objets de type <strong>Person</strong> sur laquelle vous souhaitez faire différentes opérations : transformation, filtrage etc. Commençons par la transformation de la liste.</p>
<h2>Transformation des éléments d’une collection</h2>
<p>Voici la liste initiale :</p>
<pre class="brush: java; title: ; notranslate">
List&lt;Person&gt; persons = Arrays.asList(//
				new Person(&quot;Toto&quot;, &quot;toto@email.com&quot;, 23), //
				new Person(&quot;John Doe&quot;, &quot;john.doe@email.com&quot;, 34), //
				new Person(&quot;Mad Max&quot;, &quot;mad.max@crazymail.com&quot;, 20), //
				new Person(&quot;Jane Doe&quot;, &quot;jane@email.com&quot;, 17));
</pre>
<p>La première transformation qui nous intéresse est l’extraction des adresses email à partir de la liste des personnes. C’est ce que fait la méthode <strong>extractEmails</strong> :</p>
<pre class="brush: java; title: ; notranslate">
public static List&lt;String&gt; extractEmails(List&lt;Person&gt; persons) {
	List&lt;String&gt; emails = new ArrayList&lt;String&gt;();

	for (Person person : persons) {
		emails.add(person.getEmail());
	}

	return emails;
}
</pre>
<p>Testons ce que cela donne :</p>
<pre class="brush: java; title: ; notranslate">
System.out.println(&quot;Emails = &quot; + extractEmails(persons));
</pre>
<p>Sortie de la console :</p>
<pre class="brush: bash; title: ; notranslate">
Emails = [toto@email.com, john.doe@email.com, mad.max@crazymail.com, jane@email.com]
</pre>
<p>On obtient une liste ayant la même taille que la liste des personnes mais ne contenant que les adresses email. Le code de la méthode <strong>extractEmails</strong> recèle quelques défauts dont la “<strong><em>dilution</em></strong>” de l’intention de la méthode dans du code verbeux.</p>
<p>Avant de voir comment résoudre ces défauts implémentons une autre fonctionnalité : extraire les noms à partir de la liste des personnes :</p>
<pre class="brush: java; title: ; notranslate">
public static List&lt;String&gt; extractNames(List&lt;Person&gt; persons) {
	List&lt;String&gt; names = new ArrayList&lt;String&gt;();

	for (Person person : persons) {
		names.add(person.getName());
	}

	return names;
}
</pre>
<p>Cette méthode fait ressortir un autre défaut de notre code : la <strong><em>duplication</em></strong>. Les deux méthodes ne diffèrent véritablement que par la transformation effectuée à chaque itération sur l’élément de la liste initiale. Cette transformation peut être matérialisée par une fonction <strong><em>f</em></strong> qui prend comme argument un objet de type Person et retourne son nom ou son adresse email. Ainsi l’implémentation de l’une ou l’autre de nos fonctions se résume comme suit : &laquo;&nbsp;<em>applique la fonction <strong><em>f</em></strong> à chaque élément de la liste initiale et renvoie-moi la liste correspondante</em>.&nbsp;&raquo;</p>
<p>Nous pouvons schématiser cette phrase de la façon suivante, avec à gauche la liste initiale et à droite la liste obtenue suite à la transformation :</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-HaOuoJVF4MM/UNIyFI0DaKI/AAAAAAAAAzw/HQkRqlUkB3U/s1600/map.png"><img src="http://4.bp.blogspot.com/-HaOuoJVF4MM/UNIyFI0DaKI/AAAAAAAAAzw/HQkRqlUkB3U/s400/map.png" alt="" width="293" height="26" border="0" /></a></div>
<p>Cela correspond exactement à ce que fait la fonction <strong><em>map</em></strong>. La figure ci-dessous donne le fonctionnement de la méthode <strong><em>map</em></strong> présente sur la classe <strong>List</strong> de Scala.</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://4.bp.blogspot.com/-ejBbXTsqL4Y/UNJEvkJRmJI/AAAAAAAAA0E/UwL2jaSK_m8/s1600/map_illustration.jpg"><img src="http://4.bp.blogspot.com/-ejBbXTsqL4Y/UNJEvkJRmJI/AAAAAAAAA0E/UwL2jaSK_m8/s400/map_illustration.jpg" alt="" width="400" height="300" border="0" /></a></div>
<p>Comme mentionné sur la figure la fonction map prend en paramètre une fonction, celle que nous souhaitons appliquer à chaque élément de la liste initiale. Dans notre cas la fonction a comme type <strong><em>Person =&gt; String</em></strong>.</p>
<p>Nous allons maintenant réimplémenter nos deux méthodes en utilisant la méthode map disponible dans l&#8217;<a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List">API des listes Scala</a>.</p>
<h2>Les fonctions extractEmails et extractNames revisitées</h2>
<p>Définition de la classe <strong>Person</strong> :</p>
<pre class="brush: scala; title: ; notranslate">
case class Person(name: String, email: String, age: Int)
</pre>
<p>Nous définissons d’abord la fonction qui extrait une adresse email à partir d’une instance de Person :</p>
<pre class="brush: scala; title: ; notranslate">
def extractEmail(person: Person) = person.email
</pre>
<p>Puis nous passons cette fonction à la méthode map de la liste afin de récupérer la liste des adresses email.</p>
<pre class="brush: scala; title: ; notranslate">
def extractEmails(persons: List[Person]): List[String] = persons.map(extractEmail)
</pre>
<p>Sur le même principe voici la définition de la fonction <strong>extractNames</strong> :</p>
<pre class="brush: scala; title: ; notranslate">
def extractName(person: Person) = person.name
def extractNames(persons: List[Person]): List[String] = persons.map(extractName)
</pre>
<div><strong>Note</strong> : Grâce aux fonctions anonymes nous pouvons nous passer des fonctions <strong>extractEmail</strong> et <strong>extractName</strong> qui n’ont pas grand intérêt.</div>
<pre class="brush: scala; title: ; notranslate">
def extractNames(persons: List[Person]): List[String] = persons.map(p =&gt; p.name)
def extractEmails(persons: List[Person]): List[String] = persons.map(p =&gt; p.email)
</pre>
<p>Qu&#8217;avons-nous gagné par rapport à avant ? Le code est plus expressif en éliminant le bruit et en mettant l’accent sur l’intention du code : &laquo;&nbsp;<em>mapper chaque élément de la liste sur son application à la fonction que nous passons à la méthode</em> <strong><em>map</em></strong>&laquo;&nbsp;.<br />
Les fonctions d’ordre supérieur rendent pratique une autre opération courante sur les collections : le filtrage.</p>
<h2>Filtrer une collection</h2>
<p>Nous disposons d’une liste de nombres entiers allant de <strong>1</strong> à <strong>15</strong> et nous souhaitons filtrer cette liste en éliminant tous les éléments qui ne sont pas des multiples de 3. Ce genre d’opération est résolu en programmation fonctionnelle avec la fonction d’ordre supérieur filter. Elle prend en arguments une liste et un <strong>prédicat</strong>, une fonction qui retourne &laquo;&nbsp;vrai&nbsp;&raquo; ou &laquo;&nbsp;faux&nbsp;&raquo;. Dans notre exemple le prédicat retourne “vrai” si son argument est un multiple de 3 et &laquo;&nbsp;faux&nbsp;&raquo; dans le cas contraire. Scala étant un langage orienté-objet <strong><em>filter</em></strong> est une méthode de <strong><a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.List"><em>List</em></a></strong>.<br />
Voici la définition du prédicat :</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; def isMultipleOfThree(number: Int) = number % 3 == 0
isMultipleOfThree: (number: Int)Boolean
scala&gt; isMultipleOfThree(2)
res0: Boolean = false
scala&gt; isMultipleOfThree(6)
res1: Boolean = true
</pre>
<p>Et la liste de nombres :</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
numbers: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
</pre>
<p>Le filtrage s’effectue simplement en passant la fonction <strong><em>isMultipleOfThree</em></strong> à la méthode <strong><em>filter</em></strong> de la liste de nombres :</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; val multiplesOfThree = numbers.filter(isMultipleOfThree)
multiplesOfThree: List[Int] = List(3, 6, 9, 12, 15)
</pre>
<p>Ceci peut être réécrit en remplaçant <strong>isMultipleOfThree</strong> par une fonction anonyme :</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; numbers.filter(number =&gt; number % 3 == 0)
res2: List[Int] = List(3, 6, 9, 12, 15)
</pre>
<p>Nous allons maintenant combiner <strong><em>filter</em></strong> et <strong><em>map</em></strong>.</p>
<h2>Combiner filter et map</h2>
<p>Nous souhaitons obtenir la somme des doubles des multiples de <strong>3</strong> compris entre <strong>1</strong> et <strong>15</strong>. Cela correspond à une opération de filtrage (suppression des nombres non multiples de <strong>3</strong>) suivie d’une transformation des éléments (doublement des éléments des éléments restants) et enfin une opération de réduction (la sommation). On y arrive aisément avec le code suivant :</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
numbers: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
scala&gt; numbers.filter(number =&gt; number % 3 == 0).map(number =&gt; number * 2).sum
res7: Int = 90
</pre>
<p>Il nous reste une dernière fonction d’ordre supérieur à découvrir avant de conclure cet article : la fonction <strong><em>fold</em></strong>.</p>
<h2>La fonction fold, le couteau suisse</h2>
<p>La fonction <strong>fold</strong> est un véritable couteau suisse. Elle réduit les éléments d’une liste en une valeur. Cette fonction existe en deux versions : l’une (<strong><em>foldLeft</em></strong>) parcourt la liste de la gauche vers la droite et l’autre de la droite vers la gauche (<strong><em>foldRight</em></strong>). Nous allons plutôt utiliser la première dont voici la signature :</p>
<pre class="brush: scala; title: ; notranslate">
def foldLeft[B](z: B)(f: (B, A) ⇒ B): B
</pre>
<p>C’est une fonction <a href="http://fr.wikipedia.org/wiki/Curryfication">curryfiée</a>. Elle prend une valeur initiale de type <strong>B</strong>, désignée par <strong><em>z</em></strong> et une fonction <strong><em>f</em></strong> prenant deux arguments de types <strong>A</strong> (le type des éléments de la liste) et B. Pour chaque élément de la liste la fonction <strong><em>f</em></strong> est invoquée. <strong><em>f</em></strong> est invoquée avec la valeur initiale z fournie à la méthode <strong><em>foldLeft</em></strong>. Puis la valeur résultante est passée avec le deuxième élément de la liste à la fonction <strong><em>f</em></strong>. Ce processus continue avec tous les éléments de la liste. Pensez à lire <a href="http://www.arolla.fr/blog/2011/10/listes-scala-methodes-foldleft-et-foldright/">cet article</a> si vous souhaitez en savoir davantage. Place à l’action !</p>
<p>Afin de comprendre comment fonctionne <strong><em>foldLeft</em></strong> nous allons résoudre trois petits problèmes. Le premier problème consiste à faire la somme des éléments d’une liste d’entiers.<br />
La valeur initiale dans le cas de la somme est <strong>0</strong> (l’élément neutre de l’addition) et la fonction <strong><em>f</em></strong> additionne ces deux paramètres. Voici ce que cela donne dans le REPL :</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; val nums = List(1, 2, 3, 4)
nums: List[Int] = List(1, 2, 3, 4)
scala&gt; val sum = nums.foldLeft(0)((acc, num) =&gt; acc + num)
sum: Int = 10
scala&gt; val nums2 = List(1, 3, 5, 7)
nums2: List[Int] = List(1, 3, 5, 7)
scala&gt; val sum2 = nums2.foldLeft(0)((acc, num) =&gt; acc + num)
sum2: Int = 16
</pre>
<p>Simple non ?! Ne nous arrêtons pas en si bon chemin continuons sur le deuxième problème : faire le produit des éléments d&#8217;une liste. La valeur initiale passée à foldLeft dans ce cas est l’élément neutre de la multiplication à savoir <strong>1</strong>. Quant à la fonction à passer foldLeft elle fait le produit de ces deux paramètres.</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; val nums = List(1, 2, 3, 4)
nums: List[Int] = List(1, 2, 3, 4)
scala&gt; val prod = nums.foldLeft(1)((acc, num) =&gt; acc * num)
prod: Int = 24
scala&gt; val nums2 = List(1, 3, 5, 7)
nums2: List[Int] = List(1, 3, 5, 7)
scala&gt; val prod2 = nums2.foldLeft(1)((acc, num) =&gt; acc * num)
prod2: Int = 105
</pre>
<p>So far so good! Maintenant résolvons le dernier exercice pour la route. Il s’agit de construire à partir d’une liste d’entiers une map dont les clés sont les éléments pairs de la liste et les valeurs leurs doubles. Voyons un exemple afin de clarifier les choses :</p>
<pre>List(7, 2, 10, 8, 6) -&gt; Map(2 -&gt; 4, 10 -&gt; 20, 6 -&gt; 12)</pre>
<p>La valeur initiale est une map vide. La fonction passée à <strong><em>foldLeft</em></strong> prend une map et un entier. Si l’entier est pair son double est mappé sur sa valeur. La fonction retourne la map résultante.</p>
<pre class="brush: scala; title: ; notranslate">
scala&gt; val nums = List(1, 2, 3, 4)
nums: List[Int] = List(1, 2, 3, 4)

scala&gt; val evenDoubled = nums.foldLeft(Map[Int, Int]()) { (acc, num) =&gt;
| if (num % 2 == 0) acc + ((num, 2 * num)) else acc
| }
evenDoubled: scala.collection.immutable.Map[Int,Int] = Map(2 -&gt; 4, 4 -&gt; <img src='http://www.arolla.fr/blog/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' />
</pre>
<h2>Pour conclure</h2>
<p>Nous arrivons à la fin de cette introduction aux fonctions d’ordre supérieur. Elles sont particulièrement adaptées aux traitements sur des collections. Mais leur usage va au-delà des collections. Consultez la liste de références ci-dessous pour aller loin.</p>
<h2>Références</h2>
<ul>
<li><a href="http://en.wikipedia.org/wiki/Higher-order_function">Higher Order functions</a></li>
<li><a href="http://learnyouahaskell.com/higher-order-functions">Learn you a Haskell for Great Good !</a></li>
<li><a href="http://vimeo.com/53013378">Pure, functional Javascript</a></li>
</ul>
<div id="tweetbutton1411" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fb4e6m6c&amp;via=ArollaFr&amp;text=Les%20fonctions%20et%20les%20fonctions%20d%E2%80%99ordre%20sup%C3%A9rieur&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2013%2F01%2Fles-fonctions-et-les-fonctions-d%25e2%2580%2599ordre-superieur%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2013/01/les-fonctions-et-les-fonctions-d%e2%80%99ordre-superieur/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Commentaires sur les commentaires</title>
		<link>http://www.arolla.fr/blog/2013/01/commentaires-sur-les-commentaires/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=commentaires-sur-les-commentaires</link>
		<comments>http://www.arolla.fr/blog/2013/01/commentaires-sur-les-commentaires/#comments</comments>
		<pubDate>Mon, 14 Jan 2013 08:25:17 +0000</pubDate>
		<dc:creator>christophe michel</dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[commentaires]]></category>
		<category><![CDATA[qualité]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1443</guid>
		<description><![CDATA[Lorsqu’on vous a parlé de qualité de code, on vous a sûrement déjà parlé des commentaires. On vous a peut-être dit qu’il était important d’avoir du code bien commenté, voire abondamment commenté. Alors vous ouvrez votre IDE, vous le configurez aux petits oignons et vous commencez à comm&#8230; Minute ! Tous les commentaires ne sont [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">Lorsqu’on vous a parlé de qualité de code, on vous a sûrement déjà parlé des commentaires. On vous a peut-être dit qu’il était important d’avoir du code bien commenté, voire abondamment commenté.</p>
<p style="text-align: justify;">Alors vous ouvrez votre IDE, vous le configurez aux petits oignons et vous commencez à comm&#8230;</p>
<h1 style="text-align: justify;">Minute !</h1>
<p style="text-align: justify;">Tous les commentaires ne sont pas nés égaux. En fait le code source de la plupart des applications est encombré de commentaires parfaitement inutiles et il en découle que des commentaires en quantité ne signifient pas que le code est correctement documenté.</p>
<p style="text-align: justify;">Il existe de nombreux types de commentaires néfastes, mais il y en a deux qui en constituent la grande majorité : les radoteurs et les menteurs.</p>
<p style="text-align: justify;">Les premiers se reconnaissent immédiatement :</p>
<p style="text-align: justify;"><img src="https://docs.google.com/document/d/12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI/pubimage?id=12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI&amp;image_id=1mCxuPX2mSmeEIaDSwgOCYL0i93mr9ZRd" alt="" width="221" height="150" /></p>
<p style="text-align: justify;">Souvent générés automatiquement, ces commentaires n’apportent strictement aucune information. A bannir, donc.</p>
<p style="text-align: justify;">Les menteurs quant à eux posent un autre problème :</p>
<p style="text-align: justify;"><img src="https://docs.google.com/document/d/12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI/pubimage?id=12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI&amp;image_id=16BSR-725ngbWm3y2MnjpVKNExsgCUVTS" alt="" width="304" height="163" /></p>
<p style="text-align: justify;">Rien ne vous choque ? Il a y contradiction entre le code et le commentaire. Écrire des commentaires a un prix, ils doivent être maintenus pour rester cohérents avec le code. C’est pour cette raison qu’on ne doit commenter du code que lorsque c’est indispensable à sa compréhension.</p>
<h1 style="text-align: justify;">Informer sans commenter</h1>
<p style="text-align: justify;">Le point clé pour ne pas avoir à écrire des commentaires qui risquent de devenir obsolètes, c’est d’écrire du code qui s’explique tout seul. Cela veut dire exprimer clairement ses intentions au travers du code.</p>
<p style="text-align: justify;">Le choix des noms dans le code est primordial car ils portent la plus grande part de l’information sur l’intention du développeur.</p>
<p style="text-align: justify;">Les noms de classes, de fonctions et de variables doivent avoir du sens, être clairs et sans ambiguïté. Idéalement, on cherchera à avoir des noms prononçables et concis.</p>
<p style="text-align: justify;">Voici deux fonctions qui font exactement la même chose, néanmoins la seconde est compréhensible sans qu’il n’y ait besoin d’explications supplémentaires.</p>
<p style="text-align: justify;"><img src="https://docs.google.com/document/d/12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI/pubimage?id=12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI&amp;image_id=1lnDOoUqfCKnniz54AcykoRcOlZK-rEkb" alt="" width="553" height="99" /></p>
<p style="text-align: justify;">Il est également recommandé de maintenir une certaine cohérence pour les noms au travers de l’application, ce qui renforce la compréhension. On veillera par exemple à utiliser les verbes (de type “fetch”, “get”, “delete”, “update”) de la même façon dans tout le code.</p>
<h1 style="text-align: justify;">Améliorer la structure</h1>
<p style="text-align: justify;">Pour rendre plus explicite un programme, on peut jouer sur une autre dimension et faire émerger des noms dans le code par refactoring : extraction d’expression dans des variables locales, extraction de code dans de nouvelles méthodes ou de nouvelles classes sont autant d’occasions de mettre un nom explicite sur une portion de code.</p>
<p style="text-align: justify;">Cette technique permet d’expliquer simplement des expressions régulières (souvent cryptiques pour qui n’a pas l’habitude) ou des expressions booléennes complexes :</p>
<p style="text-align: justify;"><img src="https://docs.google.com/document/d/12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI/pubimage?id=12JQ_PYuzlr_6dx3VzMDGKg04LPns7henpawz-NmkrJI&amp;image_id=1z4nhgvsQc2RTRxe5buKMxgq0U4-XquYY" alt="" width="589" height="160" /></p>
<p style="text-align: justify;">Ce travail est applicable à toutes les échelles de l’application et peut donc être appliqué sur des portions très locales, dans une perspective d’amélioration d’un existant. Faire l’effort de donner un nom à un concept oblige à réfléchir à sa cohérence et sa bonne formalisation : lorsqu’il est difficile de trouver un nom, c’est en général signe d’un problème dans la conception (le cas est criant pour les classes et permet de détecter rapidement les violations du Single Responsibility Principle)</p>
<h1 style="text-align: justify;">Un peu d’amour quand même</h1>
<p style="text-align: justify;">Si minimiser la part des commentaires dans son application est avisé, il ne s’agit pas pour autant de les éradiquer. Ils restent un outil indispensable au développeur.</p>
<p style="text-align: justify;">Ils permettent de fournir de l’information “hors code” (prévenir qu’un test unitaire est très long à exécuter), placer des marqueurs à destination du développeur (TODO, FIXME, à utiliser avec parcimonie) et parfois de clarifier un peu plus l’intention, comme par exemple de dire quel algorithme a été utilisé.</p>
<p style="text-align: justify;">Par ailleurs, dès lors que l’on travaille sur une API publique, une bonne documentation via commentaires (javadoc notamment) est indispensable.</p>
<p style="text-align: justify;">En attendant, n’oubliez jamais, le code est écrit pour être lu !</p>
<div id="tweetbutton1443" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fb588694&amp;via=ArollaFr&amp;text=Commentaires%20sur%20les%20commentaires&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2013%2F01%2Fcommentaires-sur-les-commentaires%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2013/01/commentaires-sur-les-commentaires/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>TDD Vs. math formalism: friend or foe?</title>
		<link>http://www.arolla.fr/blog/2013/01/tdd-vs-math-formalism-friend-or-foe/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=tdd-vs-math-formalism-friend-or-foe</link>
		<comments>http://www.arolla.fr/blog/2013/01/tdd-vs-math-formalism-friend-or-foe/#comments</comments>
		<pubDate>Mon, 07 Jan 2013 09:37:07 +0000</pubDate>
		<dc:creator>Cyrille</dc:creator>
				<category><![CDATA[Bonnes pratiques de dév]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[cycle]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[domain]]></category>
		<category><![CDATA[enum]]></category>
		<category><![CDATA[established]]></category>
		<category><![CDATA[finance]]></category>
		<category><![CDATA[formalism]]></category>
		<category><![CDATA[group]]></category>
		<category><![CDATA[IMM]]></category>
		<category><![CDATA[integers]]></category>
		<category><![CDATA[maths]]></category>
		<category><![CDATA[ordering]]></category>
		<category><![CDATA[partial order]]></category>
		<category><![CDATA[supple]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1437</guid>
		<description><![CDATA[It is not uncommon to oppose the empirical process of TDD, together with its heavy use of unit tests, to the more mathematically based techniques, with the  &#171;&#160;formal methods&#160;&#187; and formal verification at the other end of the spectrum. However I experienced again recently that the process of TDD can indeed help discover and draw [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">It is not uncommon to oppose the empirical process of TDD, together with its heavy use of unit tests, to the more mathematically based techniques, with the  &laquo;&nbsp;formal methods&nbsp;&raquo; and formal verification at the other end of the spectrum. However I experienced again recently that the process of TDD can indeed help discover and draw upon math formalisms well-suited to the problem considered. We then benefit from the math formalism for an easier implementation and correctness.</p>
<p style="text-align: justify;">It is quite frequent that maths structures, or more generally « established formalisms » as Eric Evans would say, are hidden everywhere in the business concepts we need to model in software.</p>
<p style="text-align: justify;">Dates and how we take liberties with them for trading of financial instruments offer a good example of a business concept with an underlying math structure: traders of futures often use a notation like ‘U8′ to describe an expiry date like September 2018; ‘U’ means September, and the ’8′ digit refers to 2018, but also to 2028, and 2038 etc. Notice that this notation only works for 10 years, and each code is recycled every decade.</p>
<div id="attachment_3741" style="text-align: justify;"><a href="http://cyrille.martraire.com/wp-content/uploads/2013/01/IMM-pit.jpg"><img title="IMM-pit" src="http://cyrille.martraire.com/wp-content/uploads/2013/01/IMM-pit-300x168.jpg" alt="" width="300" height="168" /></a>The IMM trading floor in the early 70&#8242;s (photo CME Group)</div>
<p style="text-align: justify;">In the case of IMM contract codes, we only care about quarterly dates on:</p>
<ul style="text-align: justify;">
<li>March (H)</li>
<li>June (M)</li>
<li>September (U)</li>
<li>December (Z)</li>
</ul>
<p style="text-align: justify;">This yields only 4 possibilities for the month, combined with the 10 possible year digits, hence 40 different codes in total, over the range of 10 years.</p>
<h2 style="text-align: justify;">How does that translate into source code?</h2>
<p style="text-align: justify;">As a software developer we are asked all the time to manage such IMM expiry codes:</p>
<ul style="text-align: justify;">
<li><strong>Sort</strong> a given set of IMM contract codes</li>
<li>Find the <strong>next</strong> contract from the current « leading month » contract</li>
<li>Enumerate the <strong>next 11</strong> codes from the current « leading month » contract, etc.</li>
</ul>
<p style="text-align: justify;">This is often done ad hoc with a gazillion of functions for each use-case, leading to thousands of lines of code hard to maintain because they involve parsing of the ‘U8′ format everytime we want to calculate something.</p>
<p style="text-align: justify;">With TDD, we can now tackle this topic with more rigor, starting with tests to define what we want to achieve.</p>
<p style="text-align: justify;">The funny thing is that in the process of doing TDD, the cyclic logic of the IMM codes struck me and strongly reminded me of the cyclic group Z/nZ. I had met this strange maths creature at school many years ago, I had a hard time with it by the way. But now on a real example it was definitely more interesting!</p>
<address><a href="https://github.com/cyriux/RealWorldAlgebra" target="_blank">The source code (Java) for this post is on Github</a>.</address>
<h2 style="text-align: justify;">Draw on established formalisms</h2>
<p style="text-align: justify;">Thanks to Google it is easy to find something even with just a vague idea of how it’s named, and thanks to Wikipedia, it is easy to find out more about any established formalism like <a href="http://en.wikipedia.org/wiki/Cyclic_group">Cyclic Groups</a>. In particular we find that:</p>
<blockquote><p>Every finite cyclic group is isomorphic to the group { [0], [1], [2], …, [n − 1] } of integers modulo n under addition</p></blockquote>
<p style="text-align: justify;">The Wikipedia page also mentions a concept of the product of cyclic groups in relation with their order (here the number of elements). Looks like this is the math-ish way to say that 4 possibilities for quarterly months combined with 10 possible year digits give 40 different codes in total.</p>
<p style="text-align: justify;">So what? Sounds like we could identity the set of the 4 months to a cyclic group, the set of the 10 year digits to another, and that even the combination (product) of both also looks like a cyclic group of order 10 * 4 = 40 (even though the addition operation will not be called like that). So what?</p>
<p style="text-align: justify;">Because we’ve just seen that there is an isomorphism between any finite cyclic group and the cyclic group of integer of the same order, we can just switch to the integer cyclic group logic (plain integers and the modulo operator) to simplify the implementation big time.</p>
<p style="text-align: justify;">Basically the idea is to convert from the IMM code « Z3″ to the corresponding ‘ordinal’ integer in the range 0..39, then do every operation on this ‘ordinal’ integer instead of the actual code. Then we can format back to a code « Z3″ whenever we really need it.</p>
<h2 style="text-align: justify;">Do I still need TDD when I have a complete formal solution?</h2>
<p style="text-align: justify;">I must insist that I did not came to this conclusion as easily. The process of TDD was indeed very helpful not to get lost in every possible direction along the way. Even when you have found a formal structure that could solve your problem in one go, even in a « formal proof-ish fashion », then perhaps you need less tests to verify the correctness, but you sure still need tests to think on the specification part of your problem. This is your gentle reminded that TDD is not about unit tests.</p>
<h2 style="text-align: justify;">Partial order in a cyclic group</h2>
<p style="text-align: justify;">Given a list of IMM codes we often need to sort them for display. The problem is that a cyclic group has no total order, the ordering depends on where you are in time.</p>
<p style="text-align: justify;"><a href="http://cyrille.martraire.com/wp-content/uploads/2013/01/cycle_of_week_days.png"><img title="cycle_of_week_days" src="http://cyrille.martraire.com/wp-content/uploads/2013/01/cycle_of_week_days-300x158.png" alt="" width="300" height="158" /></a></p>
<p style="text-align: justify;">Let’s take the example of the days of the week that also forms a cycle: MONDAY, TUESDAY, WEDNESDAY…SUNDAY, MONDAY etc.</p>
<p style="text-align: justify;">If we only care about the future, is MONDAY before WEDNESDAY? Yes, except if we’re on TUESDAY. If we’re on TUESDAY, MONDAY means next MONDAY hence comes after WEDNESDAY, not before.</p>
<p style="text-align: justify;">This is why we cannot unfortunately just implement Comparable to take care of the ordering. Because we need to consider a reference IMM code-aware partial order, we need to resort to a Comparator that takes the reference IMM code in its constructor.</p>
<p style="text-align: justify;">Once we identify that situation to the cyclic group of integers, it becomes easy to shift both operands of the comparison to 0 before comparing them in a safe (total order-ish) way. Again, this trick is made possible by the freedom to experiment given by the TDD tests. As long as we’re still green, we can go ahead and try any funky approach.</p>
<h2 style="text-align: justify;">Try it as a kata</h2>
<p style="text-align: justify;">This example is also a good coding kata that we’ve tried at work not long ago. Given a simple presentation of the format of an IMM contract code, you can choose to code the sort, find the next and previous code, and perhaps even optimize for memory (cache the instances, e.g. lazily) and speed (cache the toString() value, e.g. in the constructor) if you still have some time.</p>
<h2 style="text-align: justify;">In closing</h2>
<p style="text-align: justify;">Maths structures are hidden behind many common business concepts. I developed an habit to look for them whenever I can, because they always help make us think, they help question our understanding of the domain problem (« is my domain problem really similar in some way to this structure? »), and of course because they often offer wonderful ready-made implementation hints!</p>
<address><a href="https://github.com/cyriux/RealWorldAlgebra" target="_blank">The source code (Java) for this post is on Github</a>.</address>
<div id="tweetbutton1437" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fb2dr5ur&amp;via=ArollaFr&amp;text=TDD%20Vs.%20math%20formalism%3A%20friend%20or%20foe%3F&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2013%2F01%2Ftdd-vs-math-formalism-friend-or-foe%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2013/01/tdd-vs-math-formalism-friend-or-foe/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DDD is back in Paris with a brand new Meetup group!</title>
		<link>http://www.arolla.fr/blog/2013/01/ddd-is-back-in-paris-with-a-brand-new-meetup-group/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ddd-is-back-in-paris-with-a-brand-new-meetup-group</link>
		<comments>http://www.arolla.fr/blog/2013/01/ddd-is-back-in-paris-with-a-brand-new-meetup-group/#comments</comments>
		<pubDate>Fri, 04 Jan 2013 10:00:22 +0000</pubDate>
		<dc:creator>Cyrille</dc:creator>
				<category><![CDATA[Actu]]></category>
		<category><![CDATA[Bonnes pratiques de dév]]></category>
		<category><![CDATA[Evénements]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[boundedcontext]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[DDD]]></category>
		<category><![CDATA[experience]]></category>
		<category><![CDATA[junior]]></category>
		<category><![CDATA[meetup]]></category>
		<category><![CDATA[model]]></category>
		<category><![CDATA[paris]]></category>
		<category><![CDATA[senior]]></category>
		<category><![CDATA[survey]]></category>
		<category><![CDATA[ubiquitouslanguage]]></category>
		<category><![CDATA[uml]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1428</guid>
		<description><![CDATA[The first DDD Open Forum of the brand new Paris DDD meetup was last night, hosted by Arolla, and it was good to meet again after a long time with twenty-some Paris DDD aficionados! @tjaskula, the organizer of this new group, opened the evening with a welcome introduction. He also gave many suggestions of areas for [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">The first DDD Open Forum of the brand new <a href="http://www.meetup.com/DDD-Paris/">Paris DDD meetup</a> was last night, hosted by <a href="http://www.arolla.fr/">Arolla</a>, and it was good to meet again after a long time with twenty-some Paris DDD aficionados!</p>
<p style="text-align: justify;"><a href="https://twitter.com/tjaskula">@tjaskula</a>, the organizer of this new group, opened the evening with a welcome introduction. He also gave many suggestions of areas for discussion and debate.</p>
<p style="text-align: justify;"><a href="http://cyrille.martraire.com/wp-content/uploads/2013/01/photo-1.jpg"><img title="photo 1" src="http://cyrille.martraire.com/wp-content/uploads/2013/01/photo-1.jpg" alt="" width="288" height="384" /></a></p>
<p style="text-align: justify;">A quick survey revealed that one third of the participants were new to Domain-Driven Design, while another third was on the other hand rather comfortable with it. This correlated with a rather senior audience, with only one attendee with less than 5 years experience and many 10+ years developers, including 22 years and 30 years experience developers, and still coding! If you work in Paris, I guess you know them already…</p>
<p style="text-align: justify;">It was an open space session, so we first proposed a lot of topics for discussion with post-its on the wall: how to sell or convince about DDD, introduction on concepts, synchronizing between contexts…</p>
<p style="text-align: justify;"><a href="http://cyrille.martraire.com/wp-content/uploads/2013/01/photo-3.jpg"><img title="photo 3" src="http://cyrille.martraire.com/wp-content/uploads/2013/01/photo-3-225x300.jpg" alt="" width="225" height="300" /></a></p>
<p style="text-align: justify;">We all decided to start with a walk through of the fundamentals of DDD: Bounded Contexts, Ubiquitous Language, Code as Model… It was great to have this two-way knowledge transfer between seniors and juniors, in an interactive fashion and with lot of questions, including some rather challenging and skeptical ones! There was also some UML bashing of course.</p>
<p style="text-align: justify;">We concluded by eating <a href="http://en.wikipedia.org/wiki/King_cake">Galettes des Rois</a>, together with cider and beer, and a lot of fun. Thanks everyone for your questions and contributions, and see you soon on next meetup!</p>
<div id="attachment_3728">
<p><a href="http://cyrille.martraire.com/wp-content/uploads/2013/01/photo-4.jpg"><img title="photo 4" src="http://cyrille.martraire.com/wp-content/uploads/2013/01/photo-4-300x225.jpg" alt="" width="300" height="225" /></a></p>
<p style="text-align: justify;">The many proposals for discussion</p>
</div>
<div id="tweetbutton1428" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Faavlvtf&amp;via=ArollaFr&amp;text=DDD%20is%20back%20in%20Paris%20with%20a%20brand%20new%20Meetup%20group%21&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2013%2F01%2Fddd-is-back-in-paris-with-a-brand-new-meetup-group%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2013/01/ddd-is-back-in-paris-with-a-brand-new-meetup-group/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Il y a peut être une option pour continuer ¡¿ (réflexion sur la programmation par continuation)</title>
		<link>http://www.arolla.fr/blog/2012/12/option-maybe-continuation/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=option-maybe-continuation</link>
		<comments>http://www.arolla.fr/blog/2012/12/option-maybe-continuation/#comments</comments>
		<pubDate>Wed, 05 Dec 2012 13:35:00 +0000</pubDate>
		<dc:creator>Arnauld</dc:creator>
				<category><![CDATA[Fonctionnel]]></category>
		<category><![CDATA[Programmation]]></category>
		<category><![CDATA[continuation]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[maybe]]></category>
		<category><![CDATA[option]]></category>
		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1381</guid>
		<description><![CDATA[L&#8217;une des difficultés principales lorsque l&#8217;on aborde la programmation par événement est qu&#8217;il faut changer sa manière de penser: l&#8217;appel d&#8217;une méthode ne renvoie pas de résultat. Lorsque le résultat est disponible, celui-ci est à son tour publié sur un bus ou fourni à une fonction de rappel passée en paramètre lors de l&#8217;appel. C&#8217;est [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">L&#8217;une des difficultés principales lorsque l&#8217;on aborde la programmation par événement est qu&#8217;il faut changer sa manière de penser: l&#8217;appel d&#8217;une méthode ne renvoie pas de résultat. Lorsque le résultat est disponible, celui-ci est à son tour publié sur un bus ou fourni à une fonction de rappel passée en paramètre lors de l&#8217;appel. C&#8217;est cette dernière option que nous allons aborder dans cet article: la programmation par continuation.</p>
<p style="text-align: justify;"><span id="more-1381"></span></p>
<blockquote><p>En programmation fonctionnelle, la programmation par continuation désigne une technique de programmation consistant à n&#8217;utiliser que de simples appels de fonction qui prennent pour argument leur propre continuation, au lieu d&#8217;appeler séquentiellement des fonctions, ou d&#8217;exécuter une fonction sur le résultat de la précédente. Ces fonctions se retrouvent en quelque sorte maîtresses de leur destin, et ne se contentent plus de subir le contexte.</p>
<p><a href="http://fr.wikipedia.org/wiki/Continuation">Continuation</a> ~ Wikipedia</p></blockquote>
<p style="text-align: justify;">Le schéma de pensée doit alors s&#8217;orienter vers une méthode de programmation plus fonctionnelle<sup><a href="#func1">1</a></sup> que procédurale.<br />
Bien que cela paraisse plus compliqué à mettre en place au départ, cela permet une souplesse et une modularisation beaucoup plus grande et une testabilité facilitée.</p>
<p style="text-align: justify;"><em><a name="func1"></a>[1] Nous parlons ici de programmation fonctionnelle au sens de fonction uniquement et non son paradigme standard qui prône l&#8217;immutabilité des données. Une fonction devient un citoyen de premier ordre au même titre qu&#8217;une classe. Java n&#8217;ayant pas cette dimension, nous ferons une utilisation intensive des classes anonymes pour compenser cela.</em></p>
<blockquote>
<h2>Des fonctions passées en paramètre</h2>
<p>(&#8230;) Un mécanisme puissant des langages fonctionnels est l&#8217;usage des fonctions d&#8217;ordre supérieur. Une fonction est dite d&#8217;ordre supérieur lorsqu&#8217;elle peut prendre des fonctions comme argument (aussi appelées callback) et/ou renvoyer une fonction comme résultat. On dit aussi que les fonctions sont des objets de première classe, ce qui signifie qu&#8217;elles sont manipulables aussi simplement que les types de base.</p>
<p><a href="http://fr.wikipedia.org/wiki/Programmation_fonctionnelle">Programmation fonctionnelle</a> ~ Wikipedia</p></blockquote>
<p style="text-align: justify;">Nous allons voir plusieurs techniques permettant de faciliter l&#8217;intégration d&#8217;une approche fonctionnelle à un code orienté objet. Le but n&#8217;est pas de tout écrire dans un paradigme ou un autre, mais simplement de voir comment une approche peut compléter et enrichir l&#8217;autre.<br />
Après avoir défini nos techniques de bases, nous les appliquerons plus concrètement à différents cas d&#8217;utilisation.</p>
<p style="text-align: justify;">Prenons comme base de travail une application qui gère des questionnaires (Quiz).</p>
<h2 style="text-align: justify;">&laquo;&nbsp;Sans technique, la puissance n&#8217;est rien&nbsp;&raquo; <em>— Aurait aussi pu dire le pneu</em></h2>
<p style="text-align: justify;">Notre application doit tout d&#8217;abord permettre de créer un questionnaire.<br />
Afin de permettre la récupération du questionnaire créé, il est nécessaire de définir une fonction de rappel. Optons pour une approche générique et réutilisable (les noms des interfaces que nous définirons reprennent les noms standards que l&#8217;on retrouve en <a href="http://www.haskell.org">Haskell</a>, <a href="http://www.scala-lang.org/">Scala</a> ou encore la librairie <a href="http://functionaljava.org">FunctionalJava</a>.</p>
<pre class="brush: java; title: ; notranslate">
public interface Effect&lt; T&gt; {
  void e(T value);
}
</pre>
<p style="text-align: justify;">Cette interface décrit une méthode abstraite prenant un unique paramètre. Notre service pourra alors appeler cette fonction<sup><a href="#func2">2</a></sup> avec le <tt>quiz</tt> qu&#8217;il aura tout juste créé.</p>
<p style="text-align: justify;"><em><a name="func2"></a>[2] Nous utiliserons le mot &laquo;&nbsp;fonction&nbsp;&raquo; bien qu&#8217;elle ne renvoie aucun résultat et au risque d&#8217;en choquer certain nous n&#8217;utiliserons pas le mot procédure car il nous détournerait de notre vision: la lourdeur des procédures n&#8217;a d’intérêt que pour les <strong>fonction</strong>aires.</em></p>
<p style="text-align: justify;">La première version de notre service peut s&#8217;écrire:</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  ...
  public void create(String quizContent, Effect&lt;Quiz&gt; effect) {
    Quiz quiz = quizFactory.create(nextId(), quizContent);
    effect.e(quiz);
  }
}
</pre>
<p style="text-align: justify;">Notre service délègue la création du <tt>quiz</tt> à la fabrique (ligne 4). La fonction de rappel <tt>effect</tt> passée en paramètre est ensuite invoquée avec l&#8217;instance nouvellement créée (ligne 5).</p>
<p style="text-align: justify;">Nous venons de voir notre première technique:</p>
<h4 style="text-align: justify;"><span class="label notice">Première technique</span></h4>
<p style="text-align: justify;"><strong>Ajouter une fonction supplémentaire comme paramètre lors de l&#8217;appel d&#8217;une méthode. Cette fonction pourra alors être appelée avec le résultat du calcul lorsque celui sera disponible.</strong></p>
<p style="text-align: justify;">Imaginons maintenant que la construction d&#8217;une nouvelle instance de quiz nécessite plusieurs vérifications: il est impératif qu&#8217;un <tt>quiz</tt> soit unique (sinon il devient trop facile de tricher). Rajoutons pour cela un appel afin de vérifier cet invariant:</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void create(String quizContent, Effect&lt;Quiz&gt; effect) {
    if(quizIsUnique(quizContent)) {
        Quiz quiz = quizFactory.create(nextId(), quizContent);
        effect.e(quiz);
      }
    }
}
</pre>
<p style="text-align: justify;">Bon rien de très fantastique, si ce n&#8217;est un nouveau souci: que se passe-t-il si notre quiz n&#8217;est pas unique !?</p>
<p style="text-align: justify;">C&#8217;est là que notre deuxième technique intervient!</p>
<p style="text-align: justify;">Auparavant définissons une nouvelle interface générique permettant de décrire une alternative entre deux types de valeurs <tt>L</tt> et <tt>R</tt>. Il est de coutume d’appeler les différentes alternatives &laquo;&nbsp;Left&nbsp;&raquo; et &laquo;&nbsp;Right&nbsp;&raquo; (toute ressemblance avec un contexte politique est purement fortuite). Une instance de cette interface peut donc soit contenir une instance de type <tt>L</tt> soit une instance de type <tt>R</tt>.</p>
<pre class="brush: java; title: ; notranslate">
public interface Either&lt;L,R&gt; {
  boolean isLeft();
  L left();
  boolean isRight();
  R right();
}
</pre>
<p>&nbsp;</p>
<pre class="brush: java; title: ; notranslate">
public class Eithers {
  public static &lt;L,R&gt; Either&lt;L,R&gt; left(L value) {
    return new Left(value);
  }
  public static &lt;L,R&gt; Either&lt;L,R&gt; right(L value) {
    return new Right(value);
  }
}
</pre>
<p style="text-align: justify;">L&#8217;implémentation &laquo;&nbsp;Left&nbsp;&raquo; correspondante peut alors s&#8217;écrire:</p>
<pre class="brush: java; title: ; notranslate">
public final class Left&lt;L,R&gt; implements Either&lt;L,R&gt; {
  private final L value;
  public Left(L value)    { this.value = value; }
  public boolean isLeft() { return true;  }
  public L left()         { return value; }
  public boolean isRight(){ return false; }
  public R right()        { throw new IllegalStateException(&quot;Sorry only left is allowed!&quot;); }
}
</pre>
<p style="text-align: justify;">On peux aisément en déduire l&#8217;implémentation &laquo;&nbsp;Right&nbsp;&raquo;:</p>
<pre class="brush: java; title: ; notranslate">
public final class Right&lt;L,R&gt; implements Either&lt;L,R&gt; {
  private final R value;
  public Right(R value)   { this.value = value; }
  public boolean isLeft() { return false; }
  public L left()         { throw new IllegalStateException(&quot;Sorry only right is allowed!&quot;); }
  public boolean isRight(){ return true;  }
  public R right()        { return value; }
}
</pre>
<p style="text-align: justify;">Et un petit exemple avec une méthode qui divise un entier par un autre:</p>
<ul style="text-align: justify;">
<li>soit le dénominateur est différent de zéro et tout va bien, la fonction renvoie le résultat</li>
<li>soit le dénominateur est égale à zéro, la fonction renvoie alors un message indiquant que ça va pas</li>
</ul>
<pre class="brush: java; title: ; notranslate">
public static Either&lt;Float,String&gt; div(int numerator, int denominator) {
  if(denominator!=0) {
    float res = (float)numerator / (float)denominator;
    return Eithers.left(res);
  }
  else {
    return Eithers.right(&quot;Divide by zero error&quot;);
  }
}
</pre>
<p style="text-align: justify;">Revenons à la création de notre <tt>quiz</tt>: soit il est unique et tout va bien soit il ne l&#8217;est pas et ça va pas&#8230; ça ressemble fort à notre alternative. Modifions alors la signature de notre fonction de rappel afin de prendre comme résultat une alternative: notre fonction de rappel <tt>Effect</tt> devient alors <tt>Effect&lt;Either&gt;</tt>.</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void create(String quizContent, Effect&lt;Either&lt;Quiz,Failure&gt;&gt; effect) {
    if(quizIsUnique(quizContent)) {
      Quiz quiz = quizFactory.create(nextId(), quizContent);
      Either&lt;Quiz,Failure&gt; left = Eithers.left(quiz);
      effect.e(left);
    }
    else {
      // Failure is a Pojo but could also be an UniqueConstraintException
      Failure failure = new Failure(Code.NonUniqueQuiz);
      Either&lt;Quiz,Failure&gt; right = Eithers.right(failure);
      effect.e(right);
    }
  }
}
</pre>
<p style="text-align: justify;">Soit le <tt>quiz</tt> est unique (ligne 3) dans ce cas l&#8217;alternative est construite avec le <tt>quiz</tt> &#8211; alternative <tt>left</tt> &#8211; (ligne 5) puis passée à la fonction de rappel (ligne 6). Dans le cas contraire, l&#8217;alternative est construite autour d&#8217;un code d&#8217;erreur &#8211; alternative <tt>right</tt> &#8211; (ligne 11) puis passée à la fonction de rappel (ligne 12).</p>
<p style="text-align: justify;">Et voila notre deuxième technique:</p>
<h4 style="text-align: justify;"><span class="label notice">Deuxième technique</span></h4>
<p style="text-align: justify;"><strong>La fonction de rappel est définie comme prenant un résultat dont le type peut varier en fonction du déroulement du calcul&#8230;</strong></p>
<p style="text-align: justify;">Un petit aperçu de code appelant:</p>
<pre class="brush: java; title: ; notranslate">
quizService.create(&quot;&lt;question4aChampion&gt;...&quot;, new Effect&lt;Either&lt;Quiz,Failure&gt;&gt;() {
  public void e(Either&lt;Quiz,Failure&gt; res) {
    if(res.isLeft()) {
      Quiz quiz = res.left();
      displayFlashFeedback(quiz);
    }
    else {
      Failure failure = res.right();
      displayErrorFeedback(failure);
    }
  }
});
</pre>
<p style="text-align: justify;">Lorsque la fonction de rappel est invoquée, soit l&#8217;alternative passée en paramètre contient un <tt>quiz</tt> (ligne 4) dans ce cas on affiche un beau message de retour avec le <tt>quiz</tt> créé. Sinon on affiche une notification d&#8217;erreur (ligne 9).</p>
<p style="text-align: justify;">Ah, quelqu&#8217;un au fond de la salle a une remarque: &laquo;&nbsp;Comme il s&#8217;agit d&#8217;une erreur, pourquoi ne pas lancer une exception au lieu de faire une alternative, soit on a le résultat soit on lance une exception?&nbsp;&raquo;</p>
<p style="text-align: justify;">Hummmm&#8230; eh bien sans trop anticiper sur la suite de l&#8217;article, il faut envisager que l’exécution du code de la méthode puisse être asynchrone.<br />
Le contenu de la méthode s’exécute alors dans un autre fil d’exécution que le code qui l&#8217;a invoqué. Le code qui l&#8217;a invoqué continue à vivre son petit bonhomme de chemin et peut même ré-invoquer la même méthode, avant que la première exécution soit terminée. Si la méthode génère une exception, celle-ci sera dans le fil qui exécute le contenu de la méthode, l&#8217;appelant originel ne sera donc jamais informé, sauf si on ajoute un mécanisme du type <tt>UncaughtExceptionHandler</tt> qui se trouve n&#8217;être rien d&#8217;autre qu&#8217;une fonction de rappel appelée dans le cas d&#8217;erreur. En centralisant, les appels valides et invalides dans une unique fonction de rappel, le code est simplifié, ainsi que la vérification que notre fonction de rappel est appelée systématiquement.</p>
<p style="text-align: justify;">Ok et la troisième technique alors? Nous y sommes presque!<br />
Notre Quiz étant désormais créé, il faut le persister, et pour cela il nous faut une méthode pour le sauvegarder:</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void save(Quiz quiz) {
    repository.save(quiz);
  }
}
</pre>
<p style="text-align: justify;">Hummmm&#8230; une méthode sans retour, difficile de définir une fonction de rappel. Compliquons un peu les choses: la sauvegarde peut échouer et lancer une exception.</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void save(Quiz quiz) {
    try {
        repository.save(quiz);
    }
    catch(RepositoryException re) {
        Failure failure = new Failure(re);
        ...
    }
  }
}
</pre>
<p style="text-align: justify;">Nous nous retrouvons dans le cas précédent d&#8217;une alternative mais qui n&#8217;a qu&#8217;une seule possibilité, autrement dit un résultat optionnel: on a une erreur ou pas! Si tout se passe bien, on a pas de résultat, sinon on a une erreur. En s&#8217;inspirant de notre interface <tt>Either</tt> nous pouvons définir une nouvelle interface générique qui contient (ou pas!) quelque chose:</p>
<pre class="brush: java; title: ; notranslate">
public interface Option&lt;E&gt; {
  boolean isSome();
  boolean isNone();
  E get();
}
</pre>
<p>&nbsp;</p>
<pre class="brush: java; title: ; notranslate">
public class Options {
  public static &lt;E&gt; Option&lt;E&gt; some(E value) {
    return new Some(value);
  }
  public static &lt;E&gt; Option&lt;E&gt; none() {
    return new None();
  }
}
</pre>
<p style="text-align: justify;">Cette interface n&#8217;a que deux implémentations: une qui contient rien <tt>None</tt> et une qui contient quelque-chose <tt>Some</tt>.</p>
<p style="text-align: justify;">L&#8217;implémentation &laquo;&nbsp;Some&nbsp;&raquo; peut alors s&#8217;écrire:</p>
<pre class="brush: java; title: ; notranslate">
public final class Some&lt;E&gt; extends Option&lt;E&gt; {
  private final E value;
  public Some(E value)    { this.value = value; }
  public boolean isSome() { return true;  }
  public boolean isNone() { return false; }
  public E get()          { return value; }
}
</pre>
<p style="text-align: justify;">L&#8217;implémentation &laquo;&nbsp;None&nbsp;&raquo;:</p>
<pre class="brush: java; title: ; notranslate">
public final class None&lt;E&gt; extends Option&lt;E&gt; {
  public None() {}
  public boolean isSome() { return false;  }
  public boolean isNone() { return true; }
  public E get()          { throw new IllegalStateException(&quot;Sorry nothing to retrieve!&quot;); }
}
</pre>
<p style="text-align: justify;">Illustrons cela avec notre méthode de sauvegarde:</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void save(Quiz quiz, Effect&lt;Option&lt;Failure&gt;&gt; effect) {
    try {
      repository.save(quiz);
      effect.e(Options.none());
    }
    catch(RepositoryException re) {
      Failure failure = new Failure(re);
      effect.e(Options.some(failure));
    }
  }
}
</pre>
<p style="text-align: justify;">Si la sauvegarde se passe bien (pas d&#8217;exception) la fonction de rappel est appelée avec &laquo;&nbsp;rien&nbsp;&raquo;: <tt>Options.none()</tt> (ligne 5). Dans le cas contraire, l&#8217;exception est transformée en un objet plus adapté <tt>Failure</tt> et la fonction de rappel est appelée avec &laquo;&nbsp;quelque-chose&nbsp;&raquo;: <tt>Options.some(failure)</tt> (ligne 9).</p>
<p style="text-align: justify;">Un petit aperçu de code appelant:</p>
<pre class="brush: java; title: ; notranslate">
quizService.save(quiz, new Effect&lt;Option&lt;Failure&gt;&gt;() {
  public void e(Option&lt;Failure&gt; res) {
    if(res.isNone()) {
      displayFlashFeedback(Code.QuizSaved);
    }
    else {
      displayErrorFeedback(res.some());
    }
  }
});
</pre>
<p style="text-align: justify;">Soit la fonction de rappel est appelée avec &laquo;&nbsp;rien&nbsp;&raquo; (ligne 3) dans ce cas on affiche un beau message indiquant que la sauvegarde s&#8217;est bien passée. Dans le cas contraire (ligne 6), l&#8217;objet <tt>Failure</tt> est récupérée et un message d&#8217;erreur est affiché.</p>
<h4 style="text-align: justify;"><span class="label notice">Troisième technique</span></h4>
<p style="text-align: justify;"><strong>La fonction de rappel est définie comme prenant un résultat dont le contenu est optionnel</strong></p>
<p style="text-align: justify;">Avant d&#8217;exploiter tout cela, faisons un petit retour en arrière&#8230; Et si nous étions sûr que la sauvegarde se déroule toujours correctement, et que nous souhaitions juste être notifiés lorsque celle-ci a été réalisée, nous n&#8217;avons pas de technique pour cela! Effectivement, il n&#8217;y en a pas, mais l&#8217;on pourrait en ajouter une très simple: la fonction de rappel est définie comme ne prenant aucun argument et est invoquée lorsque l&#8217;action est arrivée au stade adéquat.<br />
L&#8217;interface <tt>Runnable</tt> peut alors tout à fait correspondre à ce cas d&#8217;utilisation.</p>
<pre class="brush: java; title: ; notranslate">
public class QuizService {
  public void save(Quiz quiz, Runnable onceSaved) {
    repository.save(quiz);
    onceSaved.run();
  }
}
</pre>
<h4 style="text-align: justify;"><span class="label notice">Quatrième technique</span></h4>
<p style="text-align: justify;"><strong>La fonction de rappel est définie comme une fonction ne prenant aucun paramètre, elle est invoquée pour signaler que l&#8217;action désirée est effectuée</strong></p>
<p style="text-align: justify;">Pourquoi ne pas avoir parlé de cette technique auparavant: et bien tout simplement parce qu&#8217;il n&#8217;est généralement pas souhaitable de l&#8217;utiliser. En effet cette technique crée une ambiguïté: <strong>pourquoi notre fonction de rappel n&#8217;est pas appelée?</strong> la méthode a-t-elle oublié d’appeler la fonction de rappel, une erreur a modifié le fil d’exécution et le code n&#8217;appelle plus la fonction de rappel. <strong>En l&#8217;absence de retour, il n&#8217;est pas possible de réagir</strong>.</p>
<h2 style="text-align: justify;">&laquo;&nbsp;The amateur software engineer is always in search of magic.&nbsp;&raquo; <em>— Grady Booch</em></h2>
<p style="text-align: justify;">Continuons par une petite digression qui illustrera très simplement l’intérêt d&#8217;une approche par continuation plutôt que l&#8217;approche plus traditionnelle d&#8217;une méthode avec retour.</p>
<p style="text-align: justify;">La création d&#8217;un <tt>quiz</tt> est une chose relativement complexe (si! si!) et peut prendre beaucoup de temps. Dans le cas d&#8217;une approche traditionnelle, l&#8217;appelant de notre méthode est donc en attente d&#8217;un retour, et son traitement est suspendu. Grâce à notre approche par continuation, il devient très facile de modifier le comportement de notre service afin de rendre ses traitements asynchrones, l&#8217;appelant peut alors continuer à effectuer ses propres tâches pendant ce temps.</p>
<p style="text-align: justify;">Voyons comment rendre très simplement un service asynchrone avec <a href="http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/reflect/Proxy.html">Java Proxy</a>. La méthode que nous allons voir repose sur les API du jdk, la seule limitation est que cela nous oblige à définir une interface pour notre service.</p>
<pre class="brush: java; title: ; notranslate">
public interface QuizService {
  void create(final String quizContent, final Effect effect);
  void save(Quiz quiz, Effect&amp;lt;Option&amp;gt; effect);
}
</pre>
<p style="text-align: justify;">Notre service peux devenir asynchrone grâce à l&#8217;appel suivant:</p>
<pre class="brush: java; title: ; notranslate">
QuizService serviceImpl = new QuizServiceImpl();
QuizService asynService = Async.asyncProxy(QuizService.class,
                                           serviceImpl, executor);
</pre>
<p style="text-align: justify;">Avec comme code pour notre classe utilitaire <tt>Async</tt>:</p>
<pre class="brush: java; title: ; notranslate">
import java.lang.reflect.*;
import java.util.Arrays;
import java.util.concurrent.*;

public class Async {

  public static &lt;T&gt; T asyncProxy(Class type, T impl,
                                 ExecutorService executor) {
    return new Async(executor).asyncProxy(type, impl);
  }

  private final ExecutorService executor;
  public Async(ExecutorService executor) {
    this.executor = executor;
  }

  @SuppressWarnings(&quot;unchecked&quot;)
  public &lt;T&gt; T asyncProxy(Class&lt;T&gt; type, T impl) {
    return (T)Proxy.newProxyInstance(getClassLoader(),
                                     asArray(type),
                                     asyncHandler(impl));
  }

  private static &lt;T&gt; Class&lt;?&gt;[] asArray(Class&lt;T&gt; type) {
    return new Class[]{type};
  }

  protected ClassLoader getClassLoader () {
    return getClass().getClassLoader();
  }

  protected &lt;T&gt; InvocationHandler&lt;T&gt; asyncHandler(T impl) {
    return new AsyncHandler&lt;T&gt;(impl, executor);
  }

  private static class AsyncHandler&lt;T&gt; implements InvocationHandler {
    private final T impl;
    private final ExecutorService executor;

    public AsyncHandler(T impl, ExecutorService executor) {
      this.impl = impl;
      this.executor = executor;
    }

    @Override
    public Object invoke(Object proxy,
                         final Method method,
                         final Object[] args) throws Throwable {
      Future&lt;Object&gt; future = executor.submit(new Callable&lt;Object&gt;() {
        @Override
        public Object call() throws Exception {
          return method.invoke(impl, args);
        }
      });
      Class&lt;?&gt; returnType = method.getReturnType();
      if(returnType==null || returnType==Void.class)
        return null;
      else
        return future.get();
    }
  }
}
</pre>
<p style="text-align: justify;">Quelques explications: un proxy est créé et implémente l&#8217;interface de notre service passée en paramètre <tt>type</tt> (ligne 18). Tous les appels effectués sur le proxy sont redirigés sur le <tt>InvocationHandler</tt> qui lui a été associé (ligne 21), et c&#8217;est là que les choses deviennent intéressantes: lignes 49 à 60.</p>
<p style="text-align: justify;">L&#8217;appel de la méthode est transformé en un fragment executable (<tt>new Callable() {...}</tt>) qui est soumis à l&#8217;<tt>Executor</tt> correspondant. La méthode est alors invoquée de manière asynchrone (par rapport à l&#8217;appelant) sur l&#8217;instance de service qui a été transformé: <tt>impl</tt> (passée en paramètre ligne 18): l&#8217;appel effectif est déclaré ligne 52. Et là, soyons malin:</p>
<ul style="text-align: justify;">
<li>soit la méthode invoquée ne renvoie rien <tt>void</tt>, dans ce cas le code appelant n&#8217;attend aucune valeur en retour, et il n&#8217;est pas nécessaire de rendre cet appel bloquant. On sort donc de la méthode (ligne 57) même si notre <tt>Callable</tt> n&#8217;a pas encore été executé ou s&#8217;il est en cours d&#8217;execution.</li>
<li>soit la méthode invoquée renvoie quelque chose, dans ce cas le code appelant s&#8217;attend à un retour&#8230; il faut lui renvoyer quelque chose: le code appelant va donc être suspendu (<tt>future.get()</tt>) jusqu&#8217;à ce que le resultat soit disponible (ligne 59).</li>
</ul>
<p style="text-align: justify;">Bien entendu, nous nous arrangerons pour être toujours dans le premier cas si nous voulons que les appels soient toujours asynchrones.</p>
<p style="text-align: justify;">Exemple de code appelant:</p>
<pre class="brush: java; title: ; notranslate">
quizService.create(&quot;...&quot;, new Effect() {
  public void e(Quiz quiz) {
    displayFlashFeedback(quiz);
  }
});
// Quiz is being created...
// ... in the meanwhile let's display some waiting feedback
displayWaitingFeedback();
</pre>
<p style="text-align: justify;"><strong>Nous voyons que sans modifier le code appelant, notre méthode par continuation a permis de brancher une implémentation asynchrone de notre service.</strong></p>
<p style="text-align: justify;">(On peux alors regarder le gars du fond de la salle et lui faire un petit hochement de tête complice!)</p>
<h2 style="text-align: justify;">A voir aussi</h2>
<ul style="text-align: justify;">
<li><a href="http://www.arolla.fr/blog/2012/09/la-gestion-des-erreurs-avec-scala-util-try-12/">La gestion des erreurs avec scala.util.Try (1/2) &#8211; Nouhoum</a></li>
<li><a href="http://www.arolla.fr/blog/2012/10/la-gestion-des-erreurs-avec-scala-util-try-22/">La gestion des erreurs avec scala.util.Try (2/2) &#8211; Nouhoum</a></li>
<li><a href="http://blog.richdougherty.com/2012/06/error-handling-with-scalas-try.html">Error handling with Scala&#8217;s Try</a></li>
</ul>
<ul>
<li style="text-align: justify;"><tt>Either</tt>
<ul>
<li><a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Either.html">Either ~ Haskell</a></li>
<li><a href="http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/data/Either.html">Either ~ FunctionalJava</a></li>
<li><a href="http://www.scala-lang.org/api/current/scala/Either.html">Either ~ Scala</a></li>
<li><a href="http://msdn.microsoft.com/en-us/library/ee353439.aspx">Choice ~ F#</a></li>
</ul>
</li>
<li><tt>Option</tt>
<ul>
<li style="text-align: justify;">Maybe ~ Haskell</li>
<li style="text-align: justify;"><a href="http://functionaljava.googlecode.com/svn/artifacts/3.0/javadoc/fj/data/Option.html">Option ~ FunctionalJava</a></li>
<li style="text-align: justify;"><a href="http://www.scala-lang.org/api/current/scala/Option.html">Option ~ Scala</a></li>
<li style="text-align: justify;"><a href="http://msdn.microsoft.com/en-us/library/ee353806.aspx">Option ~ F#</a></li>
</ul>
</li>
</ul>
<div id="tweetbutton1381" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fbsm8xl3&amp;via=ArollaFr&amp;text=Il%20y%20a%20peut%20%C3%AAtre%20une%20option%20pour%20continuer%20%C2%A1%C2%BF%20%28r%C3%A9flexion%20sur%20la%20programmation%20par%20continuation%29&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2012%2F12%2Foption-maybe-continuation%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2012/12/option-maybe-continuation/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>RPSLS — Rock Paper Scissors Lizard Spock</title>
		<link>http://www.arolla.fr/blog/2012/11/rpsls-%e2%80%94-rock-paper-scissors-lizard-spock/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rpsls-%25e2%2580%2594-rock-paper-scissors-lizard-spock</link>
		<comments>http://www.arolla.fr/blog/2012/11/rpsls-%e2%80%94-rock-paper-scissors-lizard-spock/#comments</comments>
		<pubDate>Mon, 26 Nov 2012 09:16:12 +0000</pubDate>
		<dc:creator>Pierre Irrmann</dc:creator>
				<category><![CDATA[Programmation]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1373</guid>
		<description><![CDATA[Let’s start with a tweet from earlier today : Leonard Hofstadter @TheRealLeonardH Anyone bored and have an android phone? play.google.com/store/apps/det… 22 Nov 12 Répondre Retweeter Favori If you follow the link, you’ll get to a Google Play application that allows you to play the (in-)famous RPSLS (Rock-paper-scissors-lizard-Spock) game. Why that tweet stroke me is that [...]]]></description>
			<content:encoded><![CDATA[<div>
<p style="text-align: justify;">Let’s start with a tweet from earlier today :</p>
<div id="twitter-widget-0" lang="fr">
<div>
<blockquote data-twt-id="271551511631376384" data-twt-intents="false" data-twt-product="tweetembed">
<div><a href="https://twitter.com/TheRealLeonardH" data-screen-name="TheRealLeonardH"> <img src="https://si0.twimg.com/profile_images/2654852680/87ee5ed912ea7364a29a380be9b22285_normal.jpeg" alt="" /> Leonard Hofstadter @<strong>TheRealLeonardH</strong> </a></div>
<div>
<p>Anyone bored and have an android phone? <a title="https://play.google.com/store/apps/details?id=cc.spock.ui" href="https://t.co/iUYY4xYK">play.google.com/store/apps/det…</a></p>
</div>
<div><a href="https://twitter.com/TheRealLeonardH/statuses/271551511631376384"> 22 Nov 12 </a></p>
<ul>
<li><a title="Répondre" href="https://twitter.com/intent/tweet?in_reply_to=271551511631376384"><strong>Répondre</strong></a></li>
<li><a title="Retweeter" href="https://twitter.com/intent/retweet?tweet_id=271551511631376384"><strong>Retweeter</strong></a></li>
<li><a title="Favori" href="https://twitter.com/intent/favorite?tweet_id=271551511631376384"><strong>Favori</strong></a></li>
</ul>
</div>
</blockquote>
</div>
</div>
<p style="text-align: justify;"><img src="http://www.pirrmann.net/wp-content/uploads/2012/09/geek-gestures-rpsls.jpg" alt="" align="right" />If you follow the link, you’ll get to a Google Play application that allows you to play the (in-)famous <a href="http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock" target="_blank">RPSLS (Rock-paper-scissors-lizard-Spock)</a> game. Why that tweet stroke me is that I had already played (with code !) around that game a few months ago…</p>
<p style="text-align: justify;">Although this is just a variant of the classical rock-paper-scissors game, the two additional gestures shift the number of gesture combinations to 25, as shown on this matrix:</p>
<p style="text-align: justify;"><img src="http://www.pirrmann.net/wp-content/uploads/2012/11/Normal_form_matrix_of_Rock-paper-scissors-lizard-Spock.jpg" alt="" /></p>
<p style="text-align: justify;"><span style="font-size: xx-small;">(image taken from </span><a title="http://en.wikipedia.org/wiki/File:Normal_form_matrix_of_Rock-paper-scissors-lizard-Spock.jpg" href="http://en.wikipedia.org/wiki/File:Normal_form_matrix_of_Rock-paper-scissors-lizard-Spock.jpg"><span style="font-size: xx-small;">http://en.wikipedia.org/wiki/File:Normal_form_matrix_of_Rock-paper-scissors-lizard-Spock.jpg</span></a><span style="font-size: xx-small;">)</span></p>
<p style="text-align: justify;">There could be several ways to test these different combinations, for instance using the previous matrix as a reference, but… come on…. a closed set of values, and a simple behaviour… That’s just a perfect candidate for an enum ! And the best part is that I have actually implemented this as a test two months ago (<a href="https://github.com/pirrmann/PolymorphicEnum/commit/f5e0a18fa2df12f95cfa06f31efe44aa16a67a1e" target="_blank">proof on Github !</a>).</p>
<p style="text-align: justify;">Let’s first define the possible game outcomes :</p>
<div style="text-align: justify;">
<div id="highlighter_59520">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>public</code> <code>class</code> <code>GameOutcome : PolymorphicEnum&lt;GameOutcome&gt;</code></div>
<div><code>{</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GameOutcome WIN = Register();</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GameOutcome LOSE = Register();</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GameOutcome DRAW = Register();</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">Then we define the Gesture class and its values :</p>
<div style="text-align: justify;">
<div id="highlighter_10295">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>public</code> <code>class</code> <code>GeekGesture : PolymorphicEnum&lt;GeekGesture&gt;</code></div>
<div><code>{</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GeekGesture ROCK = Register();</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GeekGesture PAPER = Register();</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GeekGesture SCISSORS = Register();</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GeekGesture SPOCK = Register();</code></div>
<div><code>    </code><code>public</code> <code>static</code> <code>GeekGesture LIZARD = Register();</code></div>
<div><code>    </code><code>[...]</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">The trick here is that I changed the order of the values int the enum from Rock – paper – scissors – lizard – Spock to Rock – paper – scissors – Spock – lizard. This way, each values beats its predecessor and its second successor, and loses against its successor and second predecessor…</p>
<p style="text-align: justify;">The behaviour can then be simply implemented based on the integer values of the enums :</p>
<div style="text-align: justify;">
<div id="highlighter_22424">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>// we can use the int representation and a modulo trick !</code></div>
<div><code>public</code> <code>GameOutcome PlayAgainst(GeekGesture other)</code></div>
<div><code>{</code></div>
<div><code>    </code><code>return</code> <code>this</code> <code>== other</code></div>
<div><code>        </code><code>? GameOutcome.DRAW</code></div>
<div><code>        </code><code>: (GameOutcome)(((other + 5 - </code><code>this</code><code>) % 5) % 2);</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">Now we can write the tests in a very expressive way :</p>
<div style="text-align: justify;">
<div id="highlighter_266836">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>[TestMethod]</code></div>
<div><code>public</code> <code>void</code> <code>gesture_against_2nd_next_is_a_win()</code></div>
<div><code>{</code></div>
<div><code>    </code><code>Assert.AreEqual(GameOutcome.WIN,</code></div>
<div><code>        </code><code>GeekGesture.ROCK.PlayAgainst(GeekGesture.SCISSORS));</code></div>
<div><code>    </code><code>Assert.AreEqual(GameOutcome.WIN,</code></div>
<div><code>        </code><code>GeekGesture.PAPER.PlayAgainst(GeekGesture.SPOCK));</code></div>
<div><code>    </code><code>Assert.AreEqual(GameOutcome.WIN,</code></div>
<div><code>        </code><code>GeekGesture.SCISSORS.PlayAgainst(GeekGesture.LIZARD));</code></div>
<div><code>    </code><code>Assert.AreEqual(GameOutcome.WIN,</code></div>
<div><code>        </code><code>GeekGesture.SPOCK.PlayAgainst(GeekGesture.ROCK));</code></div>
<div><code>    </code><code>Assert.AreEqual(GameOutcome.WIN,</code></div>
<div><code>        </code><code>GeekGesture.LIZARD.PlayAgainst(GeekGesture.PAPER));</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">So… here is my answer to Leonard :</p>
<div id="twitter-widget-1" lang="fr">
<div>
<blockquote data-twt-id="271551511631376384" data-twt-intents="false" data-twt-product="tweetembed">
<div><a href="https://twitter.com/TheRealLeonardH" data-screen-name="TheRealLeonardH"> <img src="https://si0.twimg.com/profile_images/2654852680/87ee5ed912ea7364a29a380be9b22285_normal.jpeg" alt="" /> Leonard Hofstadter @<strong>TheRealLeonardH</strong> </a> <a href="https://twitter.com/TheRealLeonardH/statuses/271551511631376384" rel="bookmark"> 22 Nov 12 </a></div>
<div>
<p>Anyone bored and have an android phone? <a title="https://play.google.com/store/apps/details?id=cc.spock.ui" href="https://t.co/iUYY4xYK">play.google.com/store/apps/det…</a></p>
</div>
</blockquote>
<blockquote data-twt-id="271729506933415936" data-twt-intents="false" data-twt-product="tweetembed">
<div style="text-align: justify;"><a href="https://twitter.com/pirrmann" data-screen-name="pirrmann"> <img src="https://si0.twimg.com/profile_images/1756539560/protrait_normal.jpg" alt="" /> Pierre Irrmann @<strong>pirrmann</strong> </a></div>
<div style="text-align: justify;">
<p><a title="Leonard Hofstadter" href="https://twitter.com/TheRealLeonardH">@<strong>TheRealLeonardH</strong></a> I have and android phone, but when I’m bored I think about software, and sometimes blog about it : <a title="http://www.pirrmann.net/rpsls-rock-paper-scissors-lizard-spock/" href="http://t.co/EyihOhy1">pirrmann.net/rpsls-rock-pap…</a></p>
</div>
<div><a href="https://twitter.com/pirrmann/statuses/271729506933415936"> 22 Nov 12 </a></p>
<ul>
<li style="text-align: justify;"><a title="Répondre" href="https://twitter.com/intent/tweet?in_reply_to=271729506933415936"><strong>Répondre</strong></a></li>
<li style="text-align: justify;"><a title="Retweeter" href="https://twitter.com/intent/retweet?tweet_id=271729506933415936"><strong>Retweeter</strong></a></li>
<li style="text-align: justify;"><a title="Favori" href="https://twitter.com/intent/favorite?tweet_id=271729506933415936"><strong>Favori</strong></a></li>
</ul>
</div>
</blockquote>
</div>
</div>
</div>
<div id="tweetbutton1373" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fc2gwldt&amp;via=ArollaFr&amp;text=RPSLS%20%E2%80%94%20Rock%20Paper%20Scissors%20Lizard%20Spock&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2012%2F11%2Frpsls-%25e2%2580%2594-rock-paper-scissors-lizard-spock%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2012/11/rpsls-%e2%80%94-rock-paper-scissors-lizard-spock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Surface-area over volume ratio – a metaphor for software design</title>
		<link>http://www.arolla.fr/blog/2012/11/surface-area-over-volume-ratio-%e2%80%93-a-metaphor-for-software-design/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=surface-area-over-volume-ratio-%25e2%2580%2593-a-metaphor-for-software-design</link>
		<comments>http://www.arolla.fr/blog/2012/11/surface-area-over-volume-ratio-%e2%80%93-a-metaphor-for-software-design/#comments</comments>
		<pubDate>Mon, 19 Nov 2012 08:27:53 +0000</pubDate>
		<dc:creator>Cyrille</dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[area]]></category>
		<category><![CDATA[capability]]></category>
		<category><![CDATA[cheaper]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[duck typing]]></category>
		<category><![CDATA[economics]]></category>
		<category><![CDATA[facet]]></category>
		<category><![CDATA[interfaces]]></category>
		<category><![CDATA[metaphor]]></category>
		<category><![CDATA[multi-dimension]]></category>
		<category><![CDATA[physics of software]]></category>
		<category><![CDATA[protocols]]></category>
		<category><![CDATA[quality]]></category>
		<category><![CDATA[surface]]></category>
		<category><![CDATA[volume]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1367</guid>
		<description><![CDATA[There’s a metaphor I had in mind for a long time when thinking about software design: because I’m proudly lazy, in order to make the code smaller and easier to learn, I must do my best to reduce the « surface-area over volume ratio » of the software. Surface-area over volume ratio? I like the Surface-area over volume [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">There’s a metaphor I had in mind for a long time when thinking about software design: because I’m proudly lazy, in order to make the code smaller and easier to learn, I must do my best to reduce the « surface-area over volume ratio » of the software.</p>
<h1 style="text-align: justify;">Surface-area over volume ratio?</h1>
<p style="text-align: justify;">I like the <a href="http://en.wikipedia.org/wiki/Surface-area-to-volume_ratio" target="_blank">Surface-area over volume ratio</a> as a metaphor to express how to make software cheaper to discover and learn, and smaller to maintain as well.</p>
<p style="text-align: justify;">For a given object, the surface-area over volume ratio is the amount of surface area per unit volume. For buildings and for animals, the smaller this ratio, the less the heat loss during the winter, hence a better thermal efficiency.</p>
<p style="text-align: justify;">Have you ever noticed that huge warehouses were always cool even during the summer when it’s hot? This is just because in our real 3D world the surface-area over volume ratio is much smaller when the absolute size of the building increases.</p>
<p style="text-align: justify;">The theory also mentions that the sphere is the optimal shape with respect to this ratio. In fact, the more « compact » the less the ratio, or the other way round we could define compactness of an object directly by its surface-area-over-volume ratio.</p>
<div id="attachment_3490" style="text-align: justify;"><a href="http://cyrille.martraire.com/wp-content/uploads/2012/08/Dodecahedron1.png"><img title="Dodecahedron" src="http://cyrille.martraire.com/wp-content/uploads/2012/08/Dodecahedron1.png" alt="" width="300" height="300" /></a>A dodecahedron, a volume that approximates a sphere with just 2D facets (Wikipedia picture)</p>
</div>
<h1 style="text-align: justify;">What about software design?</h1>
<p style="text-align: justify;">Let’s consider that each <strong>method signature of each interface</strong> is part of the <strong>surface-area</strong> of the software, because this is what I have to learn primarily when I join the project. The larger the surface-area, the more time I’ll need to learn, provided I can even remember all of it.</p>
<blockquote><p>Larger surface is not good for the developers.</p></blockquote>
<p style="text-align: justify;">On the  other hand, the <strong>implementation</strong> is part of what I would call the <strong>volume</strong> of the software, i.e. this is where the code is really doing its stuff. The more volume, the more powerful and richer the software. And of course the point of Object Orientation is that you don’t have to learn all the implementation in order to work on the project, as opposed to the interfaces and their method signatures.</p>
<blockquote><p>Larger volume is good for the users (or the value brought by the software in general)</p></blockquote>
<p style="text-align: justify;">As a consequence we should <strong>try to minimize the surface-area over volume ratio</strong>, just like we’re trying to reduce it when designing a green building.</p>
<p style="text-align: justify;">Can we extrapolate that we should design software to be more « compact » and more « sphere »-like?</p>
<h1 style="text-align: justify;">Facets-like interfaces</h1>
<p style="text-align: justify;">Reusing the same interface as much as possible is obviously a way to reduce the surface-area of the software. Adhering to interfaces from the JDK or Google Guava, interfaces that are already well-known, helps even better: in our metaphor, an interface that we don’t have to learn comes for free, like a perfectly isolated wall in a building. We can almost omit it in our ratio.</p>
<p style="text-align: justify;">To further reduce the ratio, we can find out every opportunity to use as much as possible the minimum set of common interfaces, even over unrelated concepts. At the extreme of this approach we get <a href="http://en.wikipedia.org/wiki/Duck_typing" target="_blank">duck typing</a> in dynamic languages. In our usual languages like Java or C# we must introduce additional small interfaces, usually with one single method.</p>
<p style="text-align: justify;">For example in a trading system, every class with a <em>isInCurrency(Currency)</em> method can implement a common interface <em>CurrencySpecific</em>. As a result, a lot of processing (filtering etc.) on <em>stuff that is related to currencies in some</em> way can be done on all these classes without any knowledge about them, except their currency-specificity.</p>
<p style="text-align: justify;">In this example, the currency-specificity we extracted into one interface is like a single facet over a larger volume made of several implementation. It makes our design more compact, it will be easier to learn, while offering a rich set of behaviors.</p>
<p style="text-align: justify;">The limit for this approach of putting a lot of implementation code under the same interface is that sometimes it really makes no domain sense. Since code is primarily meant to describe the domain, without causing confusion we must be careful not to go too far. We must also take great care when sharing interfaces between bounded contexts, there’s a high risk of excessive coupling.</p>
<div id="attachment_3489" style="text-align: justify;"><a href="http://cyrille.martraire.com/wp-content/uploads/2012/08/faceted-artwork.jpeg"><img title="faceted-artwork" src="http://cyrille.martraire.com/wp-content/uploads/2012/08/faceted-artwork-300x224.jpg" alt="" width="300" height="224" /></a>Faceted artwork (picture from http://reinierdejong.wordpress.com)</p>
</div>
<h1 style="text-align: justify;">Yet another metric?</h1>
<p style="text-align: justify;">This metric could be measured by a tool, however the primary value is not in checking the figures, but in the thinking and taking care of making the design easy to learn (less surface-area), while delivering a lot of valuable behaviors (more volume).</p>
<div id="tweetbutton1367" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fd3nfu2n&amp;via=ArollaFr&amp;text=Surface-area%20over%20volume%20ratio%20%E2%80%93%20a%20metaphor%20for%20software%20design&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2012%2F11%2Fsurface-area-over-volume-ratio-%25e2%2580%2593-a-metaphor-for-software-design%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2012/11/surface-area-over-volume-ratio-%e2%80%93-a-metaphor-for-software-design/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cartesian products in LINQ (fluent syntax)</title>
		<link>http://www.arolla.fr/blog/2012/11/cartesian-products-in-linq-fluent-syntax/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=cartesian-products-in-linq-fluent-syntax</link>
		<comments>http://www.arolla.fr/blog/2012/11/cartesian-products-in-linq-fluent-syntax/#comments</comments>
		<pubDate>Thu, 15 Nov 2012 09:28:33 +0000</pubDate>
		<dc:creator>Pierre Irrmann</dc:creator>
				<category><![CDATA[Programmation]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Extension Methods]]></category>
		<category><![CDATA[LINQ]]></category>

		<guid isPermaLink="false">http://www.arolla.fr/blog/?p=1361</guid>
		<description><![CDATA[Have you ever tried to combine sequences in order to build Cartesian products in LINQ ? This is really easily achieved using the query expressions syntax, writing for instance : var ints = Enumerable.Range(1, 4); var longs = Enumerable.Range(1, 3).Select(i =&#62; (long)i); var products = from i in ints     from l in longs     select i [...]]]></description>
			<content:encoded><![CDATA[<div>
<p style="text-align: justify;">Have you ever tried to combine sequences in order to build Cartesian products in LINQ ? This is really easily achieved using the query expressions syntax, writing for instance :</p>
<div style="text-align: justify;">
<div id="highlighter_74075">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>var ints = Enumerable.Range(1, 4);</code></div>
<div><code>var longs = Enumerable.Range(1, 3).Select(i =&gt; (</code><code>long</code><code>)i);</code></div>
<div><code>var products = from i </code><code>in</code> <code>ints</code></div>
<div><code>    </code><code>from l </code><code>in</code> <code>longs</code></div>
<div><code>    </code><code>select i * l;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">When I write LINQ queries, I tend to use as often as possible the fluent syntax, as it is more powerful, and allows me to use a wider range of operators. I also try not to mix both syntaxes, because I find it quite confusing. When I want to perform, inside of a more complex query, a simple cross-product as the previous one, the “fluent” equivalent syntax is the following :</p>
<div style="text-align: justify;">
<div id="highlighter_114217">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>var products = ints.SelectMany(i =&gt; longs.Select(l =&gt; i * l));</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">In fact, this syntax works very well, but I don’t find it as expressive as the first one. And if you go one step further and add a third sequence to the party…</p>
<div style="text-align: justify;">
<div id="highlighter_354894">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>var ints = Enumerable.Range(1, 4);</code></div>
<div><code>var longs = Enumerable.Range(1, 3).Select(i =&gt; (</code><code>long</code><code>)i);</code></div>
<div><code>var strings = </code><code>new</code><code>[] { </code><code>"a"</code><code>, </code><code>"b"</code><code>, </code><code>"c"</code> <code>};</code></div>
<div><code>var classic = from i </code><code>in</code> <code>ints</code></div>
<div><code>    </code><code>from l </code><code>in</code> <code>longs</code></div>
<div><code>    </code><code>from s </code><code>in</code> <code>strings</code></div>
<div><code>    </code><code>select (i * l).ToString() + s;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">The “fluent” syntax gets even more confusing (at least to me) :</p>
<div style="text-align: justify;">
<div id="highlighter_312136">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>var fluent = ints.SelectMany(</code></div>
<div><code>    </code><code>i =&gt; longs.SelectMany(</code></div>
<div><code>    </code><code>l =&gt; strings.Select(s =&gt; (i * l).ToString() + s)));</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">I think that what bothers me might be the ever-increasing number of unclosed parenthesis… Anyway, as usual, I played with extensions methods and here is what I came up with, using a new “Cross” method, for the 2 sequences cross-product :</p>
<div style="text-align: justify;">
<div id="highlighter_789957">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>var results = ints</code></div>
<div><code>    </code><code>.Cross(longs)</code></div>
<div><code>    </code><code>.Select((i, l) =&gt; i * l);</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">And the same syntax for the 3 sequences cross product :</p>
<div style="text-align: justify;">
<div id="highlighter_327480">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>var results = ints</code></div>
<div><code>    </code><code>.Cross(longs)</code></div>
<div><code>    </code><code>.Cross(strings)</code></div>
<div><code>    </code><code>.Select((i, l, s) =&gt; (i * l).ToString() + s);</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p style="text-align: justify;">Don’t you find it more expressive ?</p>
<p style="text-align: justify;">Finally, here are the extensions methods implementations :</p>
<div style="text-align: justify;">
<div>
<div id="highlighter_13274">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<div><code>public</code> <code>static</code> <code>IEnumerable&lt;Tuple&lt;TLeft, TRight&gt;&gt; Cross&lt;TLeft, TRight&gt;(</code></div>
<div><code>    </code><code>this</code> <code>IEnumerable&lt;TLeft&gt; left, IEnumerable&lt;TRight&gt; right)</code></div>
<div><code>{</code></div>
<div><code>    </code><code>return</code> <code>left.SelectMany(l =&gt; right.Select(r =&gt; Tuple.Create(l, r)));</code></div>
<div><code>}</code></div>
<div><code>public</code> <code>static</code> <code>IEnumerable&lt;Tuple&lt;TLeft1, TLeft2, TRight&gt;&gt; Cross&lt;TLeft1, TLeft2, TRight&gt;(</code></div>
<div><code>    </code><code>this</code> <code>IEnumerable&lt;Tuple&lt;TLeft1, TLeft2&gt;&gt; left, IEnumerable&lt;TRight&gt; right)</code></div>
<div><code>{</code></div>
<div><code>    </code><code>return</code> <code>left.SelectMany(l =&gt; right.Select(r =&gt; Tuple.Create(l.Item1, l.Item2, r)));</code></div>
<div><code>}</code></div>
<div><code>public</code> <code>static</code> <code>IEnumerable&lt;TResult&gt; Select&lt;T1, T2, TResult&gt;(</code></div>
<div><code>    </code><code>this</code> <code>IEnumerable&lt;Tuple&lt;T1, T2&gt;&gt; source, Func&lt;T1, T2, TResult&gt; selector)</code></div>
<div><code>{</code></div>
<div><code>    </code><code>return</code> <code>source.Select(t =&gt; selector(t.Item1, t.Item2));</code></div>
<div><code>}</code></div>
<div><code>public</code> <code>static</code> <code>IEnumerable&lt;TResult&gt; Select&lt;T1, T2, T3, TResult&gt;(</code></div>
<div><code>    </code><code>this</code> <code>IEnumerable&lt;Tuple&lt;T1, T2, T3&gt;&gt; source, Func&lt;T1, T2, T3, TResult&gt; selector)</code></div>
<div><code>{</code></div>
<div><code>    </code><code>return</code> <code>source.Select(t =&gt; selector(t.Item1, t.Item2, t.Item3));</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p style="text-align: justify;">I must admit that those generic methods signatures are horrible, though…</p>
</div>
<div id="tweetbutton1361" class="tw_button" style=""><a href="http://twitter.com/share?url=http%3A%2F%2Ftinyurl.com%2Fc9zy2t6&amp;via=ArollaFr&amp;text=Cartesian%20products%20in%20LINQ%20%28fluent%20syntax%29&amp;related=&amp;lang=fr&amp;count=horizontal&amp;counturl=http%3A%2F%2Fwww.arolla.fr%2Fblog%2F2012%2F11%2Fcartesian-products-in-linq-fluent-syntax%2F" class="twitter-share-button"  style="width:55px;height:22px;background:transparent url('http://www.arolla.fr/blog/wp-content/plugins/wp-tweet-button/tweetn.png') no-repeat  0 0;text-align:left;text-indent:-9999px;display:block;">Tweeter</a></div>]]></content:encoded>
			<wfw:commentRss>http://www.arolla.fr/blog/2012/11/cartesian-products-in-linq-fluent-syntax/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
