tag:linuxfr.org,2005:/tags/donald_knuth/publicLinuxFr.org : les contenus étiquetés avec « donald_knuth »2021-01-05T13:06:03+01:00/favicon.pngtag:linuxfr.org,2005:Diary/395322020-12-31T18:33:14+01:002021-01-01T11:47:26+01:00Pour finir ou commencer l'année : une interview de Donald KnuthLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>On n'interviewe pas facilement Donald Knuth. Non qu'il soit revêche, c'est un bonhomme très drôle. Mais il n'a plus de courriel, il faut écrire une lettre. Tous les samedis, la secrétaire de Donald entre dans la boite aux lettres et s'installe pour trier le courrier (l'université a fait construire une boite aux lettres géante, cubique, en porphyre noir, dont les côtés font 2,718 mètres, et d'ailleurs en hommage à Knuth la poste américaine livre le courrier en gants blancs et carrosse à cheval — DK collectionne les carrosses).</p>
<p>Dans <a href="https://news.ycombinator.com/item?id=25589619">le fil d'Hacker News</a> certains des amis de Knuth y vont de leur petite anecdote, réveillée par les questions nouvelles qu'a posé Philip Kiely — vous connaissez Kiely ? non ? il a écrit un bon livre sur <a href="https://philipkiely.com/wfsd/">l'art d'écrire pour être lu par les développeurs</a>. C'est pour la nouvelle version de son livre, prévue pour 2022, mais il a l'astuce (il est fort en marketing) de <a href="https://philipkiely.com/assets/files/WfSD_Bonus_Interview_-_Donald_Knuth.pdf">mettre à disposition cette interview de ce héraut de l'informatique</a>. </p>
<p>Tout ça est très intéressant, vraiment. <br>
Je vous laisse j'ai du homard sur le feu.</p>
<div><a href="https://linuxfr.org/users/orfenor/journaux/pour-finir-ou-commencer-l-annee-une-interview-de-donald-knuth.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/122779/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/orfenor/journaux/pour-finir-ou-commencer-l-annee-une-interview-de-donald-knuth#comments">ouvrir dans le navigateur</a>
</p>
orfenorhttps://linuxfr.org/nodes/122779/comments.atomtag:linuxfr.org,2005:Diary/393352020-09-12T13:38:04+02:002020-09-12T13:38:04+02:00Kaputt – une bibliothèque pour tester ses programmes Common LispLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>Kaputt est une bibliothèque pour écrire les tests de programmes Common Lisp. Ses principales caractéristiques sont les suivantes:</p>
<ul>
<li><p>Kaputt est simple, et ne définit que trois abstractions: les <em>assertions</em> les <em>testcases</em> et les <em>protocols,</em> en outre il n'ajoute aucun artefact dans les <em>backtraces</em>.</p></li>
<li><p>Kaputt est extensible, il est facile de définir des assertions spécifiques au problème résolu par le programme ce qui mène à des expressifs et informatifs.</p></li>
<li><p>Kaputt est taillé pour le développement interactif (Lisp oblige).</p></li>
</ul>
<p>WWW: <a href="https://github.com/michipili/cl-kaputt">https://github.com/michipili/cl-kaputt</a></p>
<p>Les bibliothèques disponibles que j'ai pu tester (5AM, stefil, fiasco) ne satisfaisaient pas aux points suivants, c'est ce qui m'a poussé à écrire Kaputt.</p>
<p>(Petit point sympa, Kaputt définit les opérateurs de Knuth pour la comparaison des nombres en virgule flottante.)</p>
<p>Je suis ouvert à toutes vos suggestions, recommandations et questions, concernant ce code, son emploi et les fonctionnalités qui vous semblerait manquer.</p>
<p>J'aimerais bien produire une documentation en ligne, par exemple des fichier HTML ou des fichiers Markdown que je pourrais intégrer à mkdocs par exemple, ici encore toutes vos suggestions sont bienvenues!</p>
<p>Happy consing! ;-)</p>
<div><a href="https://linuxfr.org/users/chat_de_sorciere/journaux/kaputt-une-bibliotheque-pour-tester-ses-programmes-common-lisp.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/121584/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/chat_de_sorciere/journaux/kaputt-une-bibliotheque-pour-tester-ses-programmes-common-lisp#comments">ouvrir dans le navigateur</a>
</p>
Michaëlhttps://linuxfr.org/nodes/121584/comments.atomtag:linuxfr.org,2005:Diary/389412020-02-11T23:03:31+01:002020-02-11T23:03:31+01:00Exercices de programmation et benchmarksLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#toc-pour-%C3%AAtre-en-bonne-sant%C3%A9-exercez-vous-r%C3%A9guli%C3%A8rement">Pour être en bonne santé, exercez-vous régulièrement</a></li>
<li><a href="#toc-pr%C3%A9sentation-de-lexercice">Présentation de l'exercice</a></li>
<li><a href="#toc-impl%C3%A9mentation-initiale">Implémentation initiale</a></li>
<li><a href="#toc-le-jugement">Le jugement</a></li>
<li><a href="#toc-des-benchmarks-et-trop-did%C3%A9es">Des benchmarks et trop d'idées</a></li>
<li><a href="#toc-la-p%C3%A9riode-sombre">La période sombre</a></li>
<li><a href="#toc-changement-doutils">Changement d'outils</a></li>
<li><a href="#toc-quand-et-quoi-optimiser">Quand et quoi optimiser</a></li>
</ul>
<p>Bonjour 'nal,</p>
<p>Un petit exercice d'algorithmique m'a récemment poussé à regarder en détail l'impact de différentes approches sur les performances et à remettre en question des connaissances que je croyais solides. Laisse-moi te raconter ce voyage.</p>
<h2 id="toc-pour-être-en-bonne-santé-exercez-vous-régulièrement">Pour être en bonne santé, exercez-vous régulièrement</h2>
<p>J'aime bien pratiquer des exercices de programmation sur des sites tels que CodinGame ou CodeSignal. Si tu ne connais pas, ces sites proposent un petit IDE en ligne et divers problèmes d'algorithmiques avec jeux de tests associés. Le jeu consiste à fournir dans l'éditeur en ligne un programme pour résoudre le problème donné ; l'implémentation se faisant dans le langage de ton choix. La plate-forme permet de lancer la solution sur les jeux de tests pour la valider.</p>
<p>Selon son profil on utilisera le service dans l'optique d'écrire le programme le plus court, ou le plus efficace, ou simplement un programme qui fonctionne. Pour moi c'est un peu un coding dojo : un lieu ou pratiquer et où se comparer aux autres pour apprendre et s'améliorer.</p>
<p>En particulier, lors d'une séance sur CodeSignal je me suis laissé allé à me comparer à la meilleure solution d'après les votants : pour chaque exercice j'implémente une solution d'une manière assez immédiate, un peu comme ça me vient, puis quand la solution est validée je regarde celles des autres. J'essaye de trouver leurs points forts, les miens, et je nous critique. Comme je fais les exercices en C++ je ne me compare qu'à la meilleure solution dans ce langage.</p>
<h2 id="toc-présentation-de-lexercice">Présentation de l'exercice</h2>
<p>Étant donné une matrice d'entiers, l'exercice consiste à calculer la somme des nombres qui ne sont pas sous un zéro. Par exemple, pour</p>
<pre><code>0, 2, 3
1, 0, 4
5, 6, 7
</code></pre>
<p>Le résultat attendu est 2 + 3 + 4 + 7 = 16. Le 1, le 5 et le 6 ne sont pas comptés car il y a un zéro plus haut dans la colonne.</p>
<p>La matrice est représentée en <em>row-major</em>, c’est-à-dire par une table de tables où chaque sous table représente une ligne de la matrice. J'ai déjà rencontré des traitements de grandes matrices par le passé et ma première réflexion est « si je traite le problème par colonne comme le suggère l'énoncé je vais sauter d'une zone mémoire à une autre et avoir des perfs nases. Il vaut mieux traiter ce genre de matrice ligne par ligne. »</p>
<p>Je vais donc scanner les lignes pour additionner les valeurs. Un booléen associé à chaque colonne me dira si j'ai déjà rencontré un zéro dans cette colonne, auquel cas j'ignore la valeur.</p>
<p>En pratique je vais donc visiter des cases pour lesquelles je sais que les valeurs seront ignorées, que je n'aurais pas visitées en scannant par colonne, mais pour l'instant je pense que c'est pour le mieux.</p>
<p>De plus, peu avant de faire l'exercice j'avais visionné les présentations <a href="https://www.infoq.com/presentations/simdjson-parser/"><em>Parsing JSON Really Quickly: Lessons Learned</em></a> (Daniel Lemire), <a href="https://www.youtube.com/watch?v=FJJTYQYB1JQ"><em>Speed Is Found In The Minds of People</em></a> (Andrei Alexandrescu) et <a href="https://www.youtube.com/watch?v=HG6c4Kwbv4I"><em>Path Tracing Three Ways: A Study of C++ Style</em></a> (Matt Godbolt) dans lesquelles les auteurs avaient amélioré les performances de manière remarquable en implémentant leurs algorithmes de manière <em>branchless</em>, c’est-à-dire sans conditions <em>if</em> qui amènent le prédicteur du processeur à faire des suppositions. Sans entrer dans les détails, il faut savoir qu'une prédiction a un coût d'annulation parfois plus grand que ce qui a été gagné par les prédictions justes. Un code sans conditions évite ce problème et se comporte de manière stable, mais il faut réussir à intégrer quelque chose correspondant à la condition dans les calculs.</p>
<h2 id="toc-implémentation-initiale">Implémentation initiale</h2>
<p>Assez de bla bla, allons dans le code. L'implémentation initiale (que tu peux retrouver dans <a href="https://github.com/j-jorge/codesignal">ce dépôt sur GitHub</a>) ressemble à cela :</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_branchless</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">row_size</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">char</span><span class="o">></span> <span class="n">usable_column</span><span class="p">(</span><span class="n">row_size</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">result</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>&</span> <span class="nl">row</span> <span class="p">:</span> <span class="n">matrix</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">row_size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">v</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="n">result</span> <span class="o">+=</span> <span class="n">v</span> <span class="o">*</span> <span class="n">usable_column</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="n">usable_column</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">*=</span> <span class="p">(</span><span class="n">v</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Il n'y a pas beaucoup de lignes mais déjà beaucoup de questions, à commencer par « est-ce que c'est vraiment mieux qu'un scan de colonnes ? ». Regardons donc la solution la mieux notée sur CodeSignal.</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_best_ratings</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">m</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">r</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o"><</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">m</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">();</span> <span class="n">j</span><span class="o">++</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span><span class="n">m</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">m</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span><span class="o">==</span><span class="mi">0</span><span class="p">)</span>
<span class="k">break</span><span class="p">;</span>
<span class="n">r</span> <span class="o">+=</span> <span class="n">m</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">r</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Bien, ça m'a l'air d'être un scan de colonnes justement ! Comparons les performances des deux implémentations à l'aide de Google Benchmark.</p>
<h2 id="toc-le-jugement">Le jugement</h2>
<p>Pour les tests j'utilise une matrice de valeurs aléatoires, chaque cellule ayant une chance d'autant plus grande d'être zéro qu'elle est proche du bas de la matrice. Bien que l'énoncé indiquait une taille maximum de 10×10 pour la matrice, je teste aussi pour des tailles supérieures : 100×100, 1000×1000 et 10000×10000.</p>
<pre><code>Run on (4 X 3100 MHz CPU s)
CPU Caches:
L1 Data 32 KiB (x2)
L1 Instruction 32 KiB (x2)
L2 Unified 256 KiB (x2)
L3 Unified 3072 KiB (x1)
-------------------------------------------------------------
Benchmark Time CPU Iterations
-------------------------------------------------------------
branchless/10 147 ns 147 ns 4624304
branchless/100 13613 ns 13612 ns 50630
branchless/1000 1363899 ns 1363210 ns 516
branchless/10000 134339389 ns 134330069 ns 5
best_ratings/10 40.5 ns 40.5 ns 17268039
best_ratings/100 1422 ns 1422 ns 485581
best_ratings/1000 49662 ns 49662 ns 14096
best_ratings/10000 3599890 ns 3599673 ns 204
</code></pre>
<p>Wow, la version la mieux notée est bien meilleure de la mienne ! Voyons si je peux améliorer ça. Déjà je me demande si l'implémentation <em>branchless</em> est vraiment mieux qu'une version avec branches. Comparons avec cette implémentation :</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_branches</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">row_size</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">char</span><span class="o">></span> <span class="n">usable_column</span><span class="p">(</span><span class="n">row_size</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">result</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>&</span> <span class="nl">row</span> <span class="p">:</span> <span class="n">matrix</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">row_size</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">usable_column</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">v</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">v</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">usable_column</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">else</span>
<span class="n">result</span> <span class="o">+=</span> <span class="n">v</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Nouveaux résultats :</p>
<pre><code>-------------------------------------------------------------
Benchmark Time CPU Iterations
-------------------------------------------------------------
branchless/10 161 ns 161 ns 4315630
branchless/100 13757 ns 13757 ns 46364
branchless/1000 1352468 ns 1352375 ns 517
branchless/10000 134475422 ns 134475261 ns 5
branches/10 116 ns 116 ns 5764899
branches/100 7689 ns 7689 ns 84635
branches/1000 781502 ns 781443 ns 861
branches/10000 70365787 ns 70364814 ns 8
best_ratings/10 42.0 ns 42.0 ns 16691501
best_ratings/100 1091 ns 1091 ns 628554
best_ratings/1000 41888 ns 41886 ns 16697
best_ratings/10000 3454331 ns 3454125 ns 203
</code></pre>
<p>Mmmmh okay, donc la version <em>branchless</em> se comporte moins bien que la version avec branches. Décidémment c'est mal parti.</p>
<h2 id="toc-des-benchmarks-et-trop-didées">Des benchmarks et trop d'idées</h2>
<p>Tiens, j'ai envie de tester avec un <code>std::vector<bool></code> pour <code>usable_column</code>. Je doute que ça apporte un réel gain mais je me demande quel impact aurait l'implémentation <em>bitset</em> par rapport à la précédente. Ça commence à faire beaucoup de lignes dans l'output alors passons en mode graphique et profitons-en pour ajouter des tailles de matrices.</p>
<p>Apparemment mon ordinateur a un cache L1 de 32 ko, deux caches L2 de 256 ko et un cache L3 de 3072 ko. Cela signifie que sur des entiers de 32 bits les matrices en dessous de 64×64 tiennent dans un cache L1, puis dans L2 jusqu'à 128×128, puis L3 jusqu'à 512×512. Au delà il faudra aller chercher les données en RAM.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30312e706e67/clean-results-01.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-01.png"></p>
<p>Bien, bien, bien… Les implémentations qui utilisent un <code>std::vector<bool></code> sont moins efficaces que les originales, et dans tous les cas c'est pire que la version en colonnes.</p>
<p>Et si je stockais les indices de la première et la dernière colonne encore pertinentes ? Ainsi le nombre de colonnes scannées devrait réduire au fur et à mesure que l'on descend dans la matrice. Ça donne quelque chose comme ça :</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_branches_range</span>
<span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">row_size</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">char</span><span class="o">></span> <span class="n">usable_column</span><span class="p">(</span><span class="n">row_size</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">first</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">last</span><span class="p">(</span><span class="n">row_size</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">result</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>&</span> <span class="nl">row</span> <span class="p">:</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">for</span> <span class="p">(;</span> <span class="p">(</span><span class="n">first</span> <span class="o">!=</span> <span class="n">last</span><span class="p">)</span>
<span class="o">&&</span> <span class="p">((</span><span class="n">usable_column</span><span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="o">||</span> <span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">first</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">));</span>
<span class="o">++</span><span class="n">first</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">last_non_zero</span><span class="p">(</span><span class="n">first</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="p">(</span><span class="n">first</span><span class="p">);</span> <span class="n">i</span> <span class="o">!=</span> <span class="n">last</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">usable_column</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">v</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">v</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="n">usable_column</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">result</span> <span class="o">+=</span> <span class="n">v</span><span class="p">;</span>
<span class="n">last_non_zero</span> <span class="o">=</span> <span class="n">i</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="n">last</span> <span class="o">=</span> <span class="n">last_non_zero</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Et le benchmark :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30322e706e67/clean-results-02.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-02.png"></p>
<p>Ha-HA ! Ça coupe enfin la ligne de l'algo naïf. Est-ce qu'il y a moyen de faire mieux ? Déjà l'approche est un peu limite car l'intervalle des colonnes ne réduit efficacement que si les extrêmes contiennent des zéros assez haut. Je vais tenter de n'itérer que sur les colonnes dont je sais qu'elles sont encore pertinentes de façon à ce que l'ordre n'ait plus d'importance. <code>usable_columns</code> devient un vecteur d'indices de colonnes à traiter duquel je supprime les indices à chaque fois que je rencontre un zéro.</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_indices</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">row_size</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">></span> <span class="n">usable_columns</span><span class="p">(</span><span class="n">row_size</span><span class="p">);</span>
<span class="k">const</span> <span class="k">auto</span> <span class="n">usable_columns_begin</span><span class="p">(</span><span class="n">usable_columns</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span>
<span class="k">auto</span> <span class="n">usable_columns_end</span><span class="p">(</span><span class="n">usable_columns</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">iota</span><span class="p">(</span><span class="n">usable_columns_begin</span><span class="p">,</span> <span class="n">usable_columns_end</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">result</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>&</span> <span class="nl">row</span> <span class="p">:</span> <span class="n">matrix</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">it</span><span class="p">(</span><span class="n">usable_columns_begin</span><span class="p">);</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">usable_columns_end</span><span class="p">;)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">i</span><span class="p">(</span><span class="o">*</span><span class="n">it</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">v</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">v</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="o">--</span><span class="n">usable_columns_end</span><span class="p">;</span>
<span class="o">*</span><span class="n">it</span> <span class="o">=</span> <span class="o">*</span><span class="n">usable_columns_end</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">result</span> <span class="o">+=</span> <span class="n">v</span><span class="p">;</span>
<span class="o">++</span><span class="n">it</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Alors qu'est-ce que ça donne…</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30332e706e67/clean-results-03.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-03.png"></p>
<p>Wouhou ! Ça devient concret, dès 1024×1024 l'algorithme ci-dessus devient plus rapide que l'algo naïf. Quoi d'autre pour l'améliorer ?</p>
<h2 id="toc-la-période-sombre">La période sombre</h2>
<p>Je n'aime pas trop la méthode utilisée pour retirer les indices de <code>usable_columns</code> : l'indice à supprimer est échangé avec le dernier de la liste puis on décrémente le pointeur de fin pour l'ignorer. Je m'attends à ce qu'après quelques itérations les indices soient complètement désordonnés et donc les accès mémoire complètement aléatoires. Est-ce que les performances seraient meilleures en passant un peu de temps à maintenir la liste triée ? Un seul moyen de le savoir :</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_indices_sort</span>
<span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">row_size</span><span class="p">(</span><span class="n">matrix</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">></span> <span class="n">usable_columns</span><span class="p">(</span><span class="n">row_size</span><span class="p">);</span>
<span class="k">const</span> <span class="k">auto</span> <span class="n">usable_columns_begin</span><span class="p">(</span><span class="n">usable_columns</span><span class="p">.</span><span class="n">begin</span><span class="p">());</span>
<span class="k">auto</span> <span class="n">usable_columns_end</span><span class="p">(</span><span class="n">usable_columns</span><span class="p">.</span><span class="n">end</span><span class="p">());</span>
<span class="n">std</span><span class="o">::</span><span class="n">iota</span><span class="p">(</span><span class="n">usable_columns_begin</span><span class="p">,</span> <span class="n">usable_columns_end</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">result</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>&</span> <span class="nl">row</span> <span class="p">:</span> <span class="n">matrix</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">it</span><span class="p">(</span><span class="n">usable_columns_begin</span><span class="p">);</span> <span class="n">it</span> <span class="o">!=</span> <span class="n">usable_columns_end</span><span class="p">;)</span>
<span class="p">{</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">i</span><span class="p">(</span><span class="o">*</span><span class="n">it</span><span class="p">);</span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">v</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">v</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="p">{</span>
<span class="o">--</span><span class="n">usable_columns_end</span><span class="p">;</span>
<span class="o">*</span><span class="n">it</span> <span class="o">=</span> <span class="o">*</span><span class="n">usable_columns_end</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">else</span>
<span class="p">{</span>
<span class="n">result</span> <span class="o">+=</span> <span class="n">v</span><span class="p">;</span>
<span class="o">++</span><span class="n">it</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// Cette ligne en plus.</span>
<span class="n">std</span><span class="o">::</span><span class="n">sort</span><span class="p">(</span><span class="n">usable_columns_begin</span><span class="p">,</span> <span class="n">usable_columns_end</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">result</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30342e706e67/clean-results-04.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-04.png"></p>
<p>Non. Réponse égale non. Retrier les indices à chaque itération ne compense pas l'hypothétique perte de performances d'accès aléatoires en mémoire. Tentons la suppression de l'indice avec <code>std::vector<>::erase(iterator)</code> et puis une autre implémentation en stockant les indices dans un <code>std::set</code> et encore une autre dans <code>std::unordered_set</code>. Je n'y crois pas trop mais ça me semble important pour la complétude.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30352e706e67/clean-results-05.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-05.png"></p>
<p>Sans surprise, il n'y a aucun gain ici. Le second meilleur, après l'algo naïf, reste celui qui conserve la liste d'indices dans un <code>std::vector</code> et qui échange les indices supprimés avec le dernier de la collection.</p>
<p>Et si l'algo retournait le résultat dès lors qu'il n'y a plus d'indices à traiter, c’est-à-dire la pratique du <em>return early</em> ? Tiens je vais essayer sur plusieurs des implémentations précédentes pour voir.</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30362e706e67/clean-results-06.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-06.png"></p>
<p>Bon, mauvaises piste. Ça fait partie du jeu de l'optimisation : dès fois on trouve et des fois on se perd. À part pour l'implémentation <em>branchless</em> il n'y a pas d'intérêt à quitter tôt. Cela dit c'est surprenant de voir que la version « indices » se comporte moins bien avec le <em>return early</em>. Est-ce le résultat de mauvaises prédictions du processeur ? Je ne saurais dire.</p>
<p>Continuons sur la version « indices ». La fonction commence par remplir un vecteur avec tous les indices de 1 à n par un appel de <code>std::iota</code>. Est-ce qu'on ne pourrait pas faire mieux en générant un tableau d'indices jusqu'à la taille maximum des matrices dès le début du programme puis initialiser la variable <code>usable_columns</code> à partir de ce tableau ? Nope, ça ne change rien. Crois-moi, j'ai testé.</p>
<p>Tiens, une autre approche classique de l'optimisation, je vais dérouler en partie la boucle la plus interne. L'implémentation commence à être un peu longue alors je vous invite à regarder <a href="https://github.com/j-jorge/codesignal">le code sur GitHub</a>. Il y a plusieurs implémentations :</p>
<ul>
<li><p><code>indices_4_by_4</code> parcours <code>usable_columns</code> par segments de 4 colonnes à la fois et <em>swappe</em> ces indices en <em>branchless</em> de manière à mettre ceux qui ont abouti à zéro à la fin de ce segment, puis les remplace par les valeurs à la fin d'<code>usable_columns</code>.</p></li>
<li><p><code>indices_4_by_4_partition</code> fait la même chose mais utilise <code>std::partition</code> pour réordonner le segment.</p></li>
<li><p>et <code>indices_8_by_8_partition</code> fait de même sur un segment de 8 colonnes.</p></li>
</ul>
<p>Et le benchmark :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30382e706e67/clean-results-08.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-08.png"></p>
<p>Bon, aucun succès à nouveau. Le compilateur se débrouille clairement mieux que moi pour optimiser la boucle, ce qui n'est pas vraiment surprenant.</p>
<h2 id="toc-changement-doutils">Changement d'outils</h2>
<p>Un peu à court d'idée je me demande ce que ça donnerait si la matrice était représentée en <em>column-major</em> plutôt que <em>row-major</em>. En d'autres termes, je me demande quel est l'impact de la structure de données sur les performances. Au niveau de l'algorithme ça serait assez direct:</p>
<pre><code class="c++"><span class="kt">int</span> <span class="nf">matrix_elements_sum_column_major</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>>&</span> <span class="n">m</span><span class="p">)</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">r</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="kt">int</span><span class="o">>&</span> <span class="nl">column</span> <span class="p">:</span> <span class="n">m</span><span class="p">)</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="nl">v</span> <span class="p">:</span> <span class="n">column</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">v</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
<span class="k">break</span><span class="p">;</span>
<span class="n">r</span> <span class="o">+=</span> <span class="n">v</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">return</span> <span class="n">r</span><span class="p">;</span>
<span class="p">}</span></code></pre>
<p>Et au niveau des performances :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d30392e706e67/clean-results-09.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-09.png"></p>
<p>Intéressant, avec une structure de données en <em>column-major</em> les performances sont les mêmes que la meilleure combinaison des algos en <em>row-major</em> vus jusque-là, et l'implémentation est simplissime.</p>
<p>Est-ce qu'un changement de compilateur change aussi les performances relatives des implémentations précédentes ? Essayons avec Clang 9 :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d31302e706e67/clean-results-10.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-10.png"></p>
<p>Ça ressemble pas mal aux résultats obtenus avec GCC 9, avec un clair gain pour la structure de données <em>column-major</em> pour les petites tailles. Par contre, cette structure de données perd face à <code>indices</code> en <code>row-major</code> des 256×256. C'est surprenant.</p>
<p>Allez pour finir comparons les performances relatives de Clang et GCC dans un seul graphe. Le programme est compilé avec les deux compilateurs puis lancé sur la <em>seed</em> 1234. Je ne prends que les meilleurs algorithmes vus précédemment :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6769746875622e636f6d2f6a2d6a6f7267652f636f64657369676e616c2f7261772f313234393663316138353661346663383832633534393361333932643639643739616235313963642f6d61747269782d656c656d656e74732d73756d2f636c65616e2d726573756c74732d31312e706e67/clean-results-11.png" alt="" title="Source : https://github.com/j-jorge/codesignal/raw/12496c1a856a4fc882c5493a392d69d79ab519cd/matrix-elements-sum/clean-results-11.png"></p>
<p>Globalement c'est assez semblable même si Clang se débrouille légèrement mieux sur la version <code>indices</code> et GCC l'emporte à peu de choses sur l'algorithme naïf. Sur la version <em>column-major</em> aucun deux compilateurs ne se démarque.</p>
<p>Il y a quatre ans j'avais effectué <a href="https://medium.com/@julienjorge/benchmarking-atoui-a-follow-up-to-writing-fast-code-90e722590f4d">des benchmarks qui montraient une forte différence d'optimisations entre GCC et Clang </a>. C'est agréable de voir que les performances des deux compilateurs sont maintenant plutôt proches.</p>
<h2 id="toc-quand-et-quoi-optimiser">Quand et quoi optimiser</h2>
<blockquote>
<p>Premature optimization is the root of all evil.</p>
</blockquote>
<p>Il est coutume dans le monde des programmeurs d'accueillir par cette citation (amputée) toute tentative d'optimisation d'un code sans avoir d'abord montré son impact sur les performances. La version longue, moins souvent citée, ressemble à ça :</p>
<blockquote>
<p>We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.<br>
— Donald Knuth</p>
</blockquote>
<p>Faut-il pour autant écrire les algorithmes les plus naïfs dès le départ comme pour prévenir toute sorte d'optimisation prématurée ? Eh bien ça dépend. L'algorithme naïf pour le problème considéré ici est performant tant que la matrice est très petite, puis s'écroule rapidement au fur et à mesure que les matrices traitées sont plus grandes. La question qu'il faut alors se poser est « Quel est l'ordre de grandeur des données que mon algo va réellement traiter ? » Autrement dit, est-ce qu'il y a absolument toutes sortes de tailles (ce n'est certainement pas le cas), est-ce que les matrices tiennent toujours dans le cache du processeur ?</p>
<p>Nous avons vu aussi que la structure de données elle-même a un fort impact sur les performances. En passant en <em>column-major</em> un algorithme natif se comporte aussi bien que les meilleurs cas de tous les autres de la version <em>row-major</em>. Ce qui amène à une autre question qui ouvre la porte à d'autres formes d'optimisations : ai-je la main sur la structure de données ? Comment puis-je la transformer pour simplifier mon implémentation et le travail du compilateur ?</p>
<p>En tant que développeur je pense qu'il est bon d'acquérir une certaine culture sur ce que peut faire le matériel qui fait tourner nos programmes ainsi que sur le coût relatif des traitements de nos algorithmes. Non pas pour optimiser tous les cas d'utilisations mais au moins pour ne pas surcharger de traitements inutiles des programmes déjà gourmands. Une sorte de preuve de bonne intention en quelque sorte.</p>
<p>Cette culture s'acquiert par la pratique ; c'est ce que nous apportent ces exercices de programmation. Notamment ici l'approche que je croyais solide (<em>row-major</em> -> scan par ligne) était complètement à la rue sur les petites tailles. On voit alors l'intérêt de pouvoir faire tenir les données dans le cache du processeur. De plus les versions <em>branchless</em> étaient moins performantes que les équivalents <em>branchful</em> (peut-être est-ce juste un manque de savoir faire pour le coup). Ce fut aussi l'occasion de tester un paquet d'implémentations et de constater, à nouveau, l'incroyable travail d'optimisation que font les compilateurs avec notre code.</p>
<p>Finalement ce petit exercice de programmation a amené beaucoup de questions et des réponses parfois surprenantes. J'ai appris des choses donc je pense que ça valait le coup. Nous verrons si les exercices suivants sont aussi enrichissants !</p>
<div><a href="https://linuxfr.org/users/julien_jorge/journaux/exercices-de-programmation-et-benchmarks.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/119392/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/julien_jorge/journaux/exercices-de-programmation-et-benchmarks#comments">ouvrir dans le navigateur</a>
</p>
Julien Jorgehttps://linuxfr.org/nodes/119392/comments.atomtag:linuxfr.org,2005:Bookmark/2072018-07-21T12:59:39+02:002018-07-21T12:59:39+02:00Pentominos en JavaScript : force brute contre algorithme DLX Donald Knuth<a href="https://github.com/alouali/pentominos">https://github.com/alouali/pentominos</a> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/114948/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/alouali/liens/pentominos-en-javascript-force-brute-contre-algorithme-dlx-donald-knuth#comments">ouvrir dans le navigateur</a>
</p>
aloualihttps://linuxfr.org/nodes/114948/comments.atomtag:linuxfr.org,2005:News/368512015-11-10T15:14:12+01:002015-11-24T21:56:41+01:00TeX et traitement de données par flot e01 : lire du TeXLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<div><p>Depuis quelques temps je travaille de manière sporadique sur une bibliothèque pour manipuler des documents TeX en Scala nommée <a href="https://github.com/satabin/toolxit-ng">ToolXiT</a>.<br>
Cette bibliothèque est loin d'être finie et bouge encore beaucoup, mais elle me permet aussi de faire des essais.<br>
Ce faisant, j'ai pu faire face à quelques défis intéressants, qui méritent au moins une série de dépêches sur LinuxFr.org, que ce soit sur TeX lui même ou le traitement par flot de données.</p>
<p>Je vais essayer de faire une série aussi intéressante que celle de <a href="//linuxfr.org/users/rewind/">rewind</a> sur la <a href="//linuxfr.org/tags/gamedev/public">création de jeu vidéo</a>, nous verrons bien comment elle évoluera.</p>
<p>Prêts ? Allons y !</p></div><ul><li>lien nᵒ 1 : <a title="https://github.com/satabin/toolxit-ng" hreflang="en" href="https://linuxfr.org/redirect/95527">ToolXiT</a></li><li>lien nᵒ 2 : <a title="https://tug.org/" hreflang="en" href="https://linuxfr.org/redirect/95528">TUG</a></li><li>lien nᵒ 3 : <a title="https://www.tug.org/utilities/plain/cseq.html" hreflang="en" href="https://linuxfr.org/redirect/95529">TeX primitives</a></li><li>lien nᵒ 4 : <a title="http://linuxfr.org/users/george/journaux/des-nouvelles-de-bluelatex-release-candidate-et-systemes-a-entites" hreflang="fr" href="https://linuxfr.org/redirect/95541">Journaux de l'auteur sur \BlueLaTeX, un autre projet</a></li></ul><div><h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li>
<a href="#tex">TeX</a><ul>
<li><a href="#quest-ce-que-cest">Qu'est-ce que c'est ?</a></li>
<li><a href="#latex-context">LaTeX ? ConTeXt ?</a></li>
<li><a href="#p%C3%A9rim%C3%A8tre-de-la-biblioth%C3%A8que">Périmètre de la bibliothèque</a></li>
</ul>
</li>
<li><a href="#lire-du-tex">Lire du TeX</a></li>
<li><a href="#le-syst%C3%A8me-de-macros-de-tex">Le système de macros de TeX</a></li>
<li><a href="#reprise-sur-erreur">Reprise sur erreur</a></li>
<li><a href="#conclusion">Conclusion</a></li>
</ul><h2 id="tex">TeX</h2>
<h3 id="quest-ce-que-cest">Qu'est-ce que c'est ?</h3>
<p>Le premier constat que j'ai pu faire en m'attaquant à TeX, c'est que globalement il existe une grosse incompréhension sur ce que c'est. Revenons donc sur les termes et définissons les précisément.</p>
<p>Ne souhaitant pas me lancer à l'aveugle et dans l'à-peu-près, je me suis procuré une copie papier de l'excellent <a href="http://www.amazon.com/The-TeXbook-Donald-E-Knuth/dp/0201134489">TeXbook</a> de Donald Knuth, auteur de TeX. Mon travail est entre autres le résultat de la lecture de ce livre de référence.</p>
<p>TeX est donc un logiciel de composition de documents.<br>
Son but est de prendre une entrée textuelle composée de caractères et de sortir un document formaté.<br>
TeX est aussi un langage, utilisé pour composer lesdits documents.<br>
Même s'il est <a href="https://fr.wikipedia.org/wiki/Turing-complet">Turing-complet</a>, je m'avancerai ici à dire que TeX est en fait un <a href="https://fr.wikipedia.org/wiki/Langage_d%C3%A9di%C3%A9">langage dédié</a> (<em>DSL</em>), et a été spécifiquement créé pour mettre en forme des documents.</p>
<p>Le premier défi rencontré tient à la nature du langage.<br>
TeX est un langage à macros qui sont développées au fur et à mesure du traitement de l'entrée.<br>
Il n'est pas <em>parsable</em> (analysable syntaxiquement) au sens classique des autres langages ; il est impossible de construire un arbre syntaxique d'une entrée.<br>
L'entrée peut modifier le comportement futur de TeX, notamment la manière dont le reste de l'entrée est analysé et interprété, ce qui rend impossible la construction d'un arbre syntaxique.<br>
Pour un exposé du problème et un traitement d'un sous problème, je conseille vivement la lecture de <a href="http://www.mathematik.uni-marburg.de/%7Eseba/publications/sle10.pdf">cet article</a>(pdf).</p>
<p>Qu'entends-je ? Il est impossible d'analyser du TeX ?<br>
Ce n'est pas bien grave car ce langage permet simplement d'écrire une séquence de commandes à interpréter dans l'ordre pour produire un joli document.<br>
Une fois qu'une commande a été traitée, TeX continue avec le reste, jetant ce qui a déjà été pris en compte.<br>
Nous voyons donc déjà venir le côté de traitement par flot.</p>
<p>Pour ce faire, TeX reconnait environ 300 commandes primitives de natures diverses :</p>
<ul>
<li>les commandes liées aux macros et à leur développement (définition, conditions, …) ;</li>
<li>les commandes représentant des variables utilisées pour la composition du document (tailles, polices, …) ;</li>
<li>les commandes de composition de document ;</li>
<li>d'autres types de commandes encore pour gérer des interactions, les logs, etc.</li>
</ul><p>Outre leur description dans le livre de Knuth, vous pourrez trouver une excellente et complète référence en ligne de <a href="https://www.tug.org/utilities/plain/cseq.html">toutes les primitives de TeX</a>, agrémentée de plein d'exemples.</p>
<p>Les commandes de composition sont des instructions à l'ordinateur afin de lui indiquer comment représenter le document.<br>
C'est une séquence, sans structure, un peu comme des instructions de dessin.<br>
Pour faire simple, TeX crée des boites, qui peuvent contenir d'autres boites, des caractères ou des lignes, et l'ensemble de ces boites compose des pages, des paragraphes, des lignes et des caractères.<br>
Beaucoup de calculs ont lieu, tous plus intéressants les uns que les autres afin que le résultat soit agréable et respecte certaines règles typographiques.<br>
Par exemple, l'<a href="http://www.tug.org/docs/liang/">algorithme de calcul des césures</a> utilisé par TeX pour savoir quand couper un mot en fin de ligne pour que le résultat soit correct dans la langue du document pourrait faire l'objet d'un futur article dédié.<br>
Et ce n'est qu'un exemple parmi d'autres.</p>
<p>À noter qu'il n'y a aucune notion de structure de document (titre, chapitre, section, …) dans TeX.</p>
<p>Le gros problème de TeX est qu'il est pour le moins rugueux à appréhender, et ne contient pas de notions de très haut niveau pour définir les éléments structurels d'un document.<br>
Fort heureusement, le langage de macros permet de définir des commandes de plus au niveau, qui seront rapidement ramenées aux primitives par TeX, mais qui permettent à l'utilisateur de manipuler des concepts de documents plus facilement.</p>
<p>Dans le vocabulaire consacré, un ensemble de macros utilisé pour un document est appelé un <em>format</em>.<br>
Dans son livre, Knuth définit le format <em>plain TeX</em> qu'il utilise lui même pour composer son livre.<br>
Entre autres, ce format définit des macros permettant de déclarer des théorèmes numérotés, de créer des sections ou encore de composer des documents avec des caractères accentués non présents sur le clavier.</p>
<p>C'est mieux, mais encore compliqué et assez bas niveau.</p>
<h3 id="latex-context">LaTeX ? ConTeXt ?</h3>
<p>TeX n'est réellement devenu populaire dans certains milieux que par d'autres formats, très (trop) complets, comme <a href="https://www.latex-project.org/">LaTeX</a> ou <a href="http://wiki.contextgarden.net/Main_Page">ConTeXt</a>.<br>
Ces deux projets consistent en un énorme ensemble de macros TeX entassées les unes sur les autres avec des concepts plus haut niveau comme les tables de matière et de figures ou le placement automatique de figures.<br>
Ils ont aussi une structure modulaire permettant de charger des paquets adaptés à des usages précis (dessin, tableau, …).</p>
<p>Ces formats simplifient grandement l'usage de TeX, mais ont à mes yeux de gros problèmes :</p>
<ul>
<li>ils sont composés d'un empilement démentiel de macros, développées lors du traitement du document rendant le diagnostic quelque peu ardu en cas d'erreur se produisant au fin fond d'un développement ;</li>
<li>ils donnent une fausse impression de langage de documents structurés alors que tout est toujours à plat. Les éditeurs qui prennent les commandes comme <code>\chapter</code> et autres <code>\section</code> comme des primitives sont très peu stables face au cas général d'une entrée TeX, et il est très facile de les faire se prendre les pieds dans le tapis et casser tout leur intérêt (outline, …) avec quelques <code>\def</code> bien placés ;</li>
<li>ils confondent trop contenu et mise en forme sémantique (mise en exergue, en gras, …) et mise en forme du document final (page format A4, format pdf, …).</li>
</ul><p>Cependant ces outils restent dans le top de l'existant pour moi et surpassent n'importe quel traitement de texte WYSIWYG, tant en terme d'utilisabilité que de résultat (phrase subjective détectée).</p>
<p>Vous remarquerez que dans cette section, à aucun moment je n'ai parlé de formules mathématiques.<br>
Il est en effet souvent admis que TeX et ses dérivés sont principalement utiles pour écrire des maths.<br>
Je dirais : non.</p>
<p>Tout simplement, la composition de formules mathématiques consiste en un sous ensemble non trivial de la composition de document en général et TeX la prend en charge de manière native sans s'y restreindre.<br>
Ainsi, même sans avoir besoin de formater des symboles grecs ou des équations, TeX peut avoir des avantages, que ce soit pour mettre en forme des <a href="http://eple.hib.no/felles/EGypto.pdf">hiéroglyphes</a> ou des <a href="http://icking-music-archive.org/software/musixtex/musixdoc.pdf">partitions de musique</a> ; on peut même estimer qu'avoir ses documents (spécifications, lettres, factures, …) sous format texte est plus fiable pour les stocker pendant des années que n'importe quel format de traitement de texte et utiliser TeX à ces fins.<br>
Tout est histoire de goût et de préférence bien sûr, et je m'éloigne du sujet initial.<br>
Tout ça pour dire : TeX n'est pas synonyme de maths.</p>
<h3 id="périmètre-de-la-bibliothèque">Périmètre de la bibliothèque</h3>
<p>Maintenant que nous savons de quoi nous parlons, je souhaite recentrer la dépêche sur ce qui a vocation à être pris en charge dans la bibliothèque que je développe.<br>
Le but est de savoir interpréter une entrée TeX composée de caractères et de macros et de sortir une suite de commandes primitives pouvant être ensuite interprétées pour mettre en forme le document.<br>
Le but premier est donc d'implémenter la définition et le développement des macros.<br>
Et ce problème n'est déjà pas forcément trivial.</p>
<h2 id="lire-du-tex">Lire du TeX</h2>
<p>Avant de parler du traitement des macros, il est important de définir comment Knuth a envisagé la lecture d'une entrée par TeX.<br>
Tout le reste dépend fortement de ses choix.<br>
Dans son livre, il explique que l'entrée est avant tout une suite de caractères, qui sont ensuite transformés en <em>tokens</em> qui peuvent correspondre à un caractère ou une séquence de contrôle de la forme <code>\name</code>.<br>
Ces tokens sont ensuite développés via le développement de macros, jusqu'à ce que des commandes primitives soient rencontrées.<br>
Quand de telles commandes apparaissent, elles sont interprétées.</p>
<p>Nous voyons ici se découper un traitement de l'entrée par couches successives qui la transforment petit à petit pour mettre en forme le document.<br>
Ce qu'il est important de noter est que le développement des macros se fait au niveau des tokens, donc après une première couche d'analyse pour transformer les caractères.</p>
<p>De plus, les macros et primitives pouvant modifier la manière de transformer les caractères en tokens, nous comprenons aussi que l'entrée doit être traitées au fur et à mesure et ne peut pas être lue entièrement avant d'être traitée.</p>
<p>Dans son livre, Knuth utilise un vocabulaire biologique assez parlant pour décrire les différentes phases de traitement de TeX :</p>
<ul>
<li>TeX lit les caractères avec ses <em>yeux</em> et les transforme en tokens ;</li>
<li>les tokens passent ensuite par la <em>bouche</em> de TeX qui les <em>mâche</em> pour en faire des primitives ;</li>
<li>ces primitives sont ensuite passées au <em>système digestif</em> qui les digère et un document formaté en sort.</li>
</ul><p>Le vocabulaire usuel voudrait que les yeux soient une sorte de <em>lexer</em> et que la bouche soit le <em>parser</em>.</p>
<h2 id="le-système-de-macros-de-tex">Le système de macros de TeX</h2>
<p>Donc TeX est un langage de macros.<br>
C'est bien mais il existe plusieurs <a href="http://ojs.statsbiblioteket.dk/index.php/brics/article/viewFile/20151/17772">types de systèmes de macros</a> (section 2 pour un résumé) qui sont très différents les uns des autres.</p>
<p>Sans faire durer le suspens plus longtemps, entrons directement en matière : TeX possède des macros de type lexical, c'est-à-dire qu'il manipule des éléments lexicaux (les tokens) et qu'une fois développée, une macro est remplacée par une suite de tokens ne formant pas forcément une structure syntaxique correcte.<br>
Il s'agit tout simplement de remplacer une suite de tokens formant un appel à une macro par une nouvelle suite de tokens, qui sont à leur tour développés si nécessaire, et ainsi de suite.</p>
<p>Les macros agissent sur les tokens et non sur les caractères de l'entrée.<br>
Globalement il existe en première approximation deux types de tokens seulement :</p>
<ul>
<li>les caractères comme <code>c</code>
</li>
<li>les séquence de contrôle comme <code>\a</code>.</li>
</ul><p>Si vous souhaitez plus de détails sur les règles qui transforment les caractères en tokens, je vous renvoie aux chapitres 7 et 8 du <em>TeXbook</em>.<br>
Notamment vous pourrez y trouver la raison pour laquelle des espaces semblent disparaitre dans vos documents, comme avalés par TeX.</p>
<p>Les macros peuvent prendre des paramètres (jusqu'à neuf dans l'implémentation de Knuth), avec ou sans délimiteur, elles peuvent être développées au moment de leur déclaration ou à leur utilisation, être globales ou locales, etc.<br>
Les règles qui régissent leur utilisation et leur définition sont assez nombreuses et font l'objet d'un chapitre entier dans le <em>TeXbook</em> (chapitre 20).<br>
Je n'aborderai pas toutes les subtilités ici, mais traiterai d'un exemple simple.</p>
<pre><code class="tex"><span class="k">\def\double</span>#1<span class="nb">{</span>#1#1<span class="nb">}</span></code></pre>
<p>Cette commande <code>\def</code> déclare une nouvelle macro <code>\double</code> qui prend un argument <code>#1</code> en entrée et le double.<br>
Ainsi, l'appel</p>
<pre><code class="tex"><span class="k">\double</span><span class="nb">{</span>to<span class="nb">}</span></code></pre>
<p>est développé en</p>
<pre><code class="tex">toto</code></pre>
<p>Pour procéder au développement de macros dans une entrée TeX, il faut simplement être capable de lire autant de tokens que nécessaire pour avoir tous les paramètres de la macro, et de les remplacer par le texte de remplacement donné lors de la définition, et de lire la nouvelle entrée.</p>
<p>TeX possède aussi des primitives qui entrent en jeu dans le développement de macros, comme les conditionnelles.<br>
D'autres primitives inhibent temporairement le développement de macros, comme <code>\noexpand</code>.<br>
Tout cela est composé de règles simples individuellement, mais dont la combinaison résulte en un système assez complexe.</p>
<h2 id="reprise-sur-erreur">Reprise sur erreur</h2>
<p>Un autre aspect que je souhaitais mentionner ici est la reprise sur erreur de TeX.<br>
En cas d'erreur lors du développement de macros ou du traitement d'une primitive, le système de reprise sur erreur de TeX se met en marche.<br>
Il permet soit de relire l'entrée pour corriger l'erreur, soit de sauter les tokens jusqu'à trouver une séquence de tokens correcte.</p>
<p>Ce mécanisme est d'intérêt dans le traitement de données par flot et nous y reviendrons sûrement dans la suite.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Nous avons donc vu ce qu'est TeX et comment il se lit à un haut niveau.<br>
Armés de ces concepts et définitions, dans les prochains épisodes, nous aborderons le design de la bibliothèque ToolXiT, le traitement de données par flot en général et dans notre cas ainsi que les solutions mises en place pour que tout se passe bien.</p>
<p>ToolXiT est en développement constant, cette série de dépêche devrait me permettre de le faire évoluer en même temps, et j'espère qu'il en sortira quelque chose de bon.<br>
N'hésitez pas à faire des retours sur ces articles ou sur l'implémentation, ils sont les bienvenus.</p></div><div><a href="https://linuxfr.org/news/tex-et-traitement-de-donnees-par-flot-e01-lire-du-tex.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/107268/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/tex-et-traitement-de-donnees-par-flot-e01-lire-du-tex#comments">ouvrir dans le navigateur</a>
</p>
LucasZeroHeureBenoît Sibaudhttps://linuxfr.org/nodes/107268/comments.atomtag:linuxfr.org,2005:Diary/353682014-10-27T02:46:53+01:002014-10-27T02:46:53+01:00Conférence d'Andrew S. TanenbaumLicence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p><a href="http://www.cs.vu.nl/%7East">Andrew S. Tanenbaum</a>, créateur de Minix, un OS à micro-noyau qui a été une des sources d'inspiration de Linux, viendra parler de <a href="http://www.minix3.org/">Minix 3</a> mardi 28 Octobre 2014 à Jussieu à 18h dans l'amphi 24.</p>
<p>La <a href="http://colloquium.lip6.fr/Tanenbaum-2014-10-28/">conférence</a> a lieu dans le cadre du <em>colloquium d'informatique de l'UPMC</em>, série de conférences auxquelles ont déjà participé, entre autres sommités de l'informatique, Donald Knuth, Leslie Lamport, Robert Sedgewick, ou Tony Hoare.</p>
<p>Vous aurez l'occasion de demander à Tanenbaum si <a href="https://groups.google.com/forum/#!topic/comp.os.minix/wlhw16QWltI%5B1-25-false%5D">Linux est obsolète</a>, comme il l'affirmait en 1992, ou plus sérieusement, de discuter des mérites comparés des micro-noyaux et des noyaux monolithiques.</p>
<blockquote>
<p>But in all honesty, I would suggest that people who want a <strong>MODERN</strong> "free" OS look around for a<br>
microkernel-based, portable OS, like maybe GNU or something like that.</p>
</blockquote>
<p>(Hé oui, le développement de GNU/Hurd a commencé en 1990, deux ans avant ce message sur <em>comp.os.minix</em> !)</p><div><a href="https://linuxfr.org/users/programlyrique/journaux/conference-d-andrew-s-tanenbaum.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/103754/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/programlyrique/journaux/conference-d-andrew-s-tanenbaum#comments">ouvrir dans le navigateur</a>
</p>
programLyriquehttps://linuxfr.org/nodes/103754/comments.atomtag:linuxfr.org,2005:Diary/352512014-09-16T15:58:22+02:002014-09-16T15:58:22+02:00Sortie de Blueprint v0.1Licence CC By‑SA http://creativecommons.org/licenses/by-sa/4.0/deed.fr<p>J'ai le plaisir de vous annoncer la sortie Blueprint v0.1, une bibliothèque METAPOST pour produire des graphiques utiles aux <em>project managers</em> et <em>system desginers</em>. Voilà une liste (exhaustive) de figures pouvant être produites avec la bibliothèque:</p>
<h3 id="exemple-de-timeline-graphic">Exemple de <em>timeline graphic</em>
</h3>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6269746275636b65742e6f72672f6d6963686970696c692f626c75657072696e742f646f776e6c6f6164732f6578616d706c655f74696d656c696e652d302e706e67/example_timeline-0.png" alt="timeline graphic" title="Source : https://bitbucket.org/michipili/blueprint/downloads/example_timeline-0.png"></p>
<h3 id="exemple-de-schedule-graphic">Exemple de <em>schedule graphic</em>
</h3>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6269746275636b65742e6f72672f6d6963686970696c692f626c75657072696e742f646f776e6c6f6164732f6578616d706c655f7363686564756c652d302e706e67/example_schedule-0.png" alt="schedule graphic" title="Source : https://bitbucket.org/michipili/blueprint/downloads/example_schedule-0.png"></p>
<h3 id="example-de-uml-component-diagram">Example de <em>UML component diagram</em>
</h3>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6269746275636b65742e6f72672f6d6963686970696c692f626c75657072696e742f646f776e6c6f6164732f6578616d706c655f756d6c636f6d706f6e656e742d302e706e67/example_umlcomponent-0.png" alt="UML component diagram" title="Source : https://bitbucket.org/michipili/blueprint/downloads/example_umlcomponent-0.png"></p>
<h3 id="example-de-graphique-avec-des-légendes">Example de graphique avec des légendes</h3>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f6269746275636b65742e6f72672f6d6963686970696c692f626c75657072696e742f646f776e6c6f6164732f6578616d706c655f6c6567656e642d302e706e67/example_legend-0.png" alt="chart with legends" title="Source : https://bitbucket.org/michipili/blueprint/downloads/example_legend-0.png"></p>
<p>Ce dernier graphique utilise La bibliothèque <code>graph</code> de METAFONT QUI permet de faire de zolis dessins, j'ai ajouté des légendes. Cela permet par exemple de faire dessins qui pètent pour <a href="http://stackoverflow.com/questions/25790177/monadic-buffers-in-ocaml/25829491">StackOverflow</a>.</p>
<h3 id="mais-je-nai-jamais-entendu-parler-de-metapost">Mais, je n'ai jamais entendu parler de METAPOST!</h3>
<p>C'est un programme par John Hobby, dérivant du METAFONT de Donald Knuth. Les deux programmes sont présents dans les distribution TeX. Essayez <code>which mpost</code> si vous n'êts pas sûr de l'avoir installé.</p>
<p>Plus de détails: <a href="http://www.tug.org/metapost.html">http://www.tug.org/metapost.html</a> (j'aime bien l'intro de André Heck,“Learning METAPOST by doing” par exemple).</p>
<h3 id="télécharger">Télécharger</h3>
<p>Le projet est publié sous bitbucket: <a href="https://bitbucket.org/michipili/blueprint/overview">https://bitbucket.org/michipili/blueprint/overview</a></p>
<h3 id="utiliser">Utiliser</h3>
<p>Il faut savoir programmer en METAPOST!</p>
<p>Si vous vouez essayer de compiler les exemples, la procédure automatique utilise mes macros BSD Make <a href="https://bitbucket.org/michipili/bsdowl">bsdowl</a> disponibles sous MacPorts et bientôt FreeBSD et Debian/Ubuntu. On peut aussi installer ces macros à la main bien-sûr, ou même s'en passer et se débrouiller pour compiler l'exemple à la main.</p>
<h3 id="contribuer">Contribuer</h3>
<p>Si <em>vous connaissez bien le domaine de project management</em> vous pouvez m'aider à utiliser une terminologie plus proche de la terminologie traditionnelle (<em>roadmap</em>, <em>milestone diagram</em> et <em>project schedule</em> sont souvent utilisés de façon interchangeable dans ce que j'ai pu lire).</p>
<p>Si <em>vous connaissez des beaux graphiques</em> — comme celui de la <em>timeline</em> — que vous aimeriez bien pouvoir dessiner avec METAPOST, n'hésitez pas à ouvrir une <em>issue</em> dans le projet avec un ou plusieurs exemples en document joint.</p>
<p>En particulier, si vous avez un exemple de <em>project schedule</em> plus joli que le mien ou un <em>UML component diagram</em> un peu mieux structuré que l'exemple que j'ai pioché dans mon moteur de rechercher préféré, n'hésitez pas!</p>
<h3 id="autres-solutions-pour-uml">Autres solutions pour UML</h3>
<p>Je connais Dia, mais je ne sais pas écrire des macros en Dia et je ne sais pas l'interfacer avec TeX. Je sais qu'il y a déjà une blbliothèque UML pour METAPOST, mais elle est complètement procédurale ce qui la rend très compliquée d'utilisation.</p>
<h3 id="exemple-de-code">Exemple de code</h3>
<p>Pour le graphe de fonction (extrait de <code>example/example_leegernd.mp</code>):</p>
<pre><code> draw begingraph(90mm, 60mm);
glabel.bot(TEX("Size of the dictionary"), OUT);
glabel.lft(TEX("Execution time (s)"), OUT);
gdraw "./times.d" dashed evenly;
gdraw "./times.d";
beginlegend;
legenditem(TEX("Monadic"), dashed evenly);
legenditem(TEX("Higher-Order"), withpen pencircle);
endlegend;
endgraph;
</code></pre>
<p>Les données du graphique sont contenues dans le fichier <code>times.d</code>.</p>
<p>Pour le <em>project schedule</em> (extrait de <code>example/example_schedule.mp</code>):</p>
<pre><code> domain2("Technical implementation", schedulepalette2);
activity2 1("Setup", month2, month2);
activity2 2("Test", month3, month3);
milestone2 deploy1("Deploy 1", month5);
milestone2 deploy2("Deploy 2", month7);
</code></pre>
<p>Pour la <em>timeline</em> (extrait de <code>examples/example_timeline.mp</code>) chaque <em>milestone</em> est déclarée avec un numéro, une importance et sa position relativement à la précédente. Les annotation sont positionnées en collant une pastille sur l'autocollant de la <em>milestone</em> avec un paramètre horaire (<code>11h</code>, <code>6h</code>, etc.) et en collant le texte sur ligne prédéfinie, en principe au dessus de l'autocollant mais en décalant si besoin.</p>
<pre><code> phase "Planning";
% Assessment
milestone 1, 2.0, 2;
annotation "Needs\\Assessment", 11h, overline1;
annotation "Needs Assessment\\Feedback", 6h, underline1 + u*right;
% Research
milestone 2, 3.0, 2;
annotation "Research", 11h, overline3 + u*right;
</code></pre>
<p>Pour <em>UML component diagram</em> on écrit des choses comme cela (extrait de <code>examples/example_umldiagram.mp</code>):</p>
<pre><code> component8("<Infrastructure>\\Persistence");
lollipop8 persistence("Persistence");
socket8 jdbc("JDBC");
…
z7 access anchor =
tick.lft7(1/2);
z7 encrypt anchor =
tick.top7(1/2);
z8 persistence anchor =
tick.lft8(1/2);
…
drawlollipop7 access;
drawlollipop7 encrypt;
drawlollipop8 persistence;
</code></pre>
<p>L'avantage de METAPOST est de pouvoir définir des macros. Par exemple tous les <em>Data Providers</em> sont définis avec la même macro, ce qui permet de changer facilement les connecteurs, etc.</p><div><a href="https://linuxfr.org/users/chat_de_sorciere/journaux/sortie-de-blueprint-v0-1.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/103300/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/chat_de_sorciere/journaux/sortie-de-blueprint-v0-1#comments">ouvrir dans le navigateur</a>
</p>
Michaëlhttps://linuxfr.org/nodes/103300/comments.atomtag:linuxfr.org,2005:News/348222013-11-17T16:22:08+01:002013-11-17T16:22:08+01:00Groff cherche un nouveau chef de projetLicence CC By‑SA http://creativecommons.org/licenses/by-sa/3.0/deed.fr<div><p>Groff est l'implémentation GNU du logiciel de formatage de texte Troff. Il est majoritairement utilisé aujourd'hui pour mettre en forme les pages de manuels, mais il réunit toujours autour de lui une communauté d'utilisateurs convaincus.</p>
<p>Depuis longtemps déjà, Werner Lemberg, le mainteneur principal du projet ne pouvait plus y consacrer beaucoup de temps. Il a officiellement fait appel ce week-end à un nouveau chef de projet pour Groff. La suite de la dépêche détaille le contexte de cet appel à candidature.</p></div><ul><li>lien nᵒ 1 : <a title="https://www.gnu.org/software/groff/" hreflang="fr" href="https://linuxfr.org/redirect/88502">GNU Troff</a></li><li>lien nᵒ 2 : <a title="http://lists.gnu.org/archive/html/groff/2013-11/msg00051.html" hreflang="fr" href="https://linuxfr.org/redirect/88503">Appel à candidature</a></li><li>lien nᵒ 3 : <a title="https://www.gnu.org/help/evaluation.html#whatmeans" hreflang="fr" href="https://linuxfr.org/redirect/88504">Maintenir un projet Gnu</a></li><li>lien nᵒ 4 : <a title="http://linuxfr.org/users/sygne/journaux/jouons-avec-unicode-tchars-un-dchars-pour-troff" hreflang="fr" href="https://linuxfr.org/redirect/88505">DLFP : Jouons avec Unicode: Tchars, un Dchars pour Troff</a></li><li>lien nᵒ 5 : <a title="http://linuxfr.org/users/sygne/journaux/utroff-est-publie" hreflang="fr" href="https://linuxfr.org/redirect/88506">DLFP : Utroff est publié</a></li></ul><div><h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><a href="#contexte-de-lappel-%C3%A0-candidature">Contexte de l'appel à candidature</a></li>
<li>
<a href="#t%C3%A2ches-du-futur-mainteneur">Tâches du futur mainteneur</a><ul>
<li><a href="#maintenance-g%C3%A9n%C3%A9rale">Maintenance générale</a></li>
<li><a href="#am%C3%A9liorations-techniques">Améliorations techniques</a></li>
</ul>
</li>
<li><a href="#%C3%89l%C3%A9ments-de-motivation">Éléments de motivation</a></li>
</ul><h2 id="contexte-de-lappel-à-candidature">Contexte de l'appel à candidature</h2>
<p>Il y a quelques mois, <a href="http://www.troff.org/whoswho.html#werner">Werner Lemberg</a>, qui a longtemps maintenu Groff avec soin, annonçait aux membre de la liste de discussion de Groff que celui-ci n'était plus pour lui une priorité :</p>
<blockquote>
<p>Je vais donner la priorité à d'autres travaux, particulièrement <a href="http://freetype.org/">FreeType</a> et <a href="http://www.freetype.org/ttfautohint/">ttfautohint</a>. Pour l'instant, je suis particulièrement occupé à faire évoluer ces logiciels, et je serais vraiment reconnaissant si quelqu'un pouvait s'occuper de la tâche de mainteneur principal…</p>
</blockquote>
<p>En annonçant cela, il ne faisait qu'officialiser une situation bien connue : le développement de Groff est fortement ralenti depuis plusieurs années. Les utilisateurs de Groff semblaient d'ailleurs s'être résignés au fait que Groff n'évoluerait plus vraiment. Seuls quelques passionnés continuent à utiliser Groff pour formater leurs textes, et même pour afficher les manuels, Groff est maintenant fortement concurrencé par <a href="http://mdocml.bsd.lv/">mandoc</a>. De fait, Groff n'attire plus suffisamment d'utilisateurs pour qu'il y ait parmi eux une proportion suffisante de développeurs motivés pour le maintenir.</p>
<p>Il a donc fallu attendre ce week-end pour que quelqu'un manifeste quelque inquiétude quant à l'avenir de Groff. Et c'est <a href="http://www.schaffter.ca">Peter Schaffter</a>, le créateur de la <a href="http://www.schaffter.ca/mom/mom-01.html">macro mom</a>, qui est aussi connu pour être un fervent défenseur de Groff, qui s'est exprimé le premier à ce propos :</p>
<blockquote>
<p>Nous ne retrouverons jamais quelqu'un comme Werner, mais la tâche est devant nous : où ira Groff dorénavant, et qui prendra la barre ?</p>
</blockquote>
<p>Après quelques discussions, Werner Lemberg a publié un appel à candidature sur la liste de discussion des développeurs du projet GNU :</p>
<blockquote>
<p>Chers amis,<br>
Nous avons besoin d'un nouveau mainteneur pour Gnu Troff. Quand bien même j'applique quelques modifications critiques ici où là, je n'ai plus la force de participer activement au développement du logiciel.<br>
Sachez que Ted Harding, mon co-mainteneur, ne code pas du tout; il est plutôt cette personne bienveillante qui prend soin des demandes des utilisateurs sur la liste de discussion (et je suis vraiment reconnaissant qu'il le fasse).<br>
Je pense que le logiciel lui-même est en très bon état; il compile sans problèmes sur la plupart (sinon toutes) les plateformes, pour autant que je sache.</p>
</blockquote>
<h2 id="tâches-du-futur-mainteneur">Tâches du futur mainteneur</h2>
<p>Dans ce mail, Werner Lemberg énumère rapidement les tâches qui lui semblent prioritaires.</p>
<h3 id="maintenance-générale">Maintenance générale</h3>
<blockquote>
<p>Remplacer le repos CVS par un DVCS moderne (je préfère git).</p>
</blockquote>
<p>Ceci fait suite à la <a href="http://lists.gnu.org/archive/html/groff/2013-11/msg00052.html">proposition</a> de Éric S. Raymond de s'occuper justement de cette tâche.</p>
<blockquote>
<p>Mettre à jour l'infrastructure pour utiliser gnulib. Pour l'instant, seul un module utilise gnulib, ce qui est un gaspillage de ressource et est difficile à maintenir.</p>
<p>Faire en sorte que Groff utilise automake.</p>
</blockquote>
<p>Une meilleure utilisation des outils Gnu par Groff n'est pas un simple effet d'annonce : à plusieurs reprises, Werner Lemberg a précisé sur la liste de discussion que la façon correcte de corriger certains problèmes supposait d'utiliser tant automake que gnulib.</p>
<h3 id="améliorations-techniques">Améliorations techniques</h3>
<blockquote>
<p>Implémenter l'algorithme de Tex de formatage des paragraphes, ou un équivalent - je considère que le formatage des paragraphes lignes après lignes pratiqué par Groff est son point faible. Voir <a href="http://heirloom.sourceforge.net/doctools.html">heirloom troff</a> comme un exemple de la façon dont cela pourrait être implémenté.</p>
</blockquote>
<p>L'algorithme en question est rapidement évoqué dans l'article anglais <a href="https://en.wikipedia.org/wiki/Word_wrap#Algorithm">word wrap</a> de wikipedia et est décrit en détail dans l'article de Knuth Plass : <em>Breaking paragraph into lines</em>, in <em>Software practice and experience</em>. On pourrait aussi penser aux algorithmes de <a href="https://en.wikipedia.org/wiki/Microtypography">micro-typographie</a> qui ont motivés la création de <a href="https://en.wikipedia.org/wiki/H%C3%A0n_Th%E1%BA%BF_Th%C3%A0nh">PdfTex</a>, et qui sont aussi incorporés dans Heirloom Troff.</p>
<blockquote>
<p>Adapter Groff au monde des polices d'aujourd'hui. Celles que Groff supporte nativement (Postscript type 1) sont dépassées depuis 15 ans. À nouveau, Heirloom Troff implémente cela.</p>
</blockquote>
<p>La gestion des polices est douloureuse avec Groff. Les polices postscript elles-mêmes doivent être converties dans le format historique de Troff pour être utilisées avec Groff. Que Groff sache utiliser les polices OpenType par défaut semble être un minimum aujourd'hui.</p>
<blockquote>
<p>Meilleur support de l'Unicode.</p>
</blockquote>
<p>À vrai dire, Groff ne supporte pas l'unicode : il fait appel à un pré-processeur (preconv) qui convertit pour lui les fichiers d'entrée en ascii. C'est une solution qui fonctionne bien, mais qui a quelques défauts : certains fichiers qui ne sont lus que tardivement par la chaîne de commandes de Groff ne sont pas convertis, l'utilisateur n'ayant alors pas d'autres choix que de le faire manuellement.</p>
<h2 id="Éléments-de-motivation">Éléments de motivation</h2>
<p>Travailler avec la communauté de Groff sur le code source de Groff peut se révéler être une belle expérience :</p>
<ul>
<li>Avant d'être un ensemble d'algorithmes, la typographie est un art soucieux du détail et marqué par l'histoire. L'implémentation des algorithmes typographiques est probablement autant une affaire de génie logiciel qu'une affaire de bon goût - et il y a certainement place pour l'invention. Le mainteneur de Groff aura là une belle occasion d'entraîner son œil de typographe puisque c'est essentiellement la qualité gris typographique produit par Groff qu'il s'agit d'améliorer.</li>
<li>L'implémentation informatique des bonnes pratiques typographiques est un terrain de jeu de développeurs de renom. De fait, ce sont les textes et le code source de Kernighan et Knuth qu'il faudra étudier pour les adapter à Groff.</li>
<li>La communauté de Groff a ceci d'étrange qu'elle réunit des défenseurs d'interfaces textes, des universitaires formés aux sciences humaines, et de vieux utilisateurs de logiciels libres, dont certains ont activement participé à son histoire. Le ton de la liste de discussion y est toujours feutré et respectueux, et il y a un certain plaisir à suivre la vie de cette communauté.</li>
</ul></div><div><a href="https://linuxfr.org/news/groff-cherche-un-nouveau-chef-de-projet.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/100373/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/groff-cherche-un-nouveau-chef-de-projet#comments">ouvrir dans le navigateur</a>
</p>
SygneOntologiaNÿcoBenoît Sibaudclaudexhttps://linuxfr.org/nodes/100373/comments.atomtag:linuxfr.org,2005:Diary/342842013-09-09T09:20:30+02:002013-09-09T09:20:30+02:00Seuls les fous comprennent quelques chose à l’internetLicence CC By‑SA http://creativecommons.org/licenses/by-sa/3.0/deed.fr<h2 class="sommaire">Sommaire</h2>
<ul class="toc">
<li><ul>
<li><a href="#introduction">Introduction</a></li>
<li>
<a href="#les-gens-s%C3%A9rieux-professionnels-de-linformatique-compris-ne-comprennent-rien-%C3%A0-linternet">Les gens sérieux, professionnels de l’informatique compris, ne comprennent rien à l’internet</a><ul>
<li><a href="#b%C3%A2tir-sa-maison-sur-du-sable">Bâtir sa maison sur du sable</a></li>
<li><a href="#para%C3%AEtre-s%C3%A9rieux">Paraître sérieux</a></li>
<li><a href="#avoir-fait-les-%C3%A9coles-quil-faut">Avoir fait les écoles qu’il faut.</a></li>
</ul>
</li>
<li><a href="#mais-lexp%C3%A9rience-montre-que-seuls-les-fous-comprennent-vraiment-linternet">Mais l’expérience montre que seuls les fous comprennent vraiment l’Internet</a></li>
<li><a href="#brain-storming-collectif--qui-sont-les-fous-majeurs-qui-ont-fait-dinternet-ce-quil-est-devenu">Brain storming collectif : qui sont les fous majeurs qui ont fait d’internet ce qu’il est devenu ?</a></li>
<li>
<a href="#%C3%89bauche-de-liste-proprement-dite">Ébauche de liste proprement dite</a><ul>
<li><a href="#les-personnalit%C3%A9s-de-linternet-et-du-web">Les personnalités de l’Internet et du Web</a></li>
<li><a href="#les-stars-de-la-programmation">Les stars de la programmation</a></li>
</ul>
</li>
<li><a href="#googlers">Googlers</a></li>
<li>
<a href="#voices-of-the-opensource-revolution">Voices of the OpenSource revolution</a><ul>
<li><a href="#apple-inc">Apple Inc.</a></li>
<li><a href="#autres-personnalit%C3%A9s-ayant-fond%C3%A9-des-sites-majeurs">Autres personnalités ayant fondé des sites majeurs</a></li>
</ul>
</li>
<li><a href="#simples-particuliers-qui-utilisent-internet-de-mani%C3%A8re-particuli%C3%A8rement-intelligente">Simples particuliers qui utilisent Internet de manière particulièrement intelligente</a></li>
</ul></li>
</ul><p><strong>NOTE</strong> : <em>au fur et à mesure que ce journal grandissait grandissait, il est apparu clairement que je me suis lancé sans le savoir dans un projet un peu trop ambitieux pour un journal linuxfr. Vous pouvez bien sûr lire mon baratin ci-dessous, mais si vous voulez contribuez avec effiacité, <a href="https://github.com/internaciulo/eloge-de-la-folie">forkez sur github</a> ou avec votre client git préféré en utilisant <code>git@github.com:internaciulo/eloge-de-la-folie.git</code>, éditez, puis sortez balancez vos pulls requests ;-)</em></p>
<h3 id="introduction">Introduction</h3>
<p>Bonjour chers linuxfriens, voici mon premier journal sous ce pseudo (mais j’en ai eu de nombreux auparavant vu que je fréquente linuxfr depuis dix ans)</p>
<p>Je compte me lancer bientôt dans « une entreprise qui n’eut point d’exemple et dont l’imitation n’aura point d’imitateur » comme disait Rousseau ; un trouc un peu fou donc, mais n’étant qu’à moitié fou, je ne m’y lancerais pas tout seul et il est même probable que je vienne demander sur ce site à d’autres fous si cela les intéresse de co-fonder ce projet fou. </p>
<p>Pour l’instant, le sujet qui me préoccupe, c’est quelque-chose à la fois de totalement évident et que pourtant 95% des gens ne comprennent pas, c’est ceci : <em>Internet a été inventé par des fous, et que au fond seuls les gens eux-même un peu fous comprennent vraiment ce qui marche bien et ce qui ne marche pas du tout sur Internet.</em><br>
`</p>
<h3 id="les-gens-sérieux-professionnels-de-linformatique-compris-ne-comprennent-rien-à-linternet">Les gens sérieux, professionnels de l’informatique compris, ne comprennent rien à l’internet</h3>
<p>La partie la plus facile pour démontrer ma thèse est de regarder qui sont les « professionnels sérieux de l’informatique », notamment <strong>en France</strong>. </p>
<p>Je ne vais pas citer de nom parce que je n’aime pas tirer sur des ambulances, mais en gros si vous suivez <a href="http://fr.wikipedia.org/wiki/Soci%C3%A9t%C3%A9_de_services_en_ing%C3%A9nierie_informatique#En_France">ce lien Wikipédia</a>, que vous enlevez les heureuses exceptions de cette liste (il y en a), voous trouverez bon nombre de société ayant pignon sur rue, pleine à craquer d’armées de « professionnels sérieux de l’informatique en France. » </p>
<h4 id="bâtir-sa-maison-sur-du-sable">Bâtir sa maison sur du sable</h4>
<p>Le problème, c’est que si vous connaissez bien ces professionnels sérieux de l’informatique, vous avez du remarquer, que ce soit pour vous en amuser ou pour vous en affliger, qu’ils sont d’une <strong>inculture <em>crasse</em> en informatique</strong>. </p>
<p>J’aimerais vraiment penser que j’exagère, que ce ne soit pas le cas, tout simplement parce qu’en tant qe citoyen, contribuable, salarié du secteur, … je suis persuadé que mon métier et mon pays, la France, iraient beaucoup beaucoup meux s’ils avaient le minimum de compétence requis. Ou même si tout simplement, sans avoir eux-mêmes les compétences, ils auraient l’intelligence de comprendre que d’autres l’eux cette compétence, et l’humilité de leur demander de partager ça avec eux (moyennant finances évidemment).</p>
<p>Mais ce c’est tout simplement rarment le cas. Certes, je ne leur enleverai certainement pas cette qualité, ils manient avec beaucoup d’assurance <a href="http://en.wikipedia.org/wiki/List_of_buzzwords#Science_and_technology">les buzzwords du métier</a>, beaucoup mieux que moi en réalité, et ça leur permet de taper les mots clés dans leur base de données de CV pour croire recruter le bon profil correspondant au besoin dont le client croit avoir besoin. Cela est bien utile mais ça ne suffit hélas pas pour les raisons qu’un type dénommé Jésus a énoncé mieux que moi il y a bien longtemps</p>
<p>Matthieu 7<br>
24. C’est pourquoi, quiconque entend ces paroles que je dis et les met en pratique, sera semblable à un homme prudent qui a bâti sa maison sur le roc.<br>
25 La pluie est tombée, les torrents sont venus, les vents ont soufflé et se sont jetés contre cette maison: elle n’est point tombée, parce qu’elle était fondée sur le roc.<br>
26 Mais quiconque entend ces paroles que je dis, et ne les met pas en pratique, sera semblable à un homme insensé qui a bâti sa maison sur le sable.<br>
27 La pluie est tombée, les torrents sont venus, les vents ont soufflé et ont battu cette maison: elle est tombée, et sa ruine a été grande.</p>
<p>Car ces gens là, si vous regardez l’usage que <em>eux-même</em> font de l’informatique, vous vous rendez compte qu’il leur manque <strong>les bases</strong>. Et ça c’est grave parce que <a href="http://lightboxleadership.com/the-zen-of-self-leadership-7-core-principles/">« Effective Leadership is about leading yourself first. »</a>. </p>
<p>Exemples ?</p>
<ul>
<li>ils parlent de Web 2.0, HTML5 pour les meilleurs, mais ils ne comprennent pas le concept <a href="http://fr.wikipedia.org/wiki/URL">d’URL - Uniform Resource Locator - un truc obsolète sans doute puisque standardisé en 1994</a>
</li>
<li>l’email est leur outil de base, mais ils ne le maitrisent tout simplement pas. Ils croient que pour avoir une réponse de leurs consultants, il faut et il suffit de mettre <strong>URGENT !</strong> dans l’objet du mail. Ils fixent un nombre considérable de rendez-vous par an mais ne savent ce que <a href="http://en.wikipedia.org/wiki/ICalendar">ce truc là, « .ics » leur serait utile</a>. Ils échangent leurs contacts avec un nombre considérable de gens mais ne savent pas que <a href="http://en.wikipedia.org/wiki/VCard">ce truc là, « .vcf »</a>, leur serait plus utile que leurs jolies cartes de visite qu’ils insèrent au format JPEG dans le corps de l’email</li>
<li>ils ne jurent que par Microsoft Word et ne savent pas que ce logiciel très sophistiqué a été inventé à une époque du « Personal Computer » sans l’internet. C’est à dire où on utilisait un ordinateur isolé comme machine à écrire de luxe pour pouvoir imprimer de manière sophistiquée sur du papier. Ils ne savent pas que depuis, le monde a bien échangé. Donc ils contiuent à utiliser Word.</li>
<li>ils ne savent pas <em>gérer leurs fichiers</em>. Leur bureau est un chaos sans nom, et il y a fort à parier que leurs données ne sont pas sauvegardées, ne serait-ce qu’en local avec TimeCapsule <strong>et</strong> dans <em>le cloud</em> avec Dropbox ou Google Drive</li>
<li>ils ne jurent que par <code>Skype</code>, ne savent pas qu’on a inventé beaucoup mieux depuis (ça c’est pas grave en soi) et si vous le leur expliquez, ils s’en foutent</li>
<li>alors qu’ils dépensent des fortunes pour des <em>iPhone</em> et des <em>smartphones Samsung Galaxy truc</em>, qui certes sont des produits excellents, mais <em>dont ils n’aucune utilité réelle</em>, en revanche si vous leur dites qu’ils feraient bien d’investir 50€ dans <a href="http://www.techsmith.com/snagit.html">un bête logiciel faisant des captures d’écran</a>, ce qui serait mille fois mieux que d’écrire leurs emails incompréhensibles, <strong>ils vont vous regarder comme un fou</strong>.</li>
</ul><p>…. j’arrête là car il y aurait énormément à dire…</p>
<p>le point essentiel est qu’ils <em>nous, vous prennent pour des fous</em>. Alors comme les <em>impressionnistes</em> et tant d’autres avant nous, <strong>il serait tant d’assumer la folie qu’ils nous reprochent… pusique après tout, la folie, sur internet, ça marche (tm)…</strong></p>
<h4 id="paraître-sérieux">Paraître sérieux</h4>
<p>Reconnaissons à ces gens là le fait qu’ils inspirent la confiance des clients (qu’ils abusent selon moi), que ce soit par leur apparence qui inspire le respect ou par leur capacité à tenir un discours qui là aussi inspire confiance.</p>
<p>Je ne m’étendrais pas longtemps là-dessus, une seule image suffit :</p>
<p><img src="//img.linuxfr.org/img/68747470733a2f2f7261772e6769746875622e636f6d2f696e7465726e616369756c6f2f656c6f67652d64652d6c612d666f6c69652f6d61737465722f6d656469612f636f6e73756c74616e742e6a7067/consultant.jpg" alt="la compétence du consultant" title="Source : https://raw.github.com/internaciulo/eloge-de-la-folie/master/media/consultant.jpg"></p>
<h4 id="avoir-fait-les-écoles-quil-faut">Avoir fait les écoles qu’il faut.</h4>
<p>Ces écoles sont nécessaires et parfois vraiment utiles, là n’est pas le problème. Le souci c’est que parmi les gens sortis de ces écoles, il y a non seulement des gens compétents mais aussi nombre de gens dont l’inculture informatique donne une idée de la taille de l’univers ; et qu’en dehors de ces écoles, il y a outre des gens évidemment eux aussi incompétents des autodidactes vraiment doués. Bref les diplômes de ces écoles là sont devenus <strong>titres de noblesse</strong>, ceux là même que la Révolution Française croyait avoir porti un coup décisif</p>
<p>Vous connaissez bien l’article premier ci-dessous, mais relisez aussi avec beaucoup d’attention le <em>préambule</em> qui l’accompagnait. Vous verrez que les révolutionnaires de 1789 étaient beaucoup moins <em>naïfs</em> qu’une étude superficielle ne le laisse penser.</p>
<p><a href="http://www.assemblee-nationale.fr/histoire/dudh/1789.asp">DÉCLARATION DES DROITS DE L’HOMME ET DU CITOYEN DE 1789</a></p>
<p><em>Les Représentants du Peuple Français, constitués en Assemblée nationale, considérant que l’ignorance, l’oubli ou le mépris des droits de l’homme sont les seules causes des malheurs publics et de la corruption des Gouvernements, ont résolu d’exposer, dans une Déclaration solennelle, les droits naturels, inaliénables et sacrés de l’homme, afin que cette Déclaration, constamment présente à tous les membres du corps social, leur rappelle sans cesse leurs droits et leurs devoirs ; afin que les actes du pouvoir législatif, et ceux du pouvoir exécutif pouvant être à chaque instant comparés avec le but de toute institution politique, en soient plus respectés ; afin que les réclamations des citoyens, fondées désormais sur des principes simples et incontestables, tournent toujours au maintien de la Constitution, et au bonheur de tous. En conséquence, l’Assemblée nationale reconnaît et déclare, en présence et sous les auspices de l’Être Suprême, les droits suivants de l’homme et du citoyen.</em></p>
<p><strong>Article premier</strong><br><em>Les hommes naissent et demeurent libres et égaux en droits.</em><br><em>Les distinctions sociales ne peuvent être fondées que sur l’utilité commune.</em></p>
<h3 id="mais-lexpérience-montre-que-seuls-les-fous-comprennent-vraiment-linternet">Mais l’expérience montre que seuls les fous comprennent vraiment l’Internet</h3>
<p>Mais au fond, peu importe ces gens là. Il suffit de savoir qu’il faut les éviter. Et pour cela il suffit de comprendre que <strong>sur Internet, il y a des vérités simples à comprendre, mais que très peu de gens comprennent vraiment</strong>. </p>
<p>Exemple :</p>
<ul>
<li>Que l’informatique au fond ce n’est pas compliqué, mais que par contre <strong>ça s’apprend !</strong>. Vous passez un permis de conduire avant de conduire une voiture, vous risquez même de le perdre si vous vous laissez aller après l’avoir obtenu. Et bien vous devriez vraiment en faire de même pour votre ordinateur ou « smartphone »). Les gens qui vous disent que <em>l’informatique, ça doit être intuitif !</em> sont soit des blaireaux qui se croient intelligents, soit des gens qui voient une opportunité commerciale à ce que vous ne compreniez pas cette vérité élémentaire.</li>
<li>
<a href="http://www.1000manifestos.com/google-ten-things-know-be-true/">10 thengs Google know to be true</a> (pas de commentaire de ma part, tout est bel et bien dit)</li>
<li>Windows est l’horizon absolument dépassable de l’informatique</li>
<li>Le logiciel libre, l’opensource, wikipédia, la culture libre, … y’a rien de plus sérieux</li>
<li>Avoir un respect profond des utilisateurs même si aujourd’hui ils sont faciles à abuser est la condition numéro un du succès</li>
<li>La condition 2 est de comprendre que se passer du feedback des utilisateurs de son logiciel (avec des outils adaptés comme <a href="https://www.uservoice.com/">https://www.uservoice.com/</a> ) est une faute professionnel lourde</li>
<li>La condition 3 est de comprendre qu’il y a des gens <em>nettement plus intelligents</em> que nous qui ont inventé des choses qu’on aurait jamais pu inventer soi-même ; et qu’au lieu de l’ignorer ou de s’en lamenter, il <strong>faut</strong> bâtir ses outils propres outils sur les outils de ces gens là. Qu’en fait ce n’est pas nouveau, tous les gens intelligents sont <a href="http://fr.wikipedia.org/wiki/Des%20nains%20sur%20des%20%C3%A9paules%20de%20g%C3%A9ants" title="Définition Wikipédia">Des nains sur des épaules de géants</a>
</li>
<li>La condition 4 est de comprendre que le gratuit sur internet doit avoir toute sa place (considérable) mais rien que sa place. Refuser de payer une somme tout à fait raisonnables pour des services éminemment utiles est une connerie sans nom. Une connerie qui vous coûtera tôt ou tard un prix considérable. À la fois d’un point de vue strictement monétaire mais également en nombre d’heures qui auraient pu être employées à des choses nettement plus importantes. Une connerie qui aura même souvent un coût inestimable : perdre toutes ses donénes, photos, documents, souvenirs … totalement irremplaçables.</li>
</ul><h3 id="brain-storming-collectif--qui-sont-les-fous-majeurs-qui-ont-fait-dinternet-ce-quil-est-devenu">Brain storming collectif : qui sont les fous majeurs qui ont fait d’internet ce qu’il est devenu ?</h3>
<p>Et c’est là que j’aurais besoin de ton pouvoir de brain-storming collaboratif. Établissons ensemble la liste des gens qui ont eu un impact réel sur ce qu’est devenu l’internet aujourd’hui. </p>
<p><strong>But de ce travail collectif :</strong></p>
<p>Mon pari est que la très grande majorité de ces personnes là sont des OVNIs comparés aux « professionnels de l’informatique en France » sus-cités. Les professionnels sérieux de l’informatique en connaissent une partie (mais seulement une partie) et s’ils comprenaient <em>vraiment</em> pourquoi ces gens là, <strong>férocement anti-conformistes</strong> (c’est <em>ça</em> à mon avis <em>LE</em> point commun entre ces gens par ailleurs si différents) ont eu néanmoins un impact considérable sur ce qu’est devenu l’informatique aujourd’hui, et bien ils auraient compris depuis longtemps des choses évidentes pour les fous comme nous mais extrêmement bizarre pour eux. Et donc ils ne seraient plus depuis longtemps des « professionnels sérieux de l’informatique ».</p>
<p>Donc j’ai commencé une petite liste. Prière de ne pas confondre deux questions : </p>
<ol>
<li>est-ce que vous adulez ou haissez les gens en question, et ce pour d’excellentes raisons ? (Steve Jobs ou RMS par exemple, il y a d’excellentes raisons de les détester <em>et</em> de les aduler. Mais en fait on s’en fout, cf point suivant).</li>
<li> est-ce que ces gens ont eu un impact considérable sur ce qu’est devenu l’internet aujourd’hui ? Si oui, il est plus que probable qu’il y a énormément à apprendre d’eux</li>
</ol><h3 id="Ébauche-de-liste-proprement-dite">Ébauche de liste proprement dite</h3>
<h4 id="les-personnalités-de-linternet-et-du-web">Les personnalités de l’Internet et du Web</h4>
<ul>
<li>Tim Berners-Lee</li>
<li>Robert Cailliau</li>
<li>Vinton G. Cerf</li>
<li>David Clark</li>
<li>Leonard Kleinrock</li>
<li>Paul Kunz</li>
<li>Paul Mockapetris</li>
<li>Bruno Oudet</li>
<li>Jon Postel</li>
<li><a href="https://github.com/internaciulo/eloge-de-la-folie">Qui d’autre ???</a></li>
</ul><h4 id="les-stars-de-la-programmation">Les stars de la programmation</h4>
<ul>
<li>John Backus</li>
<li>Haskell Curry</li>
<li>Ole-Johan Dahl</li>
<li>James Gosling</li>
<li> Jean Ichbiah</li>
<li>Brian Kernighan</li>
<li>Donald Knuth</li>
<li>Rasmus Lerdorf</li>
<li>Ada Lovelace</li>
<li>Peter Naur</li>
<li>John Ousterhout</li>
<li>Dennis Ritchie</li>
<li>Guido van Rossum</li>
<li>Alexander Stepanov</li>
<li>Bjarne Stroustrup</li>
<li>Niklaus Wirth</li>
<li><a href="https://github.com/internaciulo/eloge-de-la-folie">Qui d’autre ???</a></li>
</ul><h3 id="googlers">Googlers</h3>
<p>Je me suis aidé de <a href="http://www.businessinsider.com/a-googlers-guide-to-the-10-most-powerful-googlers-under-new-ceo-larry-page-2011-1?op=1">ceci</a> et si j’avais eu le courage, j’aurais du extraire la substantifique moelle de <a href="http://en.wikipedia.org/wiki/Category:Google_employees">cela</a></p>
<ul>
<li>Larry Page</li>
<li>Eric Schmidt</li>
<li>Sergey Brin</li>
<li>Jonathan Rosenberg</li>
<li>Alan Eustace</li>
<li>Bill Coughran</li>
<li>Patrick Pitchette</li>
<li>Marissa Mayer</li>
<li>Susan Wojcickci</li>
<li>Chris DiBona</li>
</ul><h3 id="voices-of-the-opensource-revolution">Voices of the OpenSource revolution</h3>
<ul>
<li>Eben Moglen</li>
<li>Eric Raymond </li>
<li>Jimmy Wales</li>
<li>Larry Wall </li>
<li>Lawrence Lessig</li>
<li>Linus Torvalds </li>
<li>Matthias Ettrich</li>
<li>Miguel de Icaza</li>
<li>Richard Stallman</li>
<li>Yukihiro Matsumoto</li>
<li>extraire la substantifique moelle de <a href="http://fr.wikipedia.org/wiki/:Cat%C3%A9gorie:Personnalit%C3%A9%20en%20informatique%20dans%20le%20domaine%20du%20libre" title="Définition Wikipédia">:Catégorie:Personnalité en informatique dans le domaine du libre</a>
</li>
<li><a href="https://github.com/internaciulo/eloge-de-la-folie">Qui d’autre ???</a></li>
</ul><h4 id="apple-inc">Apple Inc.</h4>
<ul>
<li>Steve Jobs</li>
<li>Steve Wozniack</li>
<li>ces deux là sont incontournables (ni l’un ni l’autre n’aurait jamais pu fonder Apple Inc à lui tout seul), mais il faudrait aussi éplucher <a href="http://fr.wikipedia.org/wiki/Cat%C3%A9gorie:Personnalit%C3%A9_d'Apple_Inc.">Personnalité d'Apple Inc.</a>
</li>
<li><a href="https://github.com/internaciulo/eloge-de-la-folie">Qui d’autre ???</a></li>
</ul><h4 id="autres-personnalités-ayant-fondé-des-sites-majeurs">Autres personnalités ayant fondé des sites majeurs</h4>
<ul>
<li>Joël Spolsky, qu’on remerciera vraiment d’avoir quitté eu l’excellente idée Microsoft après y avoir fait des choses utiles. (Diable, Wikipédia ne sait pas qu’il a créé Trello ??)</li>
<li>Jeff Atwood</li>
<li>les types derrière github (??)</li>
<li>Fabien Penso et ceux qui ont pris la relève ensuite ;-)</li>
<li><a href="https://github.com/internaciulo/eloge-de-la-folie">Qui d’autre ???</a></li>
</ul><h3 id="simples-particuliers-qui-utilisent-internet-de-manière-particulièrement-intelligente">Simples particuliers qui utilisent Internet de manière particulièrement intelligente</h3>
<ul>
<li>Leo Balbuta de <a href="http://zenhabits.net/">http://zenhabits.net/</a>
</li>
<li>Valentina Lisitsa, la pianiste qui triomphe sur YouTube <a href="http://www.youtube.com/user/ValentinaLisitsa">http://www.youtube.com/user/ValentinaLisitsa</a>
</li>
<li>Benny Lewis de <a href="http://speakfromday1.com/">http://speakfromday1.com/</a> et <a href="http://www.fluentin3months.com/">http://www.fluentin3months.com/</a>
</li>
<li><a href="https://github.com/internaciulo/eloge-de-la-folie">Qui d’autre ???</a></li>
</ul><p>Merci cher journal de ta <a href="https://github.com/internaciulo/eloge-de-la-folie">participation</a>, elle sera appréciée à sa juste valeur</p><div><a href="https://linuxfr.org/users/jean-michel-bertrou-eu/journaux/seuls-les-fous-comprennent-quelques-chose-a-l-internet.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/99578/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/jean-michel-bertrou-eu/journaux/seuls-les-fous-comprennent-quelques-chose-a-l-internet#comments">ouvrir dans le navigateur</a>
</p>
jean-michel.bertrou.euhttps://linuxfr.org/nodes/99578/comments.atomtag:linuxfr.org,2005:Diary/331972012-10-02T15:41:35+02:002012-10-02T15:41:35+02:00Un papier révolutionnaire!<p>Au hasard d'internet, je suis tombé sur un papier révolutionnaire. Il est malheureusement en anglais, mais cela ne nuit pas à sa compréhension. C'est un peu long, mais c'est vraiment un document de premier ordre.</p>
<pre>
<code class=""> A Case for Access Points
</code>
</pre>
<p>Richard Matthew Stallman, kernighan ritchie, Ken Ritchie, Linus Torvalds and Edsger Dijkstra</p>
<p>Abstract</p>
<p>Unified psychoacoustic algorithms have led to many private advances, including the lookaside buffer and vacuum tubes [13]. After years of theoretical research into agents, we disprove the refinement of the transistor, which embodies the private principles of theory. Our focus in this work is not on whether rasterization and consistent hashing can agree to overcome this issue, but rather on proposing an analysis of forward-error correction (IlkAntlia).<br />
Table of Contents</p>
<p>1) Introduction<br />
2) Related Work<br />
2.1) Multimodal Symmetries<br />
2.2) Peer-to-Peer Communication<br />
3) Framework<br />
4) Implementation<br />
5) Evaluation<br />
5.1) Hardware and Software Configuration<br />
5.2) Experiments and Results<br />
6) Conclusion<br />
1 Introduction</p>
<p>The analysis of the Internet is a significant obstacle [32]. Given the current status of certifiable information, cryptographers daringly desire the investigation of access points, which embodies the practical principles of e-voting technology [20]. Along these same lines, we view operating systems as following a cycle of four phases: creation, deployment, investigation, and improvement. As a result, large-scale technology and simulated annealing have paved the way for the exploration of checksums.</p>
<p>In order to achieve this ambition, we use certifiable symmetries to show that courseware and A* search are mostly incompatible. Two properties make this method distinct: IlkAntlia prevents kernels, and also our methodology stores the construction of consistent hashing. The drawback of this type of approach, however, is that the transistor can be made highly-available, secure, and robust. Certainly, our approach creates unstable models. We view networking as following a cycle of four phases: investigation, exploration, provision, and construction. Contrarily, this approach is rarely bad.</p>
<p>In this paper, we make four main contributions. We confirm that A* search and hierarchical databases can agree to overcome this quagmire. Furthermore, we disconfirm not only that checksums and digital-to-analog converters [37] are often incompatible, but that the same is true for compilers [32]. Furthermore, we concentrate our efforts on disconfirming that redundancy and IPv4 can cooperate to answer this problem [7]. Lastly, we verify that the well-known extensible algorithm for the evaluation of reinforcement learning by Taylor et al. [26] is impossible.</p>
<p>We proceed as follows. We motivate the need for model checking. To achieve this purpose, we construct a "smart" tool for constructing Scheme (IlkAntlia), which we use to verify that consistent hashing can be made authenticated, knowledge-based, and linear-time. In the end, we conclude.</p>
<p>2 Related Work</p>
<p>We now compare our solution to existing peer-to-peer epistemologies solutions [4,35,12,6,2]. The infamous system by Anderson [16] does not develop metamorphic epistemologies as well as our approach [3]. Similarly, recent work by Zhao and White suggests an application for requesting semaphores, but does not offer an implementation [24]. These methods typically require that suffix trees and replication are rarely incompatible [30], and we verified in this work that this, indeed, is the case.</p>
<p>2.1 Multimodal Symmetries</p>
<p>The concept of extensible methodologies has been harnessed before in the literature [39,27,2]. Though Adi Shamir also proposed this approach, we visualized it independently and simultaneously [38]. Along these same lines, unlike many previous methods [21], we do not attempt to allow or emulate extensible theory. Kumar [38] originally articulated the need for the Ethernet [18,11,15]. This solution is more fragile than ours. Brown et al. originally articulated the need for collaborative modalities [1,33,19,22,31]. The only other noteworthy work in this area suffers from fair assumptions about XML [34]. All of these methods conflict with our assumption that Byzantine fault tolerance and modular algorithms are structured [5,17,3,16,28]. IlkAntlia represents a significant advance above this work.</p>
<p>2.2 Peer-to-Peer Communication</p>
<p>Several concurrent and ambimorphic systems have been proposed in the literature. A recent unpublished undergraduate dissertation constructed a similar idea for wearable algorithms [25]. Further, a recent unpublished undergraduate dissertation [36] motivated a similar idea for robust archetypes [14]. Finally, the algorithm of Robinson [23] is a confirmed choice for randomized algorithms.</p>
<p>3 Framework</p>
<p>Suppose that there exists knowledge-based theory such that we can easily enable online algorithms. This may or may not actually hold in reality. IlkAntlia does not require such a technical simulation to run correctly, but it doesn't hurt. On a similar note, despite the results by P. Moore et al., we can demonstrate that the famous "fuzzy" algorithm for the investigation of operating systems by Martin and Jones [9] is in Co-NP. We postulate that IPv7 and superpages can collude to solve this quagmire. Despite the results by Zheng et al., we can disprove that the seminal lossless algorithm for the evaluation of the Ethernet runs in Ω( log n ) time.</p>
<p>
<a href="http://apps.pdos.lcs.mit.edu/scicache/87/dia0.png">http://apps.pdos.lcs.mit.edu/scicache/87/dia0.png</a>
</p>
<p>Figure 1: Our heuristic emulates the emulation of e-business in the manner detailed above.</p>
<p>Reality aside, we would like to study a framework for how our application might behave in theory. This follows from the construction of model checking. Figure 1 diagrams the relationship between our solution and write-back caches. This may or may not actually hold in reality. Consider the early framework by Nehru et al.; our model is similar, but will actually fulfill this purpose. We use our previously visualized results as a basis for all of these assumptions.</p>
<p>Further, we assume that the study of hash tables can develop collaborative algorithms without needing to cache the Internet. Along these same lines, any confusing study of multimodal technology will clearly require that RAID can be made large-scale, interactive, and electronic; our system is no different [10]. The question is, will IlkAntlia satisfy all of these assumptions? Absolutely.</p>
<p>4 Implementation</p>
<p>Though many skeptics said it couldn't be done (most notably Thomas and Sato), we construct a fully-working version of our system. We have not yet implemented the collection of shell scripts, as this is the least technical component of IlkAntlia. We have not yet implemented the homegrown database, as this is the least essential component of IlkAntlia [8]. Overall, our approach adds only modest overhead and complexity to existing autonomous methodologies.</p>
<p>5 Evaluation</p>
<p>We now discuss our evaluation strategy. Our overall evaluation strategy seeks to prove three hypotheses: (1) that 10th-percentile work factor stayed constant across successive generations of Commodore 64s; (2) that the LISP machine of yesteryear actually exhibits better popularity of expert systems than today's hardware; and finally (3) that RAM speed is not as important as a system's historical user-kernel boundary when maximizing signal-to-noise ratio. An astute reader would now infer that for obvious reasons, we have intentionally neglected to improve expected seek time. It might seem perverse but is buffetted by previous work in the field. We hope that this section proves to the reader the work of Canadian analyst Maurice V. Wilkes.</p>
<p>5.1 Hardware and Software Configuration</p>
<p>
<a href="http://apps.pdos.lcs.mit.edu/scicache/87/figure0.png">http://apps.pdos.lcs.mit.edu/scicache/87/figure0.png</a>
</p>
<p>Figure 2: The expected power of our application, as a function of seek time.</p>
<p>Though many elide important experimental details, we provide them here in gory detail. We scripted a deployment on our desktop machines to quantify the opportunistically event-driven nature of wearable configurations. We removed more ROM from our pseudorandom cluster to quantify topologically atomic epistemologies's inability to effect the work of Russian algorithmist K. Bhabha. Configurations without this modification showed improved mean hit ratio. Similarly, we removed 7 CISC processors from Intel's mobile telephones. We removed 3 25MHz Intel 386s from our system to measure Hector Garcia-Molina's improvement of courseware in 1967. Furthermore, we removed 25Gb/s of Internet access from our decommissioned Apple Newtons to understand epistemologies. Note that only experiments on our 1000-node overlay network (and not on our system) followed this pattern.</p>
<p>
<a href="http://apps.pdos.lcs.mit.edu/scicache/87/figure1.png">http://apps.pdos.lcs.mit.edu/scicache/87/figure1.png</a>
</p>
<p>Figure 3: The effective bandwidth of our algorithm, compared with the other methodologies.</p>
<p>We ran our solution on commodity operating systems, such as Multics and KeyKOS Version 0.7.3, Service Pack 7. all software components were linked using AT&T System V's compiler built on the Soviet toolkit for provably visualizing consistent hashing. We implemented our the lookaside buffer server in Dylan, augmented with collectively topologically Bayesian extensions. Second, we implemented our IPv4 server in Smalltalk, augmented with collectively computationally wireless extensions. All of these techniques are of interesting historical significance; R. Tarjan and X. Jones investigated a similar heuristic in 1999.</p>
<p>5.2 Experiments and Results</p>
<p>Is it possible to justify having paid little attention to our implementation and experimental setup? Unlikely. Seizing upon this ideal configuration, we ran four novel experiments: (1) we deployed 48 Motorola bag telephones across the Internet-2 network, and tested our kernels accordingly; (2) we deployed 45 Apple Newtons across the Internet network, and tested our local-area networks accordingly; (3) we ran SCSI disks on 64 nodes spread throughout the 100-node network, and compared them against online algorithms running locally; and (4) we measured tape drive throughput as a function of flash-memory space on an IBM PC Junior [29]. All of these experiments completed without access-link congestion or paging.</p>
<p>Now for the climactic analysis of the second half of our experiments. We scarcely anticipated how wildly inaccurate our results were in this phase of the evaluation approach. Error bars have been elided, since most of our data points fell outside of 45 standard deviations from observed means. Third, the many discontinuities in the graphs point to improved distance introduced with our hardware upgrades.</p>
<p>Shown in Figure 3, experiments (3) and (4) enumerated above call attention to our application's distance. Note the heavy tail on the CDF in Figure 3, exhibiting weakened expected latency. Continuing with this rationale, the key to Figure 2 is closing the feedback loop; Figure 3 shows how IlkAntlia's USB key space does not converge otherwise. Along these same lines, note the heavy tail on the CDF in Figure 2, exhibiting amplified popularity of compilers.</p>
<p>Lastly, we discuss experiments (1) and (3) enumerated above. Note that robots have less discretized seek time curves than do distributed spreadsheets. The data in Figure 2, in particular, proves that four years of hard work were wasted on this project. Note that Figure 3 shows the median and not average randomized effective tape drive speed.</p>
<p>6 Conclusion</p>
<p>In conclusion, in this paper we showed that redundancy can be made symbiotic, distributed, and interactive. We validated not only that semaphores can be made virtual, read-write, and heterogeneous, but that the same is true for the UNIVAC computer. Our algorithm cannot successfully cache many hash tables at once. In fact, the main contribution of our work is that we described a heuristic for the simulation of DHCP (IlkAntlia), disproving that the memory bus and massive multiplayer online role-playing games can synchronize to answer this issue. On a similar note, we showed that complexity in our system is not a problem. Such a claim might seem perverse but has ample historical precedence. We expect to see many physicists move to harnessing our algorithm in the very near future.</p>
<p>References</p>
<p>[1]<br />
Bachman, C. Agents considered harmful. In Proceedings of PODS (Oct. 1994).</p>
<p>[2]<br />
Backus, J. Simulating RPCs and journaling file systems. In Proceedings of SOSP (Sept. 2005).</p>
<p>[3]<br />
Bhabha, H., and Dahl, O. The impact of stochastic algorithms on networking. Journal of "Fuzzy", Symbiotic Algorithms 284 (May 1999), 150-197.</p>
<p>[4]<br />
Brooks, R. Investigating erasure coding and rasterization. Journal of Certifiable, Random Epistemologies 80 (Mar. 2003), 79-87.</p>
<p>[5]<br />
Brown, G., and Taylor, Q. The relationship between architecture and hash tables. In Proceedings of SIGMETRICS (Nov. 2004).</p>
<p>[6]<br />
Darwin, C., and Milner, R. PinocleNorie: Modular algorithms. In Proceedings of OSDI (Oct. 2005).</p>
<p>[7]<br />
Daubechies, I., Shamir, A., and Thompson, K. a. Decoupling Boolean logic from IPv6 in gigabit switches. In Proceedings of the Conference on Real-Time, Relational Models (May 2002).</p>
<p>[8]<br />
ErdÖS, P. BugledHotel: A methodology for the refinement of write-ahead logging. Journal of Peer-to-Peer, Knowledge-Based, Wearable Configurations 75 (Jan. 2003), 77-88.</p>
<p>[9]<br />
ErdÖS, P., and Jacobson, V. Systems considered harmful. Journal of Real-Time Symmetries 8 (July 2002), 72-96.</p>
<p>[10]<br />
Feigenbaum, E., Thompson, P. H., and Takahashi, J. The impact of signed symmetries on electrical engineering. In Proceedings of NDSS (June 2004).</p>
<p>[11]<br />
Gayson, M., and Zheng, N. The relationship between Boolean logic and redundancy. IEEE JSAC 47 (Oct. 2002), 20-24.</p>
<p>[12]<br />
Hartmanis, J., and Torvalds, L. The influence of robust methodologies on robotics. Journal of Omniscient, Interposable Theory 52 (Dec. 1995), 20-24.</p>
<p>[13]<br />
Hopcroft, J. The relationship between symmetric encryption and write-back caches. In Proceedings of the Symposium on Stochastic, Ubiquitous Algorithms (Nov. 2000).</p>
<p>[14]<br />
Johnson, N., Ullman, J., and Watanabe, C. Comparing SCSI disks and scatter/gather I/O. Journal of Extensible, Event-Driven Models 35 (Mar. 1999), 157-195.</p>
<p>[15]<br />
Kaashoek, M. F. An emulation of DHTs using OngoingFinback. In Proceedings of the Conference on Collaborative Communication (Oct. 1992).</p>
<p>[16]<br />
Kaashoek, M. F., and Moore, K. Exploring journaling file systems using extensible theory. In Proceedings of the Conference on Stochastic, Distributed Models (Sept. 2003).</p>
<p>[17]<br />
kernighan ritchie, and Chomsky, N. Randomized algorithms considered harmful. In Proceedings of the Workshop on Decentralized Theory (Oct. 1991).</p>
<p>[18]<br />
Knuth, D., Tanenbaum, A., and Fredrick P. Brooks, J. On the synthesis of the transistor. Tech. Rep. 32-991, UCSD, Feb. 2001.</p>
<p>[19]<br />
Kubiatowicz, J., Wilson, Y. S., Hennessy, J., and Adleman, L. Deploying active networks and symmetric encryption. In Proceedings of the Conference on Decentralized, Authenticated Configurations (Sept. 2003).</p>
<p>[20]<br />
Lakshminarayanan, K. Deconstructing redundancy. Journal of Introspective, Extensible Configurations 52 (Apr. 2003), 155-199.</p>
<p>[21]<br />
Lamport, L. Autonomous, reliable, optimal epistemologies for checksums. In Proceedings of the Conference on Trainable, Peer-to-Peer Symmetries (Jan. 1992).</p>
<p>[22]<br />
Lampson, B., and Garcia, U. The impact of concurrent theory on robotics. In Proceedings of HPCA (Oct. 2002).</p>
<p>[23]<br />
Lee, B. A case for superpages. In Proceedings of NSDI (Nov. 2003).</p>
<p>[24]<br />
Leiserson, C., ErdÖS, P., Ritchie, K., Yao, A., and Karp, R. Study of linked lists. Tech. Rep. 402-86, Stanford University, Sept. 1999.</p>
<p>[25]<br />
Martin, a. Wearable models for scatter/gather I/O. In Proceedings of the Symposium on Decentralized, Psychoacoustic Communication (Jan. 2002).</p>
<p>[26]<br />
Martinez, Y., and Jones, R. The effect of perfect epistemologies on artificial intelligence. In Proceedings of MICRO (June 2002).</p>
<p>[27]<br />
Maruyama, L. Q. HugeWadset: Adaptive, certifiable theory. In Proceedings of VLDB (Apr. 1998).</p>
<p>[28]<br />
Nehru, R., and Smith, J. Low-energy, wireless symmetries for architecture. Journal of Cacheable Theory 70 (Aug. 2004), 47-53.</p>
<p>[29]<br />
Nygaard, K., and Takahashi, O. Comparing red-black trees and the UNIVAC computer with YOM. Journal of Pervasive, Peer-to-Peer Methodologies 27 (June 1991), 1-13.</p>
<p>[30]<br />
Perlis, A. Simulating 2 bit architectures using knowledge-based methodologies. Journal of Lossless, Autonomous Symmetries 73 (Aug. 2003), 157-195.</p>
<p>[31]<br />
Quinlan, J. Quaigh: Investigation of semaphores. NTT Technical Review 91 (Nov. 2005), 45-51.</p>
<p>[32]<br />
Robinson, D. D., and Reddy, R. A case for Moore's Law. Journal of Secure, "Fuzzy" Algorithms 70 (Nov. 2004), 70-89.</p>
<p>[33]<br />
Smith, U., Maruyama, W., and Thompson, J. Comparing active networks and wide-area networks. In Proceedings of MICRO (Mar. 1967).</p>
<p>[34]<br />
Subramanian, L., Watanabe, M., and Knuth, D. Towards the deployment of RPCs. In Proceedings of MOBICOM (Nov. 1997).</p>
<p>[35]<br />
Sun, M. On the study of Lamport clocks. In Proceedings of the Symposium on Read-Write, Introspective, Linear- Time Symmetries (Aug. 2000).</p>
<p>[36]<br />
Takahashi, D. Investigation of context-free grammar. In Proceedings of the Workshop on Autonomous, "Smart" Models (Nov. 1996).</p>
<p>[37]<br />
White, V., and Clark, D. Towards the investigation of local-area networks. In Proceedings of NSDI (Apr. 2002).</p>
<p>[38]<br />
Wilkinson, J. Tydy: A methodology for the study of lambda calculus. Tech. Rep. 9941, UC Berkeley, Sept. 2003.</p>
<p>[39]<br />
Williams, N., and Dongarra, J. FILL: A methodology for the synthesis of vacuum tubes. In Proceedings of MICRO (May 2005).</p><div><a href="https://linuxfr.org/users/octane/journaux/un-papier-revolutionnaire.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/95828/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/octane/journaux/un-papier-revolutionnaire#comments">ouvrir dans le navigateur</a>
</p>
octanehttps://linuxfr.org/nodes/95828/comments.atomtag:linuxfr.org,2005:News/332022012-08-07T11:20:29+02:002012-09-12T21:15:17+02:00À la recherche des sources de TroffLicence CC By‑SA http://creativecommons.org/licenses/by-sa/3.0/deed.fr<div><p>Troff est le logiciel de formatage de texte des Unix originaux. Il est toujours présent sur nos machines en sa version GNU (Groff) même s'il ne sert généralement qu'à afficher nos pages de manuel. </p>
<p><a href="http://fr.wikipedia.org/wiki/Eric_Raymond">Eric Raymond</a> n'hésite pas à dire que Troff est « l'application originale Unix qui tue tout » (<em>Unix's original killer application</em>, cf. <a href="http://www.faqs.org/docs/artu/ch08s02.html#id2934197"><em>The Art of Unix Programming</em></a>), non seulement parce qu'il s'associe à différents interpréteurs et tire le meilleur profit des tubes et de la philosophie Unix, mais aussi parce que l'efficacité du logiciel a favorisé l'adoption d'Unix par le département des brevets de Bell labs, et ensuite au-delà.</p>
<p>S'il était largement utilisé dans les années 80, Troff est aujourd'hui tombé dans l'oubli, et semble peu à peu disparaître de l'Internet. Pourtant, en cherchant bien, on retrouve de nombreuses traces de la vivacité passée de Troff. </p>
<p>Ces traces sont exhumées en seconde partie de la dépêche.</p></div><ul><li>lien nᵒ 1 : <a title="http://www.tuhs.org/Archive/PDP-11/Distributions/research/1972_stuff/s2-bits.gz" hreflang="en" href="https://linuxfr.org/redirect/82929">binaire du roff original</a></li><li>lien nᵒ 2 : <a title="http://www.tuhs.org/Archive/PDP-11/Distributions/research/Dennis_v6/v6src.tar.gz" hreflang="en" href="https://linuxfr.org/redirect/82930">sources du premier nroff</a></li><li>lien nᵒ 3 : <a title="http://www2.research.att.com/~gsf/cgi-bin/download.cgi?action=list&name=dwb" hreflang="en" href="https://linuxfr.org/redirect/82931">troff d'AT&T</a></li><li>lien nᵒ 4 : <a title="http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/" hreflang="en" href="https://linuxfr.org/redirect/82932">troff de Solaris</a></li><li>lien nᵒ 5 : <a title="http://heirloom.sourceforge.net/doctools.html" hreflang="en" href="https://linuxfr.org/redirect/82933">troff du projet Heirloom</a></li><li>lien nᵒ 6 : <a title="http://swtch.com/plan9port/" hreflang="en" href="https://linuxfr.org/redirect/82934">troff de plan9port</a></li></ul><div><h2 id="sommaire">Sommaire</h2>
<ul><li>
<a href="#toc_0">L'histoire des sources </a>
<ul><li>
<a href="#toc_1">Roff de Joseph Ossana sur les premiers Unix</a>
</li>
<li>
<a href="#toc_2">New Roff</a>
</li>
<li>
<a href="#toc_3">Ditroff de Kernighan</a>
</li>
<li>
<a href="#toc_4">DWB d'AT&T</a>
</li>
<li>
<a href="#toc_5">Troff de Solaris</a>
</li>
<li>
<a href="#toc_6">Heirloom Troff, de Gunnar Ritter</a>
</li>
<li>
<a href="#toc_7">Troff de Plan9</a>
</li>
</ul></li>
<li>
<a href="#toc_8">Documentation de troff et de ses compagnons</a>
</li>
<li>
<a href="#toc_9">Logiciels accompagnant Troff</a>
<ul><li>
<a href="#toc_10">Mpm : pour la justification verticale</a>
</li>
<li>
<a href="#toc_11">Picasso : pour dessiner</a>
</li>
<li>
<a href="#toc_12">Troff et le HTML</a>
</li>
<li>
<a href="#toc_13">Troff et le XML</a>
</li>
<li>
<a href="#toc_14">Références et index</a>
</li>
<li>
<a href="#toc_15">Développement logiciel</a>
</li>
<li>
<a href="#toc_16">Présentations scientifiques</a>
</li>
<li>
<a href="#toc_17">Macro diverses</a>
</li>
</ul></li>
<li>
<a href="#toc_18">Pourquoi cette dépêche ?</a>
<ul><li>
<a href="#toc_19">Réflexion sur l'histoire à l'âge de l'Internet</a>
</li>
<li>
<a href="#toc_20">Réflexion sur le langage à l'âge de l'image</a>
</li>
</ul></li>
</ul><p>N.B.: les liens vers le site de Bell Labs sont actuellement morts, mais cela arrive parfois et n'est jusqu'alors que provisoire.</p>
<h2 id="toc_0">L'histoire des sources </h2>
<p>Un <a href="http://linuxfr.org/news/groff-sort-en-version-121">rapide historique</a> de Troff a été proposé ici même à l'occasion de la sortie d'une nouvelle version de son équivalent GNU : <strong>Groff</strong>. Ici, nous insisterons sur les traces de cette histoire telles qu'elles sont présentes aujourd'hui sur internet, ainsi que sur la façon dont elles nous sont parvenues, car les sources du logiciel n'ont pas toujours été partagées. </p>
<h3 id="toc_1">Roff de Joseph Ossana sur les premiers Unix</h3>
<blockquote>
<p>Dear Unix Enthousiasts,</p>
</blockquote>
<p>C'est avec cette formule, que, en 2002, <a href="http://fr.wikipedia.org/wiki/SCO_Group">Caldera</a> ouvre le texte de la <a href="http://www.tuhs.org/Archive/Caldera-license.pdf">licence</a> annonçant la <a href="http://tech.slashdot.org/article.pl?sid=02/01/24/0146248">libération</a> des sources des anciens outils Unix en même temps qu'elle <a href="http://linuxfr.org//2002/01/24/6820.html">libère</a> le code source original d'<a href="http://cm.bell-labs.com/cm/cs/who/dmr/complinks.html">Unix</a> lui-même. </p>
<p>Dans l'archive de la <a href="http://www.tuhs.org/Archive/PDP-11/Distributions/research/1972_stuff/s2-bits.gz">version 3</a> des <a href="http://www.tuhs.org/Archive/PDP-11/Distributions/research/">premiers Unix</a> on trouve une version binaire de roff dans datée de 1972. Cette version binaire est en la ré-écriture pour Unix, par <a href="http://fr.wikipedia.org/wiki/Joseph_Ossanna">Joseph Ossanna</a>, du RunOff de Multics. </p>
<h3 id="toc_2">New Roff</h3>
<p>Joseph Ossana a ensuite amélioré Roff, et l'a renommé Nroff (New Roff). Nroff est probablement une ré-écriture en C de Roff. On trouve les sources, tant de Roff que de Nroff dans la <a href="http://www.tuhs.org/Archive/PDP-11/Distributions/research/Dennis_v6/v6src.tar.gz">Version 6</a> d'Unix. Une recherche dans les sources d'<a href="http://www.tuhs.org/Archive/PDP-11/Distributions/usdl/">Unix 32V</a> devrait permettre de suivre l'évolution du code source. </p>
<h3 id="toc_3">Ditroff de Kernighan</h3>
<p>En 1979, <a href="http://fr.wikipedia.org/wiki/Brian_Kernighan">Brian Kernighan</a>, ré-écrit entièrement Nroff, pour qu'il produise une sortie intermédiaire, qui devra être traitée par un autre logiciel pour finalement produire un fichier imprimable. Cette sortie intermédiaire permet à Nroff d'être utilisé pour divers types d'imprimantes, incompatibles entre elles. Il nomme ce nouveau logiciel <a href="http://www.darwinsys.com/history/hist.html">Ditroff</a>, « <em>device independant troff</em> », mais ce nom sera abandonné au profit de Troff. L'usage a imposé le nom <em>Nroff</em> pour logiciel utilisé pour écrire sur un terminal, et celui de <em>Troff</em> pour le logiciel produisant du texte destiné à être imprimé. </p>
<p>Depuis 1979, les logiciels Troff et Nroff, quelle que soit leur origine, reproduisent le comportement du Troff de Kernighan. La compatibilité entre toutes les versions est ainsi assurée, à quelques détails près. La documentation en usage est d'ailleurs celle qu'a écrit Kernighan à la même époque. Cela fait probablement du format de Troff le format de traitement de texte qui est, de fait, le plus pérenne de l'histoire de l'informatique. </p>
<h3 id="toc_4">DWB d'AT&T</h3>
<p>Le Troff de Kernighan a eu de nombreux descendants, en particulier, il a été le cœur d'un ensemble de logiciels nommé DWB (<em>Documenter's WorkBench</em>) distribués avec l'Unix d'AT&T. En cherchant bien, on peut trouver, sous licence <a href="http://www.eclipse.org/org/documents/epl-v10.php">Eclipse</a>, les sources du <a href="http://www2.research.att.com/~gsf/cgi-bin/download.cgi?action=list&name=dwb">DWB 3.2 d'AT&T</a> de 1993 (et un <a href="http://cyrillelefevre.free.fr/dwb/dwb.1993-02-04.patch.bz2">patch</a> pour le compiler dans Cygwin). </p>
<p>Certains navigateurs ayant quelques difficultés à télécharger le DWB d'AT&T, voici comment faire avec Wget, sous réserve d'acceptation de la licence: </p>
<pre>
<code class="bash">wget <span class="se">\</span>
--user <span class="s2">"I accept www.opensource.org/licenses/eclipse"</span> <span class="se">\</span>
--password <span class="s2">"."</span> <span class="se">\</span>
<span class="s2">"http://www2.research.att.com/~gsf/download/tgz/dwb.1993-02-04.tgz"</span>
</code>
</pre>
<p>Cette archive est une perle, car elle contient, outre les sources de Troff, les sources de toute la documentation, ainsi que quelques logiciels que beaucoup croient perdus, tels <strong>Picasso</strong> et <strong>Diffmk</strong>, dont il sera question plus loin. </p>
<h3 id="toc_5">Troff de Solaris</h3>
<p>En 2005, Solaris, le descendant d'Unix Systeme V dévoilé par AT&T en 1983, est <a href="http://linuxfr.org//2005/01/26/18184.html">libéré</a>, à son tour ainsi que le code des outils Unix de l'époque. Le tout est distribué sous licence <a href="http://opensource.org/licenses/cddl1.php">CDDL</a>. Le Troff d'Open Solaris est basé sur le Troff du Systeme V release 4, qui dérive du DWB d'AT&T version 2. Sur la <a href="http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/">forge</a>, de Solaris, on trouve ainsi les sources de Troff, Nroff, et d'autres logiciels qui lui sont associés : Checknr, Checkeq, Col, Deroff, Eqn, Refer, Soelim, Spell, Tbl, Ul. </p>
<h3 id="toc_6">Heirloom Troff, de Gunnar Ritter</h3>
<p>Suite à cette libération, Gunnar Ritter décide de donner une nouvelle jeunesse aux sources de Troff. Il récupère alors le Troff d'Open Solaris, lui ajoute quelques fonctions modernes, et le redistribue sous le titre <a href="http://heirloom.sourceforge.net/doctools.html">Heirloom Doctools</a> :</p>
<blockquote>
<p>Le projet Heirloom s'adresse aux personnes qui aiment travailler sur leur ordinateur en utilisant une interface Unix traditionnelle en ligne de commande. Le projet Heirloom n'est pas un musée du logiciel ; il n'essaie pas de conserver les utilitaires sans modification. Il conserve plutôt le style, l'algorithme et l'interface intacts, tandis qu'il modernise le système lorsque cela est approprié. <a href="http://heirloom.sourceforge.net/index.html">Accueil du projet Heirloom</a> </p>
</blockquote>
<p>Gunnar Ritter a très soigneusement amélioré Troff afin de lui apporter les fonctions typographiques indispensables aujourd'hui : calcul des espaces inter-mots paragraphe par paragraphe (selon une variante de l'algorithme Knuth-Plass utilisé par Tex), micro-typographie (taille des glyphes et interlettrage finement modifiables (comme le préconise Hàn The Thành dans <em>Micro-typographic extensions to the TEX typesetting system</em>), <a href="http://fr.wikipedia.org/wiki/Kerning">réglage de l'approche</a>, ligatures arbitraires, décalage de certains glyphes hors de la marge (« <em>hanging characters</em> »), support des polices <a href="http://fr.wikipedia.org/wiki/Fontes_PostScript">PostScript Type 1</a>, <a href="http://fr.wikipedia.org/wiki/Truetype">TrueType</a>, <a href="http://fr.wikipedia.org/wiki/OpenType">OpenType</a>, et de leurs possibilités, césure des mots internationalisée, gestion de l'UTF-8, méta-données PDF (table des matières, liens, mots-clefs, auteur, titre et sujet). Bref, Heirloom Troff est à Troff ce que pdfTeX est à TeX. Outre ces améliorations, Gunnar Ritter a aussi incorporé les extensions de troff introduites par Groff, son équivalent GNU. L'ensemble compile maintenant sur à peu près toutes les plate-formes : Linux, BSD, Solaris et plan9. </p>
<p>L'archive contient, outre Troff, Nroff, Dpost, Eqn, Pic, Refer et Soelim, des outils un peu oubliés : Checknr, qui vérifie qu'un fichier Troff est bien formaté, Vgrind, un pré-processeur qui formate du code source pour l'impression via Troff (Il est encore fait mention du copyright de Bill Joy dans les sources), Picpack qui permet d'inclure des images postscript, et Ptx, pour créer des index. </p>
<h3 id="toc_7">Troff de Plan9</h3>
<p><a href="http://plan9.bell-labs.com/plan9/">Plan9</a> incorpore une version de Troff dans ses sources. Largement modifiée, cette version n'apporte que peu d'améliorations visibles par l'utilisateur final, sinon qu'elle gère nativement l'utf-8. Néanmoins, les utilisateurs de Plan9 sont aujourd'hui parmi les derniers a utiliser Troff, aussi, sur la liste de discussion <a href="http://marc.info/?l=9fans">9fans</a>, on trouve de nombreuses informations sur Troff, et les sources d'anciens logiciels qui lui étaient associés y apparaissent régulièrement. </p>
<p>Une version compilable sur Unix/Linux du Troff de Plan9 est disponible dans l'archive de <a href="http://swtch.com/plan9port/">plan9 from user space</a>. </p>
<p>Dans cette archive, on trouve, outre <a href="http://swtch.com/plan9port/man/man1/troff.html">Troff</a> : <a href="http://swtch.com/plan9port/man/man1/troff2html.html">Troff2html</a>, <a href="http://swtch.com/plan9port/man/man1/tr2post.html">Tr2post</a>, <a href="http://swtch.com/plan9port/man/man1/tbl.html">Tbl</a>, <a href="http://swtch.com/plan9port/man/man1/spell.html">Spell</a>, <a href="http://swtch.com/plan9port/man/man1/proof.html">Proof</a>, <a href="http://swtch.com/plan9port/man/man1/pic.html">Pic</a>, <a href="http://swtch.com/plan9port/man/man1/htmlroff.html">Htmlroff</a>, <a href="http://swtch.com/plan9port/man/man1/grap.html">Grap</a>, <a href="http://swtch.com/plan9port/man/man1/eqn.html">Eqn</a>, <a href="http://swtch.com/plan9port/man/man1/doctype.html">Doctype</a>, <a href="http://swtch.com/plan9port/man/man1/deroff.html">Deroff</a> et <a href="http://swtch.com/plan9port/man/man1/grap.html">Grap</a>. </p>
<h2 id="toc_8">Documentation de troff et de ses compagnons</h2>
<p>La documentation de Troff est, à mon avis, particulièrement bien faite. Elle est composée d'un ensembles d'articles courts, clairs et exhaustifs. Comme indiqué ci-dessus, les sources de la documentation originale de Troff sont présentes dans l'archive du DWB d'AT&T. Mais on trouve aussi la version postscript de ces articles sur le site de Bell Labs. Seulement, ces articles sont mal indexés, et introuvables sans aide. Le site de référence à ce sujet est celui de <a href="http://troff.org">Ralph Corderoy</a>. Je me contente de recueillir ici les liens connus vers la documentation. </p>
<p>Deux des documents écrits par Brian Kernighan font aujourd'hui encore office de référence : <a href="http://cm.bell-labs.com/cm/cs/cstr/54.ps.gz">54.ps.gz</a>, la documentation complète, <a href="http://cm.bell-labs.com/cm/cs/cstr/97.ps.gz">97.ps.gz</a>, la description du format de sortie indépendant du périphérique (<em>device independant</em>). </p>
<p>Quant aux autres documents, ils traitent des logiciels qui s'articulent avec Troff. En voici la liste : <a href="http://cm.bell-labs.com/cm/cs/cstr/116.ps.gz">Pic</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/114.ps.gz">Grap</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/122.ps.gz">Chem</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/132.ps.gz">algorythm animation</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/142.ps.gz">Dformat</a>, <a href="http://cm.bell-labs.com/cm/cs/doc/74/eqn.ps.gz">Eqn user guide</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/127.ps.gz">cross references</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/128.ps.gz">index tools</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/103.ps.gz">ideal</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/162.ps.gz">MetaPost manual</a>, <a href="http://cm.bell-labs.com/cm/cs/cstr/163.ps.gz">graph with MetaPost</a>.</p>
<p>Sur la page de <a href="http://www.kohala.com/start/troff/troff.html">Richard Stevens</a> on trouve une copie de ces articles, mais aussi d'autres documents sur Troff : <a href="http://www.kohala.com/start/troff/cstr54.ps">manuel</a>, <a href="http://www.kohala.com/start/troff/v7man/trofftut/trofftut.ps">tutoriel</a>, <a href="http://www.kohala.com/start/troff/cstr97.ps">device independant</a>, <a href="http://www.kohala.com/start/troff/v7man/tbl/tbl.ps">Tbl</a>, <a href="http://www.kohala.com/start/troff/v7man/eqn/eqn2e.ps">Eqn2e</a>, <a href="http://www.kohala.com/start/troff/v7man/eqn/cacm.ps">Eqn</a>, <a href="http://www.kohala.com/start/troff/cstr116.ps">Pic</a>, <a href="http://www.kohala.com/start/troff/gpic.raymond.ps">GNU Pic</a>, <a href="http://www.kohala.com/start/troff/pic.examples.ps">Pic examples</a>, <a href="http://www.kohala.com/start/troff/Setup.pic.txt">Pic macros</a>, <a href="http://www.kohala.com/start/troff/pic2html.html">Pic to html</a>, <a href="http://www.kohala.com/start/troff/v7man/msmacros/msmacros.ps">ms</a>, <a href="http://www.kohala.com/start/troff/cstr114.ps">Grap</a>, <a href="http://www.kohala.com/start/troff/gpic.raymond.ps">Gpic</a>, <a href="http://www.kohala.com/start/troff/cstr128.ps">index tools</a>, <a href="http://www.kohala.com/start/troff/indexing.tools.txt">index tools sources</a>, <a href="http://www.kohala.com/start/troff/v7man/refer/refer.ps">refer</a>. </p>
<p>Quant aux autres documents que j'ai pu trouver, en voici la liste, en vrac : <a href="http://www.zen89632.zen.co.uk/Groff/Eqn/eqnguide.pdf">GNU Eqn</a>, <a href="http://docs.freebsd.org/44doc/usd/19.memacros/paper.pdf">Me tutoriel</a>, <a href="http://docs.freebsd.org/44doc/usd/20.meref/paper.pdf">Me reference manual</a>, <a href="http://www.schweikhardt.net/man_page_howto.html">man how-to</a>, <a href="http://home.windstream.net/kollar/groff/effman.html">Effman</a>, <a href="http://www.schaffter.ca/mom/mom-01.html">Mom</a>, <a href="ftp://ftp.axis.se/pub/groff/swedish_mm_manual.src.tgz">Mm</a>. </p>
<p>Enfin, Oreilly publie les sources du livre <a href="http://oreilly.com/openbook/utp/"><em>Unix Text Processing</em></a> écrit par Dale Dougherty et Tim O'Reilly lui-même. </p>
<h2 id="toc_9">Logiciels accompagnant Troff</h2>
<p>De nombreux logiciels gravitent autour de Troff. Si les sources des anciens Troff tendent à réapparaître sur le net, les sources des logiciels qui l'entouraient tendent quant à elles à disparaître. Voici quelques liens permettant d'en retrouver les traces. </p>
<h3 id="toc_10">Mpm : pour la justification verticale</h3>
<p>Mpm est un post-processeur qui gère la justification verticale des blocs (figures, paragraphes…). Il réapparait tous les dix ans sur la <a href="http://marc.info/?l=9fans&r=1&w=2">liste de discussion de plan9</a> : ainsi <a href="http://marc.info/?l=9fans&m=111558829312191&w=2">en 2002</a> et <a href="http://marc.info/?l=9fans&m=134060727303392&w=2">en 2012</a>. On peut trouver ses sources dans le répertoire <a href="http://plan9.bell-labs.com/sources/contrib/steve/root/sys/src/cmd/pm">contrib</a> de plan9. Gunnar Ritter l'a ajouté dans l'archive de Heirloom Troff. On trouve la documentation qu'en a fait Brian Kernighan sur usenix : <a href="http://www.usenix.org/publications/compsystems/1989/spr_kernighan.pdf">spr_kernighan</a>.</p>
<p>À la fin du README, il est indiqué :</p>
<blockquote>
<p>Historical note: There is a simpler version of pm and -mpm called pj and -mpj that only does vertical justification of pages that have already been laid out by conventional means. This simpler version may be adequate, but it is no longer supported and memory of how it works is growing dim. </p>
</blockquote>
<h3 id="toc_11">Picasso : pour dessiner</h3>
<p>Picasso est une interface graphique permettant de dessiner des dessins au format pic. Il en est parfois question dans la liste de discussion de Groff, mais avec regrets, car les sources semblent perdues. Pourtant, en cherchant bien, on les trouve : dans l'archive du DWB d'AT&T ! </p>
<p>Un <a href="http://marc.info/?l=9fans&m=130619143229061&w=2">post</a> de 9fans y fait aussi référence, et cite trois alternatives : </p>
<blockquote>
<p>art (from the 2nd edition), though Andrey did stirling work porting it to the draw model years ago I honestly don't feel it up to the job - perhaps my lack of stamina? </p>
</blockquote>
<p>On devrait le trouver dans le répertoire de Steve Simon de Plan9/contrib. </p>
<blockquote>
<p>cip/xcip - this is part of the blit distribution and xcip is avaialable on the net these days. I have a vague memory that someone got this to run on a modern OS - plan9/X11 perhaps? anyone know more? </p>
</blockquote>
<p>Cip fait l'inverse de Pic : à partir d'une image, il produit le code de Pic. Xcip est la version graphique de Cip, comme l'indique la quatrième de couverture de <a href="http://www.amazon.com/Network-Programming-Addison-Wesley-Professional-Computing/dp/product-description/0201563185"><em>Unix System V Network Programming</em></a> :</p>
<blockquote>
<p>Acknowledgements. This book was produced on an Intel i386-based system running UNIX System V Release 4.0, Version 3. The text editor sam was used to create and update the text. The pictures were created with xcip, a newer version of cip, on an AT&T 630MTG terminal. The output for the book was produced with eqn, tbl, pic, troff, and dpost from the Documenter's WorkBench, Version 3.2. </p>
</blockquote>
<p>On en parle aussi dans un <a href="http://man.lupaworld.com/content/other/Linux/Linux_Unixs_secret/unx25.htm">guide sur Unix</a>, et dans un <a href="http://lists.gnu.org/archive/html/groff/2010-10/msg00035.html">post</a> de la liste de discussion de groff. Il est présent dans contrib/Venkatesh Srinivas/ selon ce <a href="http://marc.info/?l=9fans&m=130619279630297&w=2">post</a> :</p>
<blockquote>
<p>xfig + transfig - feels a bit like a patch on a patch and, being modern unix code would (no doubt) include configure hell… </p>
</blockquote>
<p><a href="http://xfig.org/">Xfig et transfig</a> sont encore en activité, car plus récents et compatibles avec Latex. </p>
<p>Parfois, il est aussi question de ideal, de <a>dag</a> dont on trouve la <a href="ftp://ftp.cs.utexas.edu/pub/code2/kleyn/graphs/AttDag/dagdoc.ps">documentation</a>, de <a href="http://www.cs.uwaterloo.ca/~dberry/FTP_SITE/reprints.journals.conferences/flo.conference.paper.pdf">flow</a> ou de <a href="http://troff.org/papers.html">g3</a> (<em>"G3 - A Language for Typesetting Three Dimensional Graphics"</em>, dont on trouve un scan de la <a href="http://www.ukuug.org/events/1990/evolves/G3typesetting.pdf">documentation</a>, mais ceux-ci semblent bel et bien perdus… </p>
<p>Sinon, on peut aussi travailler avec dformat, dont on trouve <a href="http://www.troff.org/dformat.jlb">l'original</a> et une version <a href="http://www.troff.org/dformat">nettoyée</a>, <a href="http://www.manpagez.com/man/1/grn/">grn</a> ou bien <a href="http://ect.bell-labs.com/who/hobby/MetaPost.html">metapost</a> qui produit des fichiers pour troff, et pas seulement pour Tex. </p>
<h3 id="toc_12">Troff et le HTML</h3>
<p>Éparpillés sur le net, on trouve des outils pour transformer un fichier troff vers de l'html : <a href="http://www-rn.informatik.uni-bremen.de/software/unroff/">Unroff</a>, <a href="http://www.snake.net/software/">Troffcvt</a>, <a href="http://freecode.com/projects/manserver">Manserver</a>, <a href="http://users.softlab.ece.ntua.gr/~christia/man-cgi.html">Man-cgi</a>, <a href="http://plan9.bell-labs.com/sources/plan9/sys/src/cmd/ms2html.c">Ms2html</a>, <a href="http://www.ccs.neu.edu/home/dorai/troff2page/">Troff2page</a>, <a href="http://www.pathname.com/~quinlan/troff2html/">Troff2hml.pl</a> et <a href="http://alumnus.caltech.edu/~copeland/work/software/web2.shar.gz">Web2</a>.</p>
<p>Certains outils sont concentrés dans l'archive de Plan9 From User Space : <a href="http://swtch.com/plan9port/man/man1/troff2html.html">Troff2html</a>, <a href="http://swtch.com/plan9port/man/man1/htmlroff.html">Htmlroff</a>, </p>
<p>Sur la page de <a href="http://alumnus.caltech.edu/~copeland/work/">Jeffrey Copeland</a>, on trouve un <a href="http://alumnus.caltech.edu/~copeland/work/PDF/2000-11-tbl.pdf">article</a> concernant la transfert du format tbl en HTML, ainsi qu'un <a href="http://alumnus.caltech.edu/~copeland/work/software/tbl.shar.gz">logiciel</a> faisant ce travail. Pour le même travail, on pourra aussi utiliser <a href="http://home.windstream.net/kollar/groff/htbl.tar.gz">Htbl</a>. </p>
<h3 id="toc_13">Troff et le XML</h3>
<p>Pour transférer un fichier Troff vers Docbook, l'outil de référence est <a href="http://www.catb.org/~esr/doclifter/">Doclifter</a> (écrit par Éric S. Raymond). On appréciera aussi <a href="http://dbtroff.sourceforge.net">Dbtroff</a> (écrit par Gunnar Ritter), qui fait le travail inverse. </p>
<p>Pour l'ODT, il y a un fichier XSLT dans l'archive de Heirloom Troff.</p>
<h3 id="toc_14">Références et index</h3>
<p>Dans l'archive des <a href="http://heirloom.sourceforge.net/tools.html">utilitaires</a>, du projet Heirloom, on trouve tout un tas d'outils pour gérer la bibliographie au format refer : Addbib, Sortbib, Roffbib, Indxbib, Lookbib. On pourra aussi utiliser les outils de <a href="http://www.snake.net/software/">Bibstuff</a>. </p>
<p>On trouve aussi des outils pour créer des <a href="http://www.netlib.org/typesetting/indexing.tools">index</a>. Outils qu'on retrouve parmi les logiciels du <a href="http://www.netlib.org/">Netlib de Bell Lab</a>. Ces <a href="http://www.cs.princeton.edu/netlib/typesetting/indexing.tools.gz">outils d'indexation</a> sont aussi publiés sur la page personnelle de <a href="http://www.cs.princeton.edu/~bwk/btl.mirror/new/">Brian Kernighan</a>.</p>
<h3 id="toc_15">Développement logiciel</h3>
<p><a href="http://home.windstream.net/kollar/groff/nrchbar.tar.gz">Nrchbar</a> permet d'imprimer un diff. On peut aussi utiliser Diffmk, présent dans l'archive de DWB pour marquer les différences entre deux fichiers troff. </p>
<h3 id="toc_16">Présentations scientifiques</h3>
<p>Troff est toujours fourni avec une version de Eqn, qui permet d'écrire des formules mathématiques. Mais on trouve aussi, parmi les logiciels du <a href="http://www.netlib.org/">Netlib de Bell Lab</a> une version de <a href="http://www.netlib.org/typesetting/chem">Chem</a> qui permet d'écrire des formules chimiques. La version originale est disponible sur la page personnelle de <a href="http://www.cs.princeton.edu/~bwk/btl.mirror/new/">Brian Kernighan</a> ainsi que sa <a href="http://www.cs.princeton.edu/netlib/typesetting/chem.gz">documentation</a>.</p>
<p>Sur la liste de discussion de Plan9, on peut trouver plusieurs macros. Pour créer des <a href="http://marc.info/?l=9fans&m=125062452017555&w=2">slides</a>, d'autres <a href="http://plan9.bell-labs.com/sources/contrib/steve/foils.tgz">slides</a> et des <a href="http://plan9.bell-labs.com/sources/contrib/fernan/schem.tgz">circuits électroniques</a>. </p>
<p>D'autres macro permettent de créer des présentations, telles <a href="http://www.science.uva.nl/~bobd/useful/gpresent/">Gpresent</a>, <a href="http://www.cs.rit.edu/~hpb/Man/_Man_Local_html/html5/mv.5.html">Mv</a>, dont les sources semblent perdues, et <a href="http://web.cecs.pdx.edu/~trent/gnu/groff/mo-0.2.tar.gz">Mo</a>. </p>
<p>Heirloom Troff est fourni avec une version de Grap, qui permet de dessiner des graphiques depuis une liste de données. <a href="http://swtch.com/plan9port/">Plan9 from user space</a>, fournit lui aussi une version de <a href="http://swtch.com/plan9port/man/man1/grap.html">grap</a>. Si on préfère, on pourra utiliser une autre <a href="http://www.lunabase.org/~faber/Vault/software/grap/">version</a>, ou alors utiliser <a href="http://www.kohala.com/start/troff/prag-1.0pl2.shar">Prag</a>, un script Awk capable de remplacer Grap. </p>
<h3 id="toc_17">Macro diverses</h3>
<p>On trouve une macro nommée <a href="ftp://ftp.cs.princeton.edu/pub/people/drh/loom.tar.gz">Loom</a>, une autre nommée <a href="http://troff.org/labels-20020520.tar.gz">Labels</a> pour écrire des étiquettes, pour des étiquettes toujours, on peut utiliser cette <a href="http://home.windstream.net/kollar/groff/labels.tar.gz">version</a>. On trouve aussi une macro nommée <a href="http://www.cowlark.com/meta/">Meta</a>, une autre nommée <a href="http://alumnus.caltech.edu/~copeland/work/software/resume.shar.gz">Resume</a>, et encore une nommée <a href="http://alumnus.caltech.edu/~copeland/work/software/letter.shar.gz">Letter</a>. </p>
<h2 id="toc_18">Pourquoi cette dépêche ?</h2>
<p>Il est vrai que cette dépêche n'est qu'une collection de liens à peine commentés. Quel est donc son intérêt, au delà de l'effet marque page ?</p>
<h3 id="toc_19">Réflexion sur l'histoire à l'âge de l'Internet</h3>
<p>En premier lieu, la dépêche a été motivée par la curiosité de <a href="http://linuxfr.org/users/oulala">Tonton Th</a>, qui, au détour d'un commentaire a exprimé sa <a href="http://linuxfr.org/nodes/95053/comments/1374575">curiosité</a> quant à l'histoire de Troff. Ce commentaire apparaissait dans une discussion sur la pérennité des données sur Internet. On peut avoir l'impression qu'Internet n'a pas de mémoire, et rechercher <em>troff</em> sur Google ne donne pas grand chose de très intéressant sur son passé. Pourtant, en cherchant bien, on trouve les documents nécessaires à l'écriture de l'histoire de Troff. La méthode à suivre est d'ailleurs assez simple : </p>
<ul><li>Il faut commencer par trouver un centre de référence ; en l'occurrence, ici, il s'agit des listes de discussion de Plan9 et de Groff, où se rencontrent les derniers utilisateurs de Troff. </li>
<li>En parcourant ces listes de discussion, on retrouve de nombreux noms de logiciels. </li>
<li>Ces noms permettent de faire des recherches plus précises dans les moteurs de recherches, qui deviennent alors pertinents. </li>
</ul><p>Par exemple, pour trouver le logiciel <em>Picasso</em>, il m'a fallu d'abord prendre connaissance du nom du logiciel, qui est déjà bien oublié ; il m'a fallu apprendre ensuite qu'il faisait partie d'un ensemble dénommé DWB, et au détour d'un article sur l'histoire d'Unix, j'ai appris que DWB était un produit d'AT&T. Finalement, c'est une (longue) recherche sur DWB et AT&T qui m'a permis de trouver l'archive contenant <em>Picasso</em>.</p>
<p>Ce travail de recherche met en évidence deux mouvements : certes, des données disparaissent d'internet, mais il faut remarquer que des données y ré-apparaissent tout autant. Sur les listes de discussion, des logiciels, ou des liens vers des logiciels ressortent régulièrement : à la demande d'un utilisateur, un particulier peut partager un logiciel dont il conservait une copie. Les entreprises elles-aussi peuvent décider de libérer les sources de logiciels ayant une importance historique, comme l'a fait <em>Caldera</em> pour Unix.</p>
<h3 id="toc_20">Réflexion sur le langage à l'âge de l'image</h3>
<p>En second lieu cette dépêche fait suite au journal de <a href="http://linuxfr.org/users/mrspackman">MrSpackMan</a> : « <a href="http://linuxfr.org/users/mrspackman/journaux/l-esprit-unix-une-culture-des-mots">L'esprit Unix, une culture de mots</a> ». Qu'est-ce qui définit proprement Unix ? <a href="http://theody.net/elements.html">Thomas Scoville</a> pense que, au-delà (ou en-deçà) des tubes, du shell et du tout fichier, ce qui définit Unix c'est son affinité avec le langage. Unix, c'est le langage comme interface. Si tel est bel et bien le cas, alors, Unix est l'outil idéal pour manipuler du texte. Or, la manipulation du texte sous Unix trouve son terme (l'impression) avec Troff. Si Unix se définit par son logocentrisme, alors Troff constitue un moment essentiel de son aventure. De fait, Internet garde les traces de l'importance qu'a pu avoir Troff, et devant la foison de logiciels qui s'articulaient avec lui, on peut avoir l'impression que l'histoire d'Unix est intimement liée à l'histoire de Troff. Peut-être que le moment où Unix était adopté en entreprise coïncide avec le moment ou Troff était considéré comme un outil d'édition pertinent.</p>
<p>Si l'on s'accorde pour dire que les histoires d'Unix et de Troff sont conjointes, nous pouvons nous demander ce que signifie pour Unix l'oubli de Troff. Avec l'oubli de Troff, c'est le texte qui disparaît d'Unix. De fait, le déport du texte hors du cœur d'Unix vers l'interface graphique et le web modifie radicalement l'usage d'Unix. Si les seuls textes qui persistent au cœur d'Unix sont les fichiers de configuration, alors, les outils Unix deviennent des outils dédiés à l'administration. Ils l'ont toujours été, mais je crois qu'il fut un temps où la manipulation de fichiers de configuration et la manipulation de textes destinés à être imprimés ont convergé, et cette convergence a marqué l'apogée de l'histoire d'Unix.</p>
<p>On repère ce déplacement dans l'histoire de Troff : il apparaît un moment où les interfaces graphiques complètent l'éco-système logiciel, en particulier pour créer des dessins. Mais très vite, ces outils sont dépassés. De même, dans l'histoire de Troff, on repère l'émergence du web : il arrive un moment où une foison d'outils servent à exporter un fichier troff vers l'HTML. Mais tous ces outils arrivent trop tard, l'HTML, et les outils le manipulant, se sont implantés à côté de Troff, et non pas dans sa continuité. Ces deux ruptures ne sont pas équivalentes. Troff semble avoir pu concurrencer un temps les interfaces graphiques mais a aucun moment il n'a pu se faire une place dans le monde de l'HTML.</p>
<p>Enfin, si Troff a pu être un maillon important d'un système informatique ayant le langage comme interface, alors retrouver l'usage de Troff est un moyen de retrouver l'usage du langage comme interface. Troff et les logiciels qui l'accompagnent forment un ensemble de mini-langages (Eqn, Pic, Tbl, et Refer ont chacun leur mini-langage). La syntaxe de Troff, qui force à l'écriture de ligne courtes, s'articule parfaitement avec les outils de manipulation de flux lignes à lignes (Sed, Awk, Diff, Patch). En ligne de commande, Troff fait un usage intensif des tubes. Cet ensemble forme ainsi un tout cohérent, une suite bureautique en ligne de commande, mais dont nous avons perdus l'usage. Retrouver les sources de ces logiciels et leurs documentations est un moyen de retrouver la grammaire d'une langue, avant de pouvoir la parler de nouveau.</p></div><div><a href="https://linuxfr.org/news/a-la-recherche-des-sources-de-troff.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/95091/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/a-la-recherche-des-sources-de-troff#comments">ouvrir dans le navigateur</a>
</p>
SygneNils Ratusznikbaud123NÿcoB16F4RV4RD1NPierre Jarillonpatrick_ghttps://linuxfr.org/nodes/95091/comments.atomtag:linuxfr.org,2005:Diary/314482011-08-04T23:22:21+02:002011-08-04T23:22:21+02:00Petite^W Longue critique du livre Code Complete<h2 id="sommaire">Sommaire</h2>
<ul><li><a href="#toc_0">Un petit problème…</a></li>
<li><a href="#toc_1">OK. Mais de quoi traite ce livre au juste ?</a></li>
<li><a href="#toc_2">Quelques exemples de bonnes pratiques</a></li>
<li><a href="#toc_3">Autres points généraux sur lequel l'auteur insiste</a></li>
<li><a href="#toc_4">Un bon point de départ</a></li>
<li><a href="#toc_5">Que dire de plus ?</a></li>
</ul><p>J'aime bien suivre l'actualité générale autour du Libre (comprendre : lire DLFP), suivre quelques blogs, etc. Mais j'aime bien aussi lire des livres traitant d'informatique. Et le dernier en date, c'est justement <a href="http://cc2e.com/">Code Complete, de Steve McConnell</a> (2e édition).</p>
<p>[/!\ § d'accroche]<br />
En bref : si vous aimez la programmation, il y a des chances que vous aimerez encore plus ce « métier » situé entre l'art et l'ingénierie après avoir lu ce livre. En tout cas c'est mon sentiment.</p>
<h2 id="toc_0">Un petit problème…</h2>
<p>Alors, pour ceux qui ont déjà cliqué sur le premier lien, oui, l'éditeur est Microsoft Press. Ne pas acheter ce livre juste à cause de ça est idiot ÀMHA. Comme je suis un libriste comme tout le monde ici, mon avis sur le sujet vous semblera peut-être intéressant :</p>
<ul><li><p>Déjà, les exemples de code, qui sont assez nombreux, sont soit en C++ (bien), Java (moins bien) ou Visual Basic (argh !). Mais dans ce genre de livre, le langage n'a pas trop d'importance. Et le Visual Basic n'a pas une syntaxe trop exotique, pas comme le Smalltalk par exemple qui est parfois utilisé dans le livre <a href="http://en.wikipedia.org/wiki/Design_Patterns">Design Patterns</a>.</p></li>
<li><p>Le lien avec Microsoft ou Windows se limite juste à quelques références ou anecdotes. De ce point de vue là, c'est très varié.</p></li>
<li><p>Le monde OpenSource, de UNIX et de GNU/Linux n'est pas oublié, mais on peut regretter une absence totale du Libre (eh non, <a href="http://www.framablog.org/index.php/post/2009/10/02/logiciel-libre-open-source">OpenSource ≠ Libre</a>).</p></li>
</ul><h2 id="toc_1">OK. Mais de quoi traite ce livre au juste ?</h2>
<p>Construire un programme qui fonctionne, ce n'est pas difficile. En construire un dont le code est simple à comprendre, qui est facilement maintenable, et où on n'a pas perdu du temps à travailler sur des choses inutiles ou peu significatives, c'est une autre paire de manches. Code Complete explique donc plein de bonnes pratiques pour arriver à cet objectif.</p>
<p>Dans un projet de programmation, écrire le code source est inévitable. Donc autant le faire le mieux possible. Mais en-dehors de l'écriture du code, il peut y avoir beaucoup d'autres choses (surtout dans les entreprises, moins pour un projet personnel) :</p>
<ul><li>définir le problème à résoudre ;</li>
<li>définir le cahier des charges, les exigences ;</li>
<li>réfléchir à l'architecture du logiciel ;</li>
<li>{écrire le code} ;</li>
<li>tester et déboguer ;</li>
<li>intégration des différents composants ;</li>
<li>refactoring (améliorer du code existant) ;</li>
<li>améliorer les performances, mais pas n'importe comment.</li>
</ul><p>Tout ceci ne se fait évidemment pas séquentiellement, mais de manière itérative. Ainsi, si on fait une erreur dans une des premières étapes, on s'en rend plus vite compte, et l'impact est moins important.</p>
<p>Code Complete parle de tous ces sujets, mais les trois premiers points de manière résumée/introductive. Et pour les autres sujets autres que {écrire le code} (qui est la partie la plus développée du livre), il y a pas mal d'explications, mais en fin de chapitres il y a à chaque fois des références vers d'autres bouquins plus complets.</p>
<h2 id="toc_2">Quelques exemples de bonnes pratiques</h2>
<p>Vous vous demandez surement comment on peut écrire un ouvrage de 900 pages, alors que le sujet principal est l'écriture de code. Quels genres de conseils y sont donnés ?</p>
<p>Pour donner un exemple très précis, prenons l'écriture du nom d'une fonction. Le nom d'une fonction, c'est très important, pour savoir ce qu'elle fait exactement, et pour la retrouver et la réutiliser facilement quand on en a besoin.</p>
<p>Si avant de commencer à écrire la fonction, on a du mal à lui donner un nom, c'est qu'il y a un problème : on n'a pas bien réfléchi à l'avance ce que la fonction est censée faire exactement, et dans ce cas-là, soit on lui donner un nom bateau genre « handle_stuff() », et la fonction fait plein de diverses choses. Soit on change d'avis, et au lieu d'écrire une fonction fourre-tout, on la décompose en plusieurs fonctions qui ne font qu'une chose, mais qui le font bien™. Tient, ça ressemble vachement à la philosophie UNIX !</p>
<p>Et là, les programmeurs chevronnés se disent : « pff, c'est tout à fait logique, je n'ai pas besoin de ce genre de conseils ». Sur ce point-là, je n'ai pas un avis très tranché. Il y a quelques parties du livre (mais pour ma part ça ne représentait pas beaucoup) qui s'adressent clairement aux débutants. D'ailleurs dans ce cas, il y a un avertissement au début du chapitre, pour dire que certains peuvent sauter une ou plusieurs sections. En tout cas, sur la quatrième de couverture, il est clairement marqué que c'est adressé tant aux débutants qu'aux programmeurs plus expérimentés.</p>
<p>En programmation, il y a beaucoup de choses qu'on fait par habitude. Si on prend des bonnes habitudes dès le début, tout va bien. Mais le problème c'est qu'on est pas toujours conscient qu'on a pris de mauvaises habitudes. Je vais prendre un exemple qui m'a assez choqué dans le livre, mais qui s'avère au final bénéfique.</p>
<p>Pratiquement tous les programmeurs, pour écrire des boucles, utilisent les noms de variables i, j, voir k (mais trop d'imbrications rend le code plus difficile à suivre, mais là n'est pas le sujet). Il est conseillé d'utiliser plutôt des noms plus long qui décrivent bien ce que l'index représente. Ainsi, quand on veut modifier la valeur d'un tableau imbriqué par exemple, au lieu de lire :</p>
<blockquote>
<p><code>score[i][j] = ...;</code></p>
</blockquote>
<p>on lit :</p>
<blockquote>
<p><code>score[ teamIndex ][ eventIndex ] = ...;</code></p>
</blockquote>
<p>En ayant des noms plus explicites, en rapport avec le domaine d'application, il y a moins de risque de confondre les deux variables, et on comprend mieux ce que le code fait.</p>
<p>Et pourtant, l'utilisation des i, j, etc. est très très courant. Pourquoi ? Si c'est pour <em>écrire</em> le code plus vite, ce n'est pas une bonne raison. On lit beaucoup plus de code qu'on en écrit. En règle générale, il faut écrire du code non pas pour la machine, mais pour soi-même et les autres personnes qui vont le lire.</p>
<p>Il y a comme ça certains conseils généraux qui sont souvent répétés. Certains préfèrent que certaines informations soient répétées pour mieux les retenir, d'autres trouvent ça inutile. Pour ces derniers, il y a peut-être <a href="http://en.wikipedia.org/wiki/Pragmatic_Programmer">d'autres livres</a> sur <a href="http://netlib.bell-labs.com/cm/cs/pearls/">le même sujet</a> qui leurs conviendraient mieux.</p>
<h2 id="toc_3">Autres points généraux sur lequel l'auteur insiste</h2>
<ul><li><p>Un des buts premiers de la programmation est de gérer la complexité, en faisant abstraction de certaines choses, à tous les niveaux. L'exemple typique est la programmation orientée objet : pour utiliser une classe, il ne faut pas (normalement) savoir comment elle fonctionne en interne.</p></li>
<li><p>Programmer en termes du problème au lieu des détails techniques. Par exemple on s'en fiche de savoir quelle structure de données est utilisée pour stocker certaines informations. Donc on préfèrera des noms de fonctions tels que get_last_document() plutôt que get_top_stack().</p></li>
<li><p>Faire attention aux signes qui montrent que notre code est mal écrit : par exemple quelqu'un qui nous dit que notre code est difficile à comprendre. Ou bien des warnings lors de la compilation, etc.</p></li>
<li><p>Ne pas se focaliser sur une seule et unique méthode. Aucune méthode n'est parfaite pour tous les types de projets. Trouver les bonnes techniques se fait par une heuristique, il n'y a pas de procédé clairement défini. C'est comme un ouvrier avec une boite à outils. Il n'y a pas un outil qui convient pour tout.</p></li>
</ul><h2 id="toc_4">Un bon point de départ</h2>
<p>Le texte est rempli de références vers d'autres ouvrages, donnant souvent envie d'en apprendre plus. Le dernier chapitre est d'ailleurs consacré rien qu'à ça.</p>
<p>Peut-être qu'en lisant ce journal, vous avez pensé à <a href="http://en.wikipedia.org/wiki/The_Art_of_Computer_Programming">The Art of Computer Programming</a> de Donald Knuth. Cette série de livres détaille en profondeur l'algorithmique et les structures de données. Code Complete aborde évidemment aussi ce sujet, mais il en aborde tellement d'autres que ce n'est pas comparable.</p>
<h2 id="toc_5">Que dire de plus ?</h2>
<p>Encore beaucoup de choses, mais je vais m'arrêter là pcq c'est déjà suffisamment long comme ça. Pour ceux qui ont lu jusqu'ici, merci :)</p>
<p>Ah non, j'ai menti, encore une chose. Je pense qu'il existe une traduction en français, mais comme toute traduction d'un livre informatique écrit à la base en anglais, il est plutôt conseillé de lire l'original. J'ai déjà vu des livres en français où le code source était mal formaté, des mots comme CPU sont traduits en UC (Unité Centrale), etc. Bref, à déconseiller.</p><div><a href="https://linuxfr.org/users/swilmet/journaux/petitew-longue-critique-du-livre-code-complete.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/87006/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/swilmet/journaux/petitew-longue-critique-du-livre-code-complete#comments">ouvrir dans le navigateur</a>
</p>
swilmethttps://linuxfr.org/nodes/87006/comments.atomtag:linuxfr.org,2005:Diary/310072011-04-16T22:02:05+02:002011-04-16T22:02:05+02:00Nouvelle version stable de FVWMLicence CC By‑SA http://creativecommons.org/licenses/by-sa/3.0/deed.fr<p><a href="http://fvwm.org">FVWM</a>¹ est un ancêtre parmi les gestionnaires de fenêtre. Lui-même héritier de twm, il a <a href="http://commons.wikimedia.org/wiki/File:Fvwm_family.svg">servi de base</a> à WindowMaker, AfterStep, Enlightenment, au WM de XFCE...</p>
<p>Parmi ses forces, on notera une très grande configurabilité, même si certains font des <a href="http://www.fvwm.org/screenshots/desktops/GlenLeeEdwards-desk4-1024x768/screenshot.gif">mélanges de couleurs pas très heureux</a>. Dans sa configuration par défaut, FVWM a <a href="http://www.fvwm.org/screenshots/desktops/Thomas_Adam-desk-1280x960/screenshot.png">un look un peu rétro</a>, mais on peut en faire quelque chose de bien plus <a href="http://www.fvwm.org/screenshots/desktops/Christine-toogrey-1024x768/screenshot.png">minimal et moderne</a>. On peut transformer FVWM en un <a href="http://linuxboxadmin.com/articles/tools-and-utilities/tiling-window-management-with-fvwm.html">gestionnaire tiling</a> ou l'utiliser <a href="http://linuxgazette.net/128/adam1.html">en mode kiosk</a>.</p>
<p><a href="http://openbsd.org/faq/faq11.html#Intro">Tous les</a> <a href="http://www-cs-faculty.stanford.edu/~knuth/programs.html">gens cools</a> <a href="http://www.catb.org/~esr/fvwm2/">utilisent</a> <a href="http://groups.google.com/group/comp.os.coherent/msg/e4673e2bb97ced9f">FVWM</a>.</p>
<p>La dernière version stable était <a href="http://thread.gmane.org/gmane.comp.window-managers.fvwm.announce/18">la version 2.4.20</a>, publiée en 2006. Cependant, le développement était toujours actif, et se faisait sur la branche 2.5 dite « instable ». Bien sûr, beaucoup de nouveautés étaient arrivées dans cette branche, et la plupart des distributions suivent la branche 2.5 pour fournir FVWM. Cette branche était, malgré son nom, stable.</p>
<p>Hier, Thomas Adam a <a href="http://thread.gmane.org/gmane.comp.window-managers.fvwm.announce/30">annoncé la version 2.6.0</a>. Je ne détaillerai pas les changements depuis la dernière version 2.4, car il y en a trop, et tous les utilisateurs étaient déjà passés sur la branche 2.5. Tous les utilisateurs sont bien sûr encouragés à mettre à jour vers cette nouvelle version, et les autres à essayer FVWM.</p>
<p>¹ FVWM est le <em>F(?)</em> <em>Virtual</em> <em>Window</em> <em>Manager</em>. Certains prétendent que le F signifie <em>Feeble</em>, en s'appuyant sur des preuves aussi intangibles que des archives Usenet, alors qu'il est évident que le F est là pour <em>Fantastic</em>.</p><div><a href="https://linuxfr.org/users/fperrin/journaux/nouvelle-version-stable-de-fvwm.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/85680/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/fperrin/journaux/nouvelle-version-stable-de-fvwm#comments">ouvrir dans le navigateur</a>
</p>
Frédéric Perrinhttps://linuxfr.org/nodes/85680/comments.atomtag:linuxfr.org,2005:News/277822011-01-17T20:52:13+01:002011-01-17T20:52:13+01:00Groff sort en version 1.21<div>C'est le 31 décembre 2010 que <a href="http://troff.org/whoswho.html#werner">Werner Lemberg</a>, le principal mainteneur de groff<a href="http://lists.gnu.org/archive/html/groff/2010-12/msg00051.html">, a annoncé</a> la sortie de la version 1.21, soit près de deux ans après la sortie de la précédente version.
<br />
<br />
Pour rappel, <a href="http://www.gnu.org/software/groff/">groff</a> est l'implémentation GNU de l'ancestral logiciel roff, interpréteur du langage de formatage de texte du même nom. Groff est généralement utilisé sur nos machines pour afficher nos pages de manuel, mais, outre la sortie en ASCII, latin1 ou UTF-8, groff peut aussi créer des fichiers HTML, xhtml, dvi, PS, ainsi que des fichiers aux formats spécifiques à certaines imprimantes.
<br />
<br />
Voici quelques-unes des améliorations apportées par cette nouvelle version:
<br />
<ul><li>Correction d'une petite faute dans <em>tmac/hyphen.fr</em> qui rendait impossible la césure des lignes des textes français ;
<br />
</li><li>Ajout d'une nouvelle catégorie d'alarme nommée <em>file</em> pour indiquer l'absence d'un fichier appelé par <em>mso</em> ;
<br />
</li><li>Amélioration du support des langues asiatiques et en particulier du japonais. C'est d'ailleurs cette amélioration importante qui a motivé Werner Lemberg <a href="http://lists.gnu.org/archive/html/groff/2010-12/msg00004.html">à publier</a> cette nouvelle version de groff ;
<br />
</li><li>Création d'une nouvelle catégorie de piège (<em>trap</em>) actionnable lorsqu'une ligne commence par un espace, sous réserve que soit définie la macro <em>lsm</em>. Le saut de ligne qui advient normalement dans ce cas n'a alors pas lieu.</li></ul>
<br />
En seconde partie de dépêche est proposée une plus large présentation de groff et de son histoire.</div><ul><li>lien nᵒ 1 : <a title="http://www.gnu.org/software/groff/" hreflang="en" href="https://linuxfr.org/redirect/70569">Groff</a></li><li>lien nᵒ 2 : <a title="http://lists.gnu.org/archive/html/groff/2010-12/msg00051.html" hreflang="en" href="https://linuxfr.org/redirect/70570">Annonce</a></li><li>lien nᵒ 3 : <a title="ftp://ftp.gnu.org/gnu/groff/" hreflang="en" href="https://linuxfr.org/redirect/70571">Archive</a></li></ul><div><h2>1. Histoire de roff</h2><h3>1.1 RUNOFF</h3>C'est en 1964, sur le <a href="http://fr.wikipedia.org/wiki/CTSS">CTSS</a> du <a href="http://fr.wikipedia.org/wiki/MIT">MIT</a>, qu'est apparu le premier programme de formatage de texte : <a href="http://en.wikipedia.org/wiki/RUNOFF">RUNOFF</a>, écrit par <a href="http://en.wikipedia.org/wiki/Jerome_H._Saltzer">Jerome H. Saltzer</a>. Le nom est supposé venir de la locution anglaise : <i>« I'll run off a copy »</i>.
<br />
<h3>1.2 Runoff</h3>Pour <a href="http://en.wikipedia.org/wiki/Multics">Multics</a>, le digne successeur du CTSS, le logiciel a été récrit par Jerome H. Saltzer, <a href="http://en.wikipedia.org/wiki/Robert_Morris_(cryptographer)">Bob Morris</a> et <a href="http://en.wikipedia.org/wiki/Doug_McIlroy">Doug Mc Ilroy</a> et renommé <a href="http://en.wikipedia.org/wiki/Runoff_(program)">runoff</a> (en minuscules). De nombreux logiciels incompatibles entre eux copiant l'usage de runoff sont alors apparus sur diverses architectures.
<br />
<h3>1.3 Roff</h3>Le code de runoff a alors été translittéré par <a href="http://fr.wikipedia.org/wiki/Joseph_Ossanna">Josef F. Osanna</a> – déjà développeur de plusieurs ports de runoff, – pour le prototype d'<a href="http://fr.wikipedia.org/wiki/Unix">Unix</a> fonctionnant sur le <a href="http://en.wikipedia.org/wiki/PDP-7">DEC PDP-7</a> en 1970, et renommé roff, puis récrit pour le <a href="http://en.wikipedia.org/wiki/PDP-11">PDP-11</a> en 1971. <a href="http://fr.wikipedia.org/wiki/Dennis_Ritchie">Dennis Ritchie</a> <a href="http://en.wikipedia.org/wiki/Roff">remarque</a> que ce logiciel, rapidement modifiable et répondant aux besoins du département des brevets de <a href="http://en.wikipedia.org/wiki/Bell_Labs">Bell Labs</a>, a été une des raisons provoquant l'adoption d'UNIX au sein de l'entreprise.
<br />
<h3>1.4 Nroff et troff</h3>Mais Josef Osanna ne s'est pas contenté de translittérer le code, il a ensuite récrit le programme en C et y a ajouté de nombreuses fonctionnalités. Il a alors décomposé le logiciel en deux programmes : <a href="http://en.wikipedia.org/wiki/Nroff">nroff</a> (<i>newer roff</i>) pour les terminaux et les imprimantes lignes à lignes et <a href="http://en.wikipedia.org/wiki/Troff">troff</a> (<i>typesetter roff</i>) pour les documents devant être imprimés, une unique imprimante était alors supportée. En 1976, il publie avec son collègue Josef Osanna le <a href="http://cm.bell-labs.com/cm/cs/cstr/54.ps.gz"><em>Troff User's Manual</em></a> qui sert de spécification du langage roff. De fait, toutes les implémentations futures de roff tenteront de conserver une compatibilité avec cet écosystème originel et son langage de formatage de texte.
<br />
<h3>1.5 Ditroff</h3>À la mort de Josef Osanna en 1977, c'est <a href="http://fr.wikipedia.org/wiki/Brian_Kernighan">Brian Kernighan</a> qui développe troff et nroff, ce qui passe par une nouvelle récriture du logiciel. Il modifie à nouveau l'architecture du système, en créant un logiciel générique, ditroff (<em>device independant troff</em>), produisant une sortie intermédiaire traitée ensuite par différents post-processeurs. Ce format de sortie intermédiaire est défini dans un <a href="http://cm.bell-labs.com/cm/cs/cstr/97.ps.gz">document</a> qui fait encore aujourd'hui office de référence.
<br />
<h3>1.6 La multiplication des *roff</h3>Avec le développement d'UNIX à la fin des années 70 le logiciel troff est largement copié et modifié, mais heureusement, ces différentes versions prennent soin de conserver la compatibilité avec le logiciel d'Osanna et Kernighan. Retenons parmi celles-ci :<ul><li>DWB (document workbench) de SoftQuad ;
<br />
</li><li>DWB 3.4 de Lucent Software Solutions ;
<br />
</li><li>Le <a href="http://plan9.bell-labs.com/magic/man2html/1/troff">troff de Plan9</a> ;
<br />
</li><li>La version de Bill Joy, vendue par Sun Microsystem, et dont un descendant équipe les Solaris ;
<br />
</li><li>Cette dernière version <a href="https://linuxfr.org//2005/01/26/18184.html">a été libérée en 2005</a> avec le code d'Open Solaris, retravaillée par Gunar Ritter pour le <a href="http://en.wikipedia.org/wiki/Heirloom_Project">Heirloom Project</a> et distribuée sous le nom <a href="http://heirloom.sourceforge.net/doctools.html">Heirloom Troff</a> (Le troff des souvenirs). M. Ritter y ajoute le support des polices open-type, la gestion de l'UTF-8 et y inclut des fonctions de micro-typographies, dont <a href="http://defoe.sourceforge.net/folio/knuth-plass.html">l'algorithme de Knuth-Plass</a> créé pour LaTeX pour la mise en forme des paragraphes.</li></ul><h3>1.7 Groff</h3>
<br />
C'est en 1990 qu'est sortie la première version de <a href="http://en.wikipedia.org/wiki/Groff_(software)">groff</a>, récriture de troff en C++ par <a href="http://fr.wikipedia.org/wiki/James_Clark">James Clark</a> pour le projet GNU. Les actuels mainteneurs de Groff, <a href="http://troff.org/whoswho.html#werner">Werner Lemberg</a> et <a href="http://troff.org/whoswho.html#ted">Ted Harding</a> prennent soin de celui-ci depuis 1999.
<br />
<h3>1.8 La fin de l'âge d'or des *roff</h3>L'usage de Roff et de ses descendants est en forte perte de vitesse depuis plusieurs années pour plusieurs raisons: l'adoption de LaTeX dans le milieu universitaire, la concurrence des logiciels de traitement de texte, la création d'outils plus génériques pour le formatage de texte tels txt2tag et la pauvreté de l'offre de macro pour roff. Même pour l'affichage des pages de manuels, terrain où groff semblait incontournable, les distributions ont tendance à préférer des outils concentrés sur cette tâche: <a href="http://lists.gnu.org/archive/html/groff/2010-06/msg00021.html">Debian propose par défaut groff-base, une implémentation réduite de groff</a>, <a href="http://lists.gnu.org/archive/html/groff/2010-06/msg00024.html">FreeBSD choisit</a> <a href="http://mdocml.bsd.lv/">mdocml</a> alors qu'ils auraient pu choisir Heirloom Troff qui est sous licence BSD. Pourtant, l'écosystème roff réunit toujours une communauté d'utilisateurs et de développeurs, qui se rencontrent sur la <a href="http://lists.gnu.org/archive/html/groff/">mailing list de groff</a>, et qui, sans se faire d'illusion pour l'avenir de roff, savent mettre en avant la spécificité et les avantages comparés de groff et de LaTeX (voir ce long <a href="http://lists.gnu.org/archive/html/groff/2007-12/msg00013.html"> fil de discussion</a>, et en particulier <a href="http://lists.gnu.org/archive/html/groff/2007-12/msg00016.html"> ce message</a> et <a href="http://lists.gnu.org/archive/html/groff/2007-12/msg00026.html"> celui-ci</a>).
<br />
<h2>2. L'écosystème groff</h2>Dans l'archive de groff se cache en fait une foule de programmes et de macros. groff n'étant que le logiciel qui permet, en une ligne de commande, d'accorder cet écosystème logiciel. L'archive contient donc des pré-processeurs, des processeurs, des post-processeurs, des outils divers et des macros.
<br />
<h3>2.1 Pré-processeurs</h3>Les pré-processeurs transforment un fichier source que l'on peut écrire à la main en langage roff moins pratique à taper. Ainsi, <a href="http://linux.die.net/man/1/tbl">tbl</a> simplifie l'écriture des tableaux, <a href="http://linux.die.net/man/1/refer">refer</a> celle des références bibliographiques, <a href="http://linux.die.net/man/1/eqn">eqn</a> des formules mathématiques, <a href="http://linux.die.net/man/1/pic">pic</a> des diagrammes, chem celle des structures chimiques. Parmi les pré-processeurs, citons aussi preconv, qui convertit des sources de formats d'encodage divers en quelque chose que groff peut comprendre et traiter.
<br />
<h3>2.2 Processeur</h3>Le processeur interprète le langage roff. Comme le ditroff historique, il produit une sortie intermédiaire qui sera traitée pour la création de fichiers plus complexes, mais le mot ditroff n'a pas survécu, les développeurs préférant l'appeler <a href="http://linux.die.net/man/1/troff">troff</a> en référence au logiciel original. Le manuel de groff considère aussi <a href="http://linux.die.net/man/1/nroff">nroff</a> comme un processeur, bien qu'il s'agisse en fait d'un script shell qui émule le nroff historique: il est utilisé pour l'affichage de texte brut (ASCII, latin1 ou utf8).
<br />
<h3>2.3 Post-processeurs</h3>Les post-processeurs traitent la sortie intermédiaire pour produire des fichiers complexes: <a href="http://linux.die.net/man/1/grotty">grotty</a> pour les sorties en texte brut (c'est le post-processeur utilisé par nroff), <a href="http://linux.die.net/man/1/grodvi">grodvi</a> pour le dvi, <a href="http://linux.die.net/man/1/grohtml">post-grohtml</a> pour le HTML et le XHTML, <a href="http://linux.die.net/man/1/grops">grops</a> pour le PostScript, <a href="http://linux.die.net/man/1/grolbp">grolpb</a> et <a href="http://linux.die.net/man/1/grolj4">grolj4</a> pour les formats d'imprimantes lpb et lj4.
<br />
<h3>2.4 Outils divers</h3>D'autres petits outils facilitant l'usage quotidien de l'écosystème roff sont fournis: <a href="http://linux.die.net/man/1/indxbib">indxbib</a>, <a href="http://linux.die.net/man/1/lkbib">lkbib</a> et <a href="http://linux.die.net/man/1/lookbib">lookbib</a> pour gérer les références bibliographiques, <a href="http://linux.die.net/man/1/afmtodit">afmtodit</a> et <a href="http://linux.die.net/man/1/tfmtodit">tfmtodit</a> pour les polices, <a href="http://linux.die.net/man/1/grog">grog</a> qui détermine la commande groff à appliquer pour mettre en forme le fichier qui lui est proposé en entrée, etc.
<br />
<h3>2.5 Macros</h3>Enfin, l'archive contient des macros. Roff est un langage de formatage de texte, les macros sont des logiciels composés dans ce langage. Roff est moins utilisé que ne l'est Tex, aussi, ces macros sont moins développées que ne le sont LaTeX ou XeTex, néanmoins, elles ont l'avantage de n'être pas très difficiles à modifier. Les usagers avertis de groff, plutôt que de chercher la macro qui va bien, sont habitués à la créer sur mesure. Citons, parmi les macros les plus connues: <a href="http://linux.die.net/man/7/groff_man">man</a>, doc et <a href="http://linux.die.net/man/7/groff_mdoc">mdoc</a>, qui sont faites pour les pages de manuel, <a href="http://linux.die.net/man/7/groff_me">me</a>, <a href="http://linux.die.net/man/7/groff_mm">mm</a> et <a href="http://linux.die.net/man/7/groff_ms">ms</a>, macros ancestrales, récrites pour groff, qui permettent d'écrire des lettres, de la documentation, ou votre thèse de philosophie, <a href="http://linux.die.net/man/7/groff_www">www</a> qui permet de personnaliser les fichiers HTML produits par Groff, et <a href="http://linux.die.net/man/7/groff_mom">mom</a>, macro généraliste et largement configurable, créée à l'origine pour l'écriture d'un roman.
<br />
<h2>3. Utiliser groff</h2><h3>3.1 Philosophie Unix</h3>Cet ensemble d'outils a d'abord été construit selon les principes de la <a href="http://fr.wikipedia.org/wiki/Philosophie_d'Unix">philosophie Unix</a> où un outil est dédié à une tâche, où chaque programme est pensé comme filtre entre des données d'entrées et des données de sorties. La meilleure introduction à Roff est d'ailleurs l'ouvrage <a href="http://oreilly.com/openbook/utp/"><em>Unix text processing</em></a>, de Dale Rougherty et Tim O'Reilly, dont le but est de montrer que les outils Unix forment une interface souple et performante pour la composition de textes. Dès lors, mettre en forme un fichier composé en roff via la macro ms et contenant des tableaux, des équations et des références bibliographiques suppose d'utiliser une longue ligne de commande :
<br />
<code>cat /path/to/ms.tmac fichier | eqn | tbl | refer | troff | grops > fichier.ps</code>
<br />
Ce que groff peut résumer par:
<br />
<code>groff -m ms -etR fichier > fichier.ps</code>
<br />
Ou par:
<br />
<code>`grog fichier` > fichier.ps</code>
<br />
<h3>3.2 Exemple</h3>Nous pouvons, maintenant, composer un fichier au format roff utilisant la macro ms:
<br />
<code>.\" fichier.ms
<br />
.\" Document exemple
<br />
.\" à mettre en forme ainsi:
<br />
.\" `grog fichier.ms` > fichier.ps
<br />
.TL
<br />
Document d'exemple
<br />
.AU
<br />
Sygne@dlfp
<br />
.NH 1
<br />
Exemples divers
<br />
.NH 2
<br />
Exemple de paragraphe
<br />
.PP
<br />
Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
<br />
Sed non risus. Suspendisse lectus tortor, dignissim sitamet,
<br />
adipiscing nec, ultricies sed, dolor.*
<br />
.FS *
<br />
Note de bas de page entre
<br />
FS (Footnote Start) et
<br />
FE (Footnote End).
<br />
.FE
<br />
.NH 2
<br />
Exemple de citations
<br />
.R1
<br />
database biblio.ref
<br />
.R2
<br />
.PP
<br />
Un texte référencé.
<br />
.[
<br />
utp
<br />
.]
<br />
Un autre texte référencé.
<br />
.[
<br />
programming
<br />
.]
<br />
.NH 2
<br />
Exemple de tableau
<br />
.PP
<br />
.TS
<br />
box center tab(|);
<br />
ccc,lcr,rlc.
<br />
center|center|center
<br />
left|center|right
<br />
right|left|center
<br />
.TE
<br />
.NH 2
<br />
Exemple de formule mathématique
<br />
.EQ
<br />
lim from {m -> inf} sum from i=0 to m c sup i
<br />
.EN
<br />
.\" Fin provisoire de fichier.ms
<br />
</code>
<br />
Pour que les références bibliographiques s'affichent, il faut composer le fichier de références biblio.ref ainsi:
<br />
<code># biblio.ref
<br />
%L utp
<br />
%T Unix Text Processing
<br />
%A Dale Dougherty
<br />
%A Tim O'Reilly
<br />
%C Indianapolis
<br />
%I Hayden Books
<br />
%D 1987
<br />
<br />
%T The Unix Programming environment
<br />
%A Brian W. Kernighan
<br />
%A Rob Pike
<br />
<br />
%T Dieu sans l'être
<br />
%A Jean-Luc Marion
<br />
%C Paris
<br />
%I PUF
<br />
%D 1991
<br />
<br />
# fin de biblio.ref
<br />
</code>
<br />
La puissance de l'écosystème roff n'est véritablement sensible que lorsque l'utilisateur est capable d'écrire ses propres macros. Pour apprendre à écrire des macros roff, la lecture de <a href="http://oreilly.com/openbook/utp/">Unix Text Processing</a> est indispensable, mais, en guise de mise en bouche, voici quelques exemples:
<br />
<code># suite de fichier.ms
<br />
.NH 1
<br />
Exemples de macros personnelles
<br />
.de PONCTUATION
<br />
.\" insère les espaces corrects
<br />
.\" espace insécable:
<br />
.char : \~:
<br />
.\" espaces fines insécables:
<br />
.char ; \|;
<br />
.char ? \|?
<br />
.char ! \|!
<br />
.char \[Fo] \[Fo]\|
<br />
.char \[Fc] \|\[Fc]
<br />
..
<br />
.de CROIX
<br />
.\" rature un mot d'une croix
<br />
.\" .s: point size of text
<br />
.\" \Z' word' : print word with 0 width and height
<br />
.\" \D'l x y': draw a line until point (x;y)
<br />
.\" \h' x': move horizontaly of x units.
<br />
.\" \w'\$1': length of word $1
<br />
.nr size (\\n[.s]*75/100)
<br />
\Z'\\$1'\D'l \w'\\$1'u -\\n[size]p'\h' -\w'\\$1'u\v' 1m'\D'l \w'\\$1'u \\n[size]p'
<br />
..
<br />
.NH 2
<br />
Exemple de ponctuation
<br />
.PONCTUATION
<br />
.PP
<br />
Mais que dire? Rien?! Non, il faut dire cela:
<br />
«Ne rien dire, c'est tout dire; tout dire, c'est ne rien
<br />
dire!»
<br />
.NH 2
<br />
Exemple de mot barré
<br />
.PP
<br />
«Le nom de
<br />
.CROIX Dieu
<br />
qui se croise parce qu'il se crucifie, relève-t-il
<br />
de l'être?»
<br />
.[
<br />
Dieu
<br />
%P 106
<br />
.]
<br />
.\" Fin de fichier.ms
<br />
</code>
<br />
Pour en savoir plus, vous pouvez consulter :<ul><li><a href="http://www.gnu.org/software/groff/manual/html_node/index.html">Le manuel complet de groff</a>.
<br />
</li><li><a href="http://lists.gnu.org/archive/html/groff/">La mailing-list de groff</a>. C'est aussi le lieu de rendez-vous de tous les amateurs de roff, quelle que soit sa version.
<br />
</li><li><a href="http://troff.org">Le site de troff</a> contenant de nombreux liens, un historique et une présentation de la communauté.
<br />
</li><li><a href="http://www.netadmintools.com/html/7roff.man.html">Une page de manuel résumant l'histoire de roff</a>.
<br />
</li><li><a href="http://tug.org/interviews/interview-files/werner-lemberg.html">Une interview de Werner Lemberg</a></li></ul></div><div><a href="https://linuxfr.org/news/groff-sort-en-version-121.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/26693/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/news/groff-sort-en-version-121#comments">ouvrir dans le navigateur</a>
</p>
Sygnehttps://linuxfr.org/nodes/26693/comments.atomtag:linuxfr.org,2005:Diary/299082010-07-01T10:24:31+02:002010-07-01T10:24:31+02:00Le successeur de TeX
Hier, Donald Knuth a enfin révélé le contenu de son fameux "Earthshaking Announcement" [1] à l'occasion du 32e anniversaire de Tex: <b>iTex</b> sera le successeur de Tex.<br />
En attendant d'avoir la vidéo de la conférence, on peut déjà avoir un avant-goût du brillant futur de iTeX sur twitter. [2]<br />
Parmi les principales nouveautés<br />
<br />
- Correction des défauts de tex78<br />
- utilisation d'XML<br />
- précision arbitrairement petite ou grande pour les unités<br />
- nombres irrationnels<br />
- autolayout<br />
- pas de séquence d'échappement<br />
- reconnaissance vocale<br />
<br />
[1] <a href="http://www-cs-faculty.stanford.edu/~knuth/news.html#lectures">http://www-cs-faculty.stanford.edu/~knuth/news.html#lectures</a><br />
[2] <a href="http://twitter.com/jeyjey/status/174536">http://twitter.com/jeyjey/status/174536</a><br />
<a href="http://twitter.com/BruceJillis/status/1747250890636900">http://twitter.com/BruceJillis/status/1747250890636900</a><br />
<a href="http://twitter.com/jeyjey/status/17453931854">http://twitter.com/jeyjey/status/17453931854</a><br />
<a href="http://twitter.com/christopheradam/status/17453485243">http://twitter.com/christopheradam/status/17453485243</a><br />
<br />
Pour finir, une image qui résume assez fidèlement le contenu de la conf: <a href="http://www.ibiblio.org/Dave/Dr-Fun/df200002/df20000210.jpg">http://www.ibiblio.org/Dave/Dr-Fun/df200002/df20000210.jpg</a><br />
<br />
Longue vie à iTex \o/
<p>
<i><b>NdM</b> Il s'agit bien entendu d'une plaisanterie de Knuth, habitué à parsemer ses travaux de pointes d'humour</i>
</p><div><a href="https://linuxfr.org/users/darkhad/journaux/le-successeur-de-tex.epub">Télécharger ce contenu au format EPUB</a></div> <p>
<strong>Commentaires :</strong>
<a href="//linuxfr.org/nodes/56190/comments.atom">voir le flux Atom</a>
<a href="https://linuxfr.org/users/darkhad/journaux/le-successeur-de-tex#comments">ouvrir dans le navigateur</a>
</p>
boqhttps://linuxfr.org/nodes/56190/comments.atom