<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:planet="http://planet.intertwingly.net/" xmlns:indexing="urn:atom-extension:indexing" indexing:index="no"><access:restriction xmlns:access="http://www.bloglines.com/about/specs/fac-1.0" relationship="deny"/>
  <title>OCamlcore Planet</title>
  <updated>2010-02-09T14:00:25Z</updated>
  <generator uri="http://intertwingly.net/code/venus/">Venus</generator>
  <author>
    <name>OCamlcore Admins</name>
    <email>planet@ocamlcore.org</email>
  </author>
  <id>http://planet.ocamlcore.org/atom.xml</id>
  <link href="http://planet.ocamlcore.org/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://planet.ocamlcore.org" rel="alternate"/>

  <entry>
    <id>http://alan.petitepomme.net/cwn/2010.02.09.html</id>
    <link href="http://alan.petitepomme.net/cwn/2010.02.09.html" rel="alternate" type="text/html"/>
    <title>Caml Weekly News, 09 Feb 2010</title>
    <summary>Thread safe heterogenous property lists (dictionaries) / Inside the mind of the inliner / New releases of Ocsigen server, Eliom and O'Browser / Blahcaml 2.0 and Camlhighlight 1.0 / OCaml-Java project: 1.4 release / Other Caml News</summary>
    <updated>2010-02-09T12:00:00Z</updated>
    <source>
      <id>http://alan.petitepomme.net/cwn/</id>
      <author>
        <name>Caml Weekly News</name>
      </author>
      <link href="http://alan.petitepomme.net/cwn/" rel="alternate" type="text/html"/>
      <link href="http://alan.petitepomme.net/cwn/cwn.rss" rel="self" type="application/rss+xml"/>
      <subtitle>News frow the Caml list</subtitle>
      <title>Caml Weekly News</title>
      <updated>2010-02-09T09:00:09Z</updated>
    </source>
  </entry>

  <entry>
    <id>tag:blogger.com,1999:blog-17133288.post-2099428691046376546</id>
    <link href="http://misterpingouin.blogspot.com/feeds/2099428691046376546/comments/default" rel="replies" type="application/atom+xml"/>
    <link href="https://www.blogger.com/comment.g?blogID=17133288&amp;postID=2099428691046376546" rel="replies" type="text/html"/>
    <link href="http://www.blogger.com/feeds/17133288/posts/default/2099428691046376546" rel="edit" type="application/atom+xml"/>
    <link href="http://www.blogger.com/feeds/17133288/posts/default/2099428691046376546" rel="self" type="application/atom+xml"/>
    <link href="http://misterpingouin.blogspot.com/2010/02/quel-effet-ca-fait.html" rel="alternate" type="text/html"/>
    <title>Quel effet ça fait</title>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Quelle différence entre <code>a→b→c</code> et <code>a→b→c</code>? Pour le savoir, lisez ce qui suit.<br/><br/>De temps en temps, je regarde un article scientifique, ou un bout de code, et je n'en suis pas satisfait. Un truc me chiffonne, ça peut se réparer, mais ya autre chose qui cloche, et au fond c'est tout bancal, ça n'en finit pas, et il vaut mieux tout remettre à plat. Ceci est arrivé récemment dans liquidsoap avec le module de décodage de fichier. Ce n'est pas intéressant de détailler, il y a juste un point dont je voulais parler. Mais avant, je trouve que c'est important de dire qu'il faut remettre les choses à plat de temps en temps.<br/><br/>Donc, il s'agit de décodage. Première question: qu'est ce que c'est un décodeur? J'ai mis un peu de temps à essayer plusieurs styles, pour finalement décider <code>input -&gt; buffer -&gt; unit</code>, une fonction qui prend en entrée une méthode pour lire des données, et un buffer pour écrire le résultat du décodage, et qui ne renvoie rien mais remplit le buffer un peu plus à chaque fois qu'on l'appelle.<br/><br/>A côté de cette notion très générique on a des notions plus spécialisées comme le <code>type file_decoder = { fill : Frame.t -&gt; unit ; close : unit -&gt; unit }</code>. C'est un enregistrement qui contient une fonction de remplissage de flux (on lui donne une frame (un morceau de flux) à remplir) et une fonction de fermeture/nettoyage où l'on libère les ressources allouées pour le décodage.<br/><br/>Ceci étant décidé, j'écris un bout de code générique qui emballe un décodeur pour construire un décodeur_de_fichier:<pre>let file_decoder filename decoder =<br/>  let input = input_from_file filename in<br/>  let buffer = create_buffer () in<br/>  let fill frame =<br/>    while not_enough_data_in buffer do<br/>      decoder input buffer<br/>    done ;<br/>    fill_frame_from_buffer frame buffer<br/>  in<br/>    { fill = fill ; close = fun () -&gt; close input }<br/></pre><br/>Vous me suivez? Maintenant, j'implémente un décodeur, pour le format MP3 en utilisant la bibliothèque mad:<pre>let create_decoder input =<br/>  let resampler = create_resampler () in<br/>  let mad_stream = Mad.openstream input in<br/>    (fun buffer -&gt;<br/>       let data = Mad.decode_frame_float mad_stream in<br/>       let sample_freq,_,_ = Mad.get_output_format fd in<br/>       let content,length =<br/>         resampler ~audio_src_rate:(float sample_freq) data<br/>       in<br/>         put_audio_in_buffer buffer content length)<br/></pre><br/>PAF! Vous voyez le bug? Je parie que non, en tout cas moi je l'avais raté. J'ai réussi à ne pas être d'accord avec moi même, penser <code>a→b→c</code> ici et <code>a→b→c</code> là!...<br/><br/>Le problème, c'est <em>les effets</em>. En mathématiques, une fonction prend un argument et renvoie un résultat. On ne sait pas comment ça se passe "dedans", en tout cas ça n'interagit pas sur le "dehors", et ça se passe pareil à chaque fois: même entrée, même sortie. En informatique, c'est bien plus compliqué. La fonction interagit avec le monde, elle peut afficher quelquechose à l'écran, elle peut aller chercher un résultat sur internet, dans un fichier, ou simplement dans une case mémoire qu'elle partage avec d'autres fonctions. On est ainsi habitué à avoir tout un paquet de fonctions de type <code>a→b</code>, puisqu'il ne s'agit pas seulement de prendre un objet de type <code>a</code> pour calculer un objet de type <code>b</code> mais aussi potentiellement de se livrer à tout un tas d'interactions avec le monde.<br/><br/>Mon code utilise cela, mais se prend les pieds dedans. Ce qui est joli, c'est que j'ai une "solution". Mais voyons d'abord le problème. Notre décodeur prend un canal d'entrée (<code>input</code>), un canal de sortie (<code>buffer</code>), et est supposé avoir comme <em>effet</em> de lire un peu de données en entrée, de les convertir et les écrire en sortie. Il ne renvoie rien d'utile (<code>unit</code>), tout son interet réside dans l'effet; si on l'appelle un assez grand nombre de fois, on finit par avoir assez de données dans notre buffer -- c'est ce qu'on a fait plus haut. On peut cacher un certains nombres d'informations dans le décodeur, c'était mon intention, par exemple j'y ai alloué un <em>resampler</em> pour convertir les données vers la bonne fréquence d'échantillonage: cet outil doit être (et est bien) crée une fois et une seule pour chaque décodeur.<br/><br/>Ce resampler maintient un état interne, tout comme le décodeur mad (<code>mad_stream</code>). Allouer ces objets est aussi un effet! Mais à quel moment a-t-il lieu? Le type ne l'indique pas: dans <code>input-&gt;buffer-&gt;unit</code>, après quel argument un effet peut-il avoir lieu? Dans le code de <code>file_decoder</code> j'utilise un décodeur comme si le seul effet était le décodage, qui a lieu une fois qu'on a renseigné l'input et l'output. Mais dans le code du décodeur MP3, pas le choix, je m'autorise un effet entre le moment où on m'a donné l'input et le moment où on me donne le décodeur. Résultat, quand on utilise <code>file_decoder</code> avec le <code>create_decoder</code> MP3, on a un son tout haché, car le décodeur et le resampleur sont reinitialisés sans arrêt, ce qui provoque la perte d'une partie des données mémorisées dans leurs buffers internes.<br/><br/>Ces problèmes sont très vicieux, et sont toujours un sujet de recherche active. Mais concrètement, que peut-on y faire avec les outils d'aujourd'hui? Documenter, espérer que tout le monde se comprend? Pas terrible, j'ai réussi à être en désaccord avec moi-même sur une courte période de temps. Comme d'habitude, <em>ce serait bien si le système de type nous servait de garde fou</em>.<br/><br/>En logique, la notion de focalisation (<em>focusing</em>) est liée à la question des effets. Une formule logique est vue comme un jeu entre deux joueurs: un qui prouve l'autre qui réfute, ou encore, l'environnement qui fournit une entrée (argument) et la machine qui renvoie une sortie (valeur de retour). Les connecteurs logiques sont attribués à l'un ou à l'autre joueur: dans <code>(int*int)→(int*int)</code> c'est d'abord l'environnement qui donne un argument, directement composé de deux entiers; puis la machine calcule un résultat, directement composé de deux entiers. Ici je dis directement, car on ne peut pas demander une réponse partielle à la machine, tout ceci vient d'un coup, une unique réponse à une seule question. La dynamique associée au type <code>int→int→(int*int)</code> est exactement la même: il n'y a pas deux questions à l'environnement, mais une seule, les deux entiers en entrée arrivent d'un coup. Là dedans, les seuls effets ne peuvent donc se situer qu'à l'interface entre les deux joueurs, dans le calcul qui se passe entre une question et une réponse.<br/><br/>Commençons à redescendons sur terre. Pour introduire la possibilité d'un effet, en focalisation, on peut introduire un délai. Par exemple, si on veut une paire d'entiers paresseuse (dont le contenu n'est calculé que si nécessaire), on retarde le calcul des <code>int</code>: <code>(unit-&gt;int)*(unit-&gt;int)</code>. Dans l'autre sens, on peut aussi vouloir retarder le moment où un argument est passé, par exemple avec <code>a-&gt;(unit*(b-&gt;c))</code>... c'est ce qu'il nous faut!<br/><br/>On la refait avec un délai autour du décodeur, implémenté non pas comme <code>(unit*...)</code> mais plus agréablement avec un type variant:<pre>type decoder = Decoder of (buffer -&gt; unit)<br/>type file_decoder = input -&gt; decoder<br/><br/>let file_decoder filename decoder =<br/>  let input = input_from_file filename in<br/>  let buffer = create_buffer () in<br/>  let Decoder f = decoder input in<br/>  let fill frame =<br/>    while not_enough_data_in buffer do<br/>      f buffer<br/>    done ;<br/>    fill_frame_from_buffer frame buffer<br/>  in<br/>    { fill = fill ; close = fun () -&gt; close input }<br/><br/>let create_decoder input =<br/>  let resampler = create_resampler () in<br/>  let mad_stream = Mad.openstream input in<br/>    Decoder (fun buffer -&gt;<br/>       let data = Mad.decode_frame_float mad_stream in<br/>       let sample_freq,_,_ = Mad.get_output_format fd in<br/>       let content,length =<br/>         resampler ~audio_src_rate:(float sample_freq) data<br/>       in<br/>         put_audio_in_buffer buffer content length)<br/></pre><br/>Le code du décodeur MP3 n'a changé que d'un iota, mais cela suffit à forcer sa bonne utilisation dans <code>file_decoder</code>, c'est à dire à passer l'input une fois pour toute, et ne plus passer que le buffer dans les appels suivants. Vraiment? Non, à vrai dire, on peut toujours se prendre les pieds dedans, ne serait-ce que parce que c'est possible de traduire entre le vieux type de décodeur et le nouveau, en violant ainsi la logique qu'on a tenté de forcer. Mais en pratique, ce petit garde fou pousse à faire naturellement la bonne chose, ou au moins à se poser la question.<br/><br/>Tout est bien qui fini bien. Cette histoire pourrait aussi s'intituler "à quoi diable pourrait bien servir un type variant avec un seul constructeur?" Ou encore, "c'est fou comme de belles idées théoriques ont du sens même en dehors de leur strict cadre théorique."<div class="blogger-post-footer"><img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/17133288-2099428691046376546?l=misterpingouin.blogspot.com" width="1"/></div></div>
    </content>
    <updated>2010-02-08T19:28:56Z</updated>
    <published>2010-02-08T19:04:00Z</published>
    <category scheme="http://www.blogger.com/atom/ns#" term="ocaml"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="types"/>
    <category scheme="http://www.blogger.com/atom/ns#" term="liquidsoap"/>
    <author>
      <name>mrpingouin</name>
      <email>noreply@blogger.com</email>
    </author>
    <source>
      <id>tag:blogger.com,1999:blog-17133288</id>
      <author>
        <name>mrpingouin</name>
        <email>noreply@blogger.com</email>
      </author>
      <link href="http://misterpingouin.blogspot.com/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/>
      <link href="http://www.blogger.com/feeds/17133288/posts/default/-/ocaml" rel="self" type="application/atom+xml"/>
      <link href="http://misterpingouin.blogspot.com/search/label/ocaml" rel="alternate" type="text/html"/>
      <link href="http://pubsubhubbub.appspot.com/" rel="hub" type="text/html"/>
      <subtitle>Journal d'un pingouin à côté de la plaque comme il se doit, thésard en info, geekesque de l'avis de tous, abracadabrant selon certains, etc.</subtitle>
      <title>Blogue à tabac</title>
      <updated>2010-02-09T04:15:26Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>tag:le-gall.net,2010-02-04:/sylvain+violaine/blog/54</id>
    <link href="http://le-gall.net/sylvain+violaine/blog/index.php?2010/02/04/54-fosdem-2010" rel="alternate" type="text/html"/>
    <title xml:lang="en">FOSDEM 2010</title>
    <summary xml:lang="en">Last year, I was not able to attend FOSDEM due to last minute problems. However, this year I will be there and even attend the Debian for some periods ([http://wiki.debian.org/DebianEvents/FOSDEM/2010]).


I will bring my Openbrick NG with a standard Debian Lenny and probably a Babelbox...</summary>
    <content type="xhtml" xml:lang="en"><div xmlns="http://www.w3.org/1999/xhtml"><p>Last year, I was not able to attend FOSDEM due to last minute problems. However, this year I will be there and even attend the Debian for some periods (<a href="http://le-gall.net/sylvain+violaine/blog/see here">[http://wiki.debian.org/DebianEvents/FOSDEM/2010</a>]).</p>


<p>I will bring my Openbrick NG with a standard Debian Lenny and probably a Babelbox installation. The Openbrick is a VIA C3 fanless computer. It is not very exotic but it is quite interesting to see this kind of hardware. For years, I have tried to build/use fanless computer. This is not a very popular topic but it introduces problems of heat and noise at a higher level.</p>


<p>I am still setting up the Babelbox, which should have been a Debian Lenny RC1. I will try to upgrade it to Debian Lenny 5.0.3.</p>


<p>See you at FOSDEM 2010.</p>


<p><a href="http://www.fosdem.org"><img alt="I'm going to FOSDEM, the Free and Open Source Software Developers' European Meeting" src="http://www.fosdem.org/promo/going-to"/></a></p></div>
    </content>
    <updated>2010-02-04T10:14:52Z</updated>
    <category label="Debian" term="Debian"/>
    <author>
      <name>gildor</name>
    </author>
    <source>
      <id>tag:le-gall.net,2010:/sylvain+violaine/blog/index.php</id>
      <link href="http://le-gall.net/sylvain+violaine/blog/index.php" rel="alternate" type="text/html"/>
      <link href="http://le-gall.net/sylvain+violaine/blog/atom.php" rel="self" type="application/atom+xml"/>
      <subtitle xml:lang="en">Debian and OCaml news</subtitle>
      <title xml:lang="en">Blog of Sylvain Le Gall</title>
      <updated>2010-02-04T10:14:52Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://forge.ocamlcore.org/forum/forum.php?forum_id=531</id>
    <link href="http://forge.ocamlcore.org/forum/forum.php?forum_id=531" rel="alternate" type="text/html"/>
    <title>OCaml Unix course, the threads chapter is translated</title>
    <summary>Thanks to the translation of Eric Cooper and the proofreading job of Prashanth Mundkur, the threads chapter of Xavier Leroy and Didier Rémy's course on Unix system programming in Objective Caml is now available in english for your reading pleasure [1].

[1] http://ocamlunix.forge.ocamlcore.org/threads.html</summary>
    <updated>2010-02-04T04:39:17Z</updated>
    <category term="Unix system programming in OCaml"/>
    <author>
      <name>Daniel Bünzli</name>
    </author>
    <source>
      <id>http://forge.ocamlcore.org</id>
      <link href="http://forge.ocamlcore.org" rel="alternate" type="text/html"/>
      <link href="http://forge.ocamlcore.org/export/rss_sfnews.php" rel="self" type="application/rdf+xml"/>
      <rights>Copyright 1999-2000 VA Linux Systems, Inc.</rights>
      <subtitle>OCamlForge Project News Highlights</subtitle>
      <title>OCamlForge Project News</title>
      <updated>2010-02-09T14:00:23Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>http://rwmj.wordpress.com/?p=1189</id>
    <link href="http://rwmj.wordpress.com/2010/02/03/on-the-awesomeness-of-ocaml-bitstring/" rel="alternate" type="text/html"/>
    <title>On the awesomeness of ocaml-bitstring</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">I used bitstring to reverse engineer the Windows registry “hive” format.  I know that bitstring is my own program, but coming back to it two years after I wrote it and using it again for this, I really think this is a brilliant tool.  (Bitstring wasn’t my idea — it was inspired by [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rwmj.wordpress.com&amp;blog=6840703&amp;post=1189&amp;subd=rwmj&amp;ref=&amp;feed=1"/></div>
    </summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><br/><p>I used <a href="http://code.google.com/p/bitstring/">bitstring</a> to reverse engineer the <a href="http://en.wikipedia.org/wiki/Windows_Registry">Windows registry “hive” format</a>.  I know that bitstring is my own program, but coming back to it two years after I wrote it and using it again for this, I really think this is a brilliant tool.  (Bitstring wasn’t my idea — it was inspired by the <a href="http://ftp.sunet.se/pub/lang/erlang/euc/07/papers/1700Gustafsson.pdf">bitstring manipulation feature in Erlang</a>).</p>
<p>C is supposed to be a good natural programming language for dealing with bits and bytes, right?  The ocaml-bitstring program, which analyzes hive files in far more detail than the C program, is half the size and just as fast.</p>
<p>As an example, here’s how we load the hive file and analyze the first part of the header:</p>
<pre style="background-color: #fcfcfc; border-left: 6px solid #f0f0f0; margin-left: 1em; font-size: 120%; padding: 5px;"><span style="color: red;">let</span> <span style="color: blue;">bits</span> <span style="color: red;">=</span> bitstring_of_file filename

<span style="color: green;">(* Split into header + data at the 4KB boundary. *)</span>
<span style="color: red;">let</span> <span style="color: blue;">header, data</span> <span style="color: red;">=</span>
  takebits (4096 * 8 ) bits, dropbits (4096 * 8 ) bits

<span style="color: red;">let</span> () <span style="color: red;">=</span>
  <span style="color: red;">bitmatch</span> header <span style="color: red;">with</span>
  { "regf" : 4*8 : string;
    <span style="color: blue;">seq1</span> : 4*8 : littleendian;
    <span style="color: blue;">seq2</span> : 4*8 : littleendian, check (seq1 = seq2);
    <span style="color: blue;">last_modified</span> : 64
      : littleendian, bind (nt_to_time_t last_modified);
    1_l <span style="color: green;">(* major *)</span> : 4*8 : littleendian;
    <span style="color: blue;">minor</span> : 4*8 : littleendian } -&gt;
      <span style="color: green;">(* ... *)</span>
</pre>
<p>The bitmatch statement elegantly matches the file.  It rejects the file if the first four bytes aren’t “regf” (the file magic number) or if the major version number is not 1.  It then unpacks the following fields, converting from the file’s littleendian ordering to host ordering, converting the <a href="http://support.microsoft.com/kb/167296">NT timestamp</a> into a time_t and so on.</p>
<p>Although not shown there, bitstring will also work just fine on arbitrary bit boundaries, albeit more slowly because the generated code is able to make fewer optimizations.</p>
<p>Even though the Windows hive file format is moronic, I successfully used bitstring to reverse engineer it in about 3 days, with some help from the contradictory and often incorrect public documentation out there.</p>
  <a href="http://feeds.wordpress.com/1.0/gocomments/rwmj.wordpress.com/1189/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/rwmj.wordpress.com/1189/"/></a> <a href="http://feeds.wordpress.com/1.0/godelicious/rwmj.wordpress.com/1189/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/rwmj.wordpress.com/1189/"/></a> <a href="http://feeds.wordpress.com/1.0/gostumble/rwmj.wordpress.com/1189/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/rwmj.wordpress.com/1189/"/></a> <a href="http://feeds.wordpress.com/1.0/godigg/rwmj.wordpress.com/1189/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/rwmj.wordpress.com/1189/"/></a> <a href="http://feeds.wordpress.com/1.0/goreddit/rwmj.wordpress.com/1189/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/rwmj.wordpress.com/1189/"/></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=rwmj.wordpress.com&amp;blog=6840703&amp;post=1189&amp;subd=rwmj&amp;ref=&amp;feed=1"/></div>
    </content>
    <updated>2010-02-03T22:52:53Z</updated>
    <category term="Uncategorized"/>
    <category term="bitmatch"/>
    <category term="bitstring"/>
    <category term="hive"/>
    <category term="ocaml"/>
    <author>
      <name>rich</name>
    </author>
    <source>
      <id>http://rwmj.wordpress.com</id>
      <logo>http://www.gravatar.com/blavatar/f46ee3188fd42abe3209dad10af39983?s=96&amp;d=http://s.wordpress.com/i/buttonw-com.png</logo>
      <link href="http://rwmj.wordpress.com/tag/ocaml/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://rwmj.wordpress.com" rel="alternate" type="text/html"/>
      <link href="http://rwmj.wordpress.com/osd.xml" rel="search" type="application/opensearchdescription+xml"/>
      <subtitle>Everyone complains about the fish, so we got rid of the fish and replaced them with ocha-ken tea dogs</subtitle>
      <title>Richard WM Jones » ocaml</title>
      <updated>2010-02-09T13:00:26Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>https://mancoosi.org/301 at https://mancoosi.org/~abate</id>
    <link href="https://mancoosi.org/~abate/extlib-optparse-part-2" rel="alternate" type="text/html"/>
    <title>ExtLib OptParse (part 2)</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>I've already wrote <a href="https://mancoosi.org/extlib-optparse-module-options-parsing-made-easy-and-clean">something</a> about OptParse last month. Today I discovered how to create a new option (that is not a string, int or bool) and validate it within the arg parser.</p>

<p>So suppose we want to write an application that can output both txt and html and we want the user to specify the format with command line option. One way would be to use a <span class="geshifilter"><code class="text geshifilter-text">StdOpt.str_option</code></span> - eventually with a default option - and to retrive it in application code with <span class="geshifilter"><code class="text geshifilter-text">OptParse.Opt.get</code></span>.</p>

<p>However this is not satisfactory as we are mixing the application code with command line parsing. A better way is to create a new type of option with <span class="geshifilter"><code class="text geshifilter-text">Opt.value_option</code></span> .</p>

<p>This is the concept :</p>

<p/><div class="geshifilter"><div class="ocaml geshifilter-ocaml" style="font-family: monospace;"><span style="color: #06c; font-weight: bold;">type</span> out_t <span style="color: #a52a2a;">=</span> Txt <span style="color: #a52a2a;">|</span> Html<br/>
<span style="color: #06c; font-weight: bold;">module</span> Options <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">struct</span><br/>
  <span style="color: #06c; font-weight: bold;">open</span> OptParse<br/>
  <span style="color: #06c; font-weight: bold;">exception</span> <span style="color: #06c; font-weight: bold;">Format</span><br/>
  <span style="color: #06c; font-weight: bold;">let</span> out_option ?default ?<span style="color: #6c6;">(</span>metavar <span style="color: #a52a2a;">=</span> <span style="color: #3cb371;">"&lt;txt|html&gt;"</span><span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span> <span style="color: #a52a2a;">=</span><br/>
    <span style="color: #06c; font-weight: bold;">let</span> corce <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span><br/>
      <span style="color: #a52a2a;">|</span><span style="color: #3cb371;">"txt"</span> <span style="color: #a52a2a;">-&gt;</span> Txt<br/>
      <span style="color: #a52a2a;">|</span><span style="color: #3cb371;">"html"</span> <span style="color: #a52a2a;">-&gt;</span> Html<br/>
      <span style="color: #a52a2a;">|</span> _ <span style="color: #a52a2a;">-&gt;</span> <span style="color: #06c; font-weight: bold;">raise</span> <span style="color: #06c; font-weight: bold;">Format</span><br/>
    <span style="color: #06c; font-weight: bold;">in</span><br/>
    <span style="color: #06c; font-weight: bold;">let</span> error _ s <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">Printf</span><span style="color: #a52a2a;">.</span><span style="color: #060;">sprintf</span> <span style="color: #3cb371;">"%s format not supported"</span> s <span style="color: #06c; font-weight: bold;">in</span><br/>
    Opt<span style="color: #a52a2a;">.</span><span style="color: #060;">value_option</span> metavar default corce error<br/>
<br/>
  <span style="color: #06c; font-weight: bold;">let</span> <span style="color: #06c; font-weight: bold;">output</span> <span style="color: #a52a2a;">=</span> out_option ~default<span style="color: #a52a2a;">:</span>Txt <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span><br/>
<br/>
  <span style="color: #06c; font-weight: bold;">let</span> description <span style="color: #a52a2a;">=</span> <span style="color: #3cb371;">"This is an example"</span><br/>
  <span style="color: #06c; font-weight: bold;">let</span> options <span style="color: #a52a2a;">=</span> OptParser<span style="color: #a52a2a;">.</span><span style="color: #060;">make</span> ~description<span style="color: #a52a2a;">:</span>description <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span><br/>
<br/>
  <span style="color: #06c; font-weight: bold;">open</span> OptParser<br/>
  add options ~short_name<span style="color: #a52a2a;">:'</span>o<span style="color: #a52a2a;">'</span> ~long_name<span style="color: #a52a2a;">:</span><span style="color: #3cb371;">"out"</span> ~help<span style="color: #a52a2a;">:</span><span style="color: #3cb371;">"Output type"</span> <span style="color: #06c; font-weight: bold;">output</span><span style="color: #a52a2a;">;</span><br/>
<span style="color: #06c; font-weight: bold;">end</span></div></div><p/>

<p>Note that the function <span class="geshifilter"><code class="text geshifilter-text">Opt.value_option</code></span> get a default value, a metavar - that is the sting associated with the option in the help ( <span class="geshifilter"><code class="text geshifilter-text"> -o&lt;txt|html&gt;, --out=&lt;txt|html&gt; Output type </code></span> ), a corce function, that is, a function that transforms a string in the desired type, and an error function that is used by the parser to give a meaningful error is the option is not correctly validated.</p>

<p>For example :  </p><div class="geshifilter"><div class="text geshifilter-text" style="font-family: monospace;">$./test.native -oooo<br/>
usage: test.native [options]<br/>
<br/>
test.native: option '-o': ooo format not supported</div></div><p/>

<p>Now when we use this new option in the application code with <span class="geshifilter"><code class="text geshifilter-text">OptParse.Opt.get</code></span> and we can be certain that it was correctly validated.</p></div>
    </summary>
    <updated>2010-02-03T13:03:16Z</updated>
    <category scheme="https://mancoosi.org/~abate/tags/ocaml" term="ocaml"/>
    <author>
      <name>abate</name>
    </author>
    <source>
      <id>https://mancoosi.org/~abate/taxonomy/term/5/0</id>
      <link href="https://mancoosi.org/~abate/taxonomy/term/5/0" rel="alternate" type="text/html"/>
      <link href="https://mancoosi.org/~abate/taxonomy/term/5/0/feed" rel="self" type="application/rss+xml"/>
      <title>Pietro Abate homepage - ocaml</title>
      <updated>2010-02-09T14:00:25Z</updated>
    </source>
  </entry>

  <entry xml:lang="en-us">
    <id>https://forge.ocamlcore.org/projects/biniou/</id>
    <link href="https://forge.ocamlcore.org/projects/biniou/" rel="alternate" type="text/html"/>
    <title>Biniou</title>
    <summary>Biniou is a fully extensible serialization format, more compact and "faster" than JSON. Applications include exchanging and storing records containing large blobs of data such as images or non-UTF-8 text.</summary>
    <updated>2010-02-03T09:00:22Z</updated>
    <source>
      <id>http://forge.ocamlcore.org</id>
      <author>
        <name>OCamlCore Forge Projects</name>
      </author>
      <link href="http://forge.ocamlcore.org" rel="alternate" type="text/html"/>
      <link href="http://forge.ocamlcore.org/export/rss_sfprojects.php" rel="self" type="application/rss+xml"/>
      <rights>Copyright 1999-2000 VA Linux Systems, Inc.</rights>
      <subtitle>OCamlForge Full Project Listing</subtitle>
      <title>OCamlForge Full Project Listing</title>
      <updated>2010-02-09T02:00:23Z</updated>
    </source>
  </entry>

  <entry>
    <id>http://alan.petitepomme.net/cwn/2010.02.02.html</id>
    <link href="http://alan.petitepomme.net/cwn/2010.02.02.html" rel="alternate" type="text/html"/>
    <title>Caml Weekly News, 02 Feb 2010</title>
    <summary>Format syntax extension / Other Caml News</summary>
    <updated>2010-02-02T12:00:00Z</updated>
    <source>
      <id>http://alan.petitepomme.net/cwn/</id>
      <author>
        <name>Caml Weekly News</name>
      </author>
      <link href="http://alan.petitepomme.net/cwn/" rel="alternate" type="text/html"/>
      <link href="http://alan.petitepomme.net/cwn/cwn.rss" rel="self" type="application/rss+xml"/>
      <subtitle>News frow the Caml list</subtitle>
      <title>Caml Weekly News</title>
      <updated>2010-02-09T09:00:09Z</updated>
    </source>
  </entry>

  <entry xml:lang="fr">
    <id>http://dutherenverseauborddelatable.wordpress.com/?p=677</id>
    <link href="http://dutherenverseauborddelatable.wordpress.com/2010/02/01/transparents-opa/" rel="alternate" type="text/html"/>
    <title>Transparents OPA</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">Je pars pour au Laboratoire d’Informatique Fondamentale d’Orléans donner une présentation sur OPA. Vous pouvez trouver les transparents ici en franglais. Il s’agit d’une introduction technique prévue pour des chercheurs.
Je tâcherai d’ajouter une version commentée un de ces jours.
       <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&amp;blog=1202429&amp;post=677&amp;subd=dutherenverseauborddelatable&amp;ref=&amp;feed=1"/></div>
    </summary>
    <content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><div class="snap_preview"><br/><p style="text-align: justify;">Je pars pour au <a href="http://www.univ-orleans.fr/lifo">Laboratoire d’Informatique Fondamentale d’Orléans</a> donner une présentation sur <a href="http://www.mlstate.com">OPA</a>. Vous pouvez trouver les transparents <a href="http://dutherenverseauborddelatable.files.wordpress.com/2010/02/lifo-2010-sans-animations2.pdf">ici</a> en franglais. Il s’agit d’une introduction technique prévue pour des chercheurs.</p>
<p style="text-align: justify;">Je tâcherai d’ajouter une version commentée un de ces jours.</p>
  <a href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/677/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/677/"/></a> <a href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/677/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/677/"/></a> <a href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/677/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/677/"/></a> <a href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/677/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/677/"/></a> <a href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/677/" rel="nofollow"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/677/"/></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&amp;blog=1202429&amp;post=677&amp;subd=dutherenverseauborddelatable&amp;ref=&amp;feed=1"/></div></div>
    </content>
    <updated>2010-02-01T08:06:07Z</updated>
    <category term="En fran&#xE7;ais / In French"/>
    <category term="Informatique / Computer science"/>
    <category term="OCaml"/>
    <category term="OPA"/>
    <category term="Recherche / Research"/>
    <category term="ajax"/>
    <category term="base de donn&#xE9;es"/>
    <category term="comet"/>
    <category term="concurrence"/>
    <category term="concurrency"/>
    <category term="database"/>
    <category term="distribution"/>
    <category term="erlang"/>
    <category term="f#"/>
    <category term="haskell"/>
    <category term="join calcul"/>
    <category term="langages"/>
    <category term="language"/>
    <category term="lifo"/>
    <category term="paas"/>
    <category term="parall&#xE9;lisme"/>
    <category term="pr&#xE9;sentation"/>
    <category term="programmation"/>
    <category term="Programmation Fonctionnelle"/>
    <category term="programmation web"/>
    <category term="programming"/>
    <category term="recherche"/>
    <category term="research"/>
    <category term="saas"/>
    <category term="sauvegarde"/>
    <category term="syst&#xE8;me de types"/>
    <category term="talk"/>
    <category term="transparents"/>
    <category term="web"/>
    <category term="web 2.0"/>
    <author>
      <name>yoric</name>
    </author>
    <source>
      <id>http://dutherenverseauborddelatable.wordpress.com</id>
      <logo>http://www.gravatar.com/blavatar/b4f8dbeb495eaa4c8ee77515c06383c8?s=96&amp;d=http://s.wordpress.com/i/buttonw-com.png</logo>
      <link href="http://dutherenverseauborddelatable.wordpress.com/category/ocaml/feed/" rel="self" type="application/atom+xml"/>
      <link href="http://dutherenverseauborddelatable.wordpress.com" rel="alternate" type="text/html"/>
      <link href="http://dutherenverseauborddelatable.wordpress.com/osd.xml" rel="search" type="application/opensearchdescription+xml"/>
      <subtitle>De l'actualité, de l'informatique, de l'enseignement, d'intenses réflexions et quelques autres absurdités</subtitle>
      <title>Il y a du thé renversé au bord de la table » OCaml</title>
      <updated>2010-02-02T16:00:11Z</updated>
    </source>
  </entry>

  <entry xml:lang="en">
    <id>https://mancoosi.org/298 at https://mancoosi.org/~abate</id>
    <link href="https://mancoosi.org/~abate/subsets-reference" rel="alternate" type="text/html"/>
    <title>subsets for reference</title>
    <summary type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml"><p>Every now and then I need to write a simple combinatorial algorithm. Using monads this is fairly easy and concise, but probably not the fastest way to do it. We start with the definition of a few functions in terms of the List module. The function themselves are kinda of self explanatory. I write this mostly for reference then for real added value.</p>

<p/><div class="geshifilter"><div class="ocaml geshifilter-ocaml" style="font-family: monospace;"><span style="color: #06c; font-weight: bold;">let</span> return a <span style="color: #a52a2a;">=</span> <span style="color: #6c6;">[</span>a<span style="color: #6c6;">]</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> bind m f <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">List</span><span style="color: #a52a2a;">.</span><span style="color: #060;">flatten</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">List</span><span style="color: #a52a2a;">.</span><span style="color: #060;">map</span> f m<span style="color: #6c6;">)</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> mzero <span style="color: #a52a2a;">=</span> <span style="color: #6c6;">[</span><span style="color: #6c6;">]</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> guard b <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">if</span> b <span style="color: #06c; font-weight: bold;">then</span> return <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span> <span style="color: #06c; font-weight: bold;">else</span> mzero<br/>
<span style="color: #06c; font-weight: bold;">let</span> mplus <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">List</span><span style="color: #a52a2a;">.</span><span style="color: #060;">append</span><br/>
<br/>
<span style="color: #06c; font-weight: bold;">let</span> card l <span style="color: #a52a2a;">=</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">List</span><span style="color: #a52a2a;">.</span><span style="color: #060;">length</span> l<span style="color: #6c6;">)</span><br/>
<br/>
<span style="color: #06c; font-weight: bold;">let</span> <span style="color: #06c; font-weight: bold;">rec</span> subsets <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span><br/>
  <span style="color: #a52a2a;">|</span><span style="color: #6c6;">[</span><span style="color: #6c6;">]</span> <span style="color: #a52a2a;">-&gt;</span> return <span style="color: #6c6;">[</span><span style="color: #6c6;">]</span><br/>
  <span style="color: #a52a2a;">|</span>h <span style="color: #a52a2a;">::</span> t <span style="color: #a52a2a;">-&gt;</span><br/>
      bind <span style="color: #6c6;">(</span>subsets t<span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> t1 <span style="color: #a52a2a;">-&gt;</span><br/>
        mplus <span style="color: #6c6;">(</span><br/>
          bind <span style="color: #6c6;">(</span>return t1<span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> t2 <span style="color: #a52a2a;">-&gt;</span> return <span style="color: #6c6;">(</span>h <span style="color: #a52a2a;">::</span> t2<span style="color: #6c6;">)</span><span style="color: #6c6;">)</span><br/>
        <span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span>return t1<span style="color: #6c6;">)</span><br/>
      <span style="color: #6c6;">)</span><br/>
<br/>
<span style="color: #5d478b; font-style: italic;">(* all subsets with cardinality less then k *)</span><br/>
<span style="color: #5d478b; font-style: italic;">(* [ x | x &lt;- (subsets X) ; |x| &lt;= k ] *)</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> subsets_k k l <span style="color: #a52a2a;">=</span><br/>
  bind <span style="color: #6c6;">(</span>subsets l<span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> x <span style="color: #a52a2a;">-&gt;</span><br/>
    bind <span style="color: #6c6;">(</span>guard <span style="color: #6c6;">(</span>card<span style="color: #6c6;">(</span>x<span style="color: #6c6;">)</span> <span style="color: #a52a2a;">&lt;=</span> k<span style="color: #6c6;">)</span><span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> _ <span style="color: #a52a2a;">-&gt;</span><br/>
      return x<br/>
    <span style="color: #6c6;">)</span><br/>
  <span style="color: #6c6;">)</span><br/>
<br/>
<span style="color: #5d478b; font-style: italic;">(* cartesian product *)</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> cartesian l1 l2 <span style="color: #a52a2a;">=</span><br/>
  bind l1 <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> x <span style="color: #a52a2a;">-&gt;</span><br/>
    bind l2 <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> y <span style="color: #a52a2a;">-&gt;</span><br/>
      return <span style="color: #6c6;">(</span>x,y<span style="color: #6c6;">)</span><br/>
    <span style="color: #6c6;">)</span><br/>
  <span style="color: #6c6;">)</span><br/>
<br/>
<span style="color: #06c; font-weight: bold;">let</span> <span style="color: #06c; font-weight: bold;">rec</span> permutation <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">function</span><br/>
  <span style="color: #a52a2a;">|</span><span style="color: #6c6;">[</span><span style="color: #6c6;">]</span> <span style="color: #a52a2a;">-&gt;</span> return <span style="color: #6c6;">[</span><span style="color: #6c6;">]</span><br/>
  <span style="color: #a52a2a;">|</span>h<span style="color: #a52a2a;">::</span>t <span style="color: #a52a2a;">-&gt;</span><br/>
      bind <span style="color: #6c6;">(</span>permutation t<span style="color: #6c6;">)</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> t1 <span style="color: #a52a2a;">-&gt;</span><br/>
        <span style="color: #06c; font-weight: bold;">List</span><span style="color: #a52a2a;">.</span><span style="color: #060;">map</span> <span style="color: #6c6;">(</span><span style="color: #06c; font-weight: bold;">fun</span> h1 <span style="color: #a52a2a;">-&gt;</span> h1 <span style="color: #a52a2a;">::</span> t1<span style="color: #6c6;">)</span> h<br/>
      <span style="color: #6c6;">)</span></div></div><p/>

<p>The previous version of the code uses the List module. If we want a more space efficient implementation of the same functions, we can use a lazy data structure and substitute the functions in the preamble. In this case, instead of writing a lazy list module from scratch, we simply use the Enum module of ExtLib.</p>

<p/><div class="geshifilter"><div class="ocaml geshifilter-ocaml" style="font-family: monospace;"><span style="color: #06c; font-weight: bold;">open</span> ExtLib<br/>
<span style="color: #06c; font-weight: bold;">let</span> return a <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">let</span> e <span style="color: #a52a2a;">=</span> Enum<span style="color: #a52a2a;">.</span><span style="color: #060;">empty</span> <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span> <span style="color: #06c; font-weight: bold;">in</span> Enum<span style="color: #a52a2a;">.</span><span style="color: #060;">push</span> e a <span style="color: #a52a2a;">;</span> e<br/>
<span style="color: #06c; font-weight: bold;">let</span> bind m f <span style="color: #a52a2a;">=</span> Enum<span style="color: #a52a2a;">.</span><span style="color: #060;">concat</span> <span style="color: #6c6;">(</span>Enum<span style="color: #a52a2a;">.</span><span style="color: #060;">map</span> f m<span style="color: #6c6;">)</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> mzero <span style="color: #a52a2a;">=</span> Enum<span style="color: #a52a2a;">.</span><span style="color: #060;">empty</span> <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span><br/>
<span style="color: #06c; font-weight: bold;">let</span> guard b <span style="color: #a52a2a;">=</span> <span style="color: #06c; font-weight: bold;">if</span> b <span style="color: #06c; font-weight: bold;">then</span> return <span style="color: #6c6;">(</span><span style="color: #6c6;">)</span> <span style="color: #06c; font-weight: bold;">else</span> mzero<br/>
<span style="color: #06c; font-weight: bold;">let</span> mplus <span style="color: #a52a2a;">=</span> Enum<span style="color: #a52a2a;">.</span><span style="color: #060;">append</span></div></div><p/>

<p>In action :</p>

<p/><div class="geshifilter"><div class="text geshifilter-text" style="font-family: monospace;"># subsets_k 1 [1;2];;                      <br/>
- : int list list = [[2]; [1]; []]<br/>
# cartesian [1;2;3] [3;4];;<br/>
- : (int * int) list = [(1, 3); (1, 4); (2, 3); (2, 4); (3, 3); (3, 4)]<br/>
permutation [[1;2;3;4];[5;6];[7;8;9]];;<br/>
- : int list list =<br/>
[[1; 5; 7]; [2; 5; 7]; [3; 5; 7]; [4; 5; 7]; [1; 6; 7]; [2; 6; 7]; [3; 6; 7];<br/>
 [4; 6; 7]; [1; 5; 8]; [2; 5; 8]; [3; 5; 8]; [4; 5; 8]; [1; 6; 8]; [2; 6; 8];<br/>
 [3; 6; 8]; [4; 6; 8]; [1; 5; 9]; [2; 5; 9]; [3; 5; 9]; [4; 5; 9]; [1; 6; 9];<br/>
 [2; 6; 9]; [3; 6; 9]; [4; 6; 9]]</div></div><p/></div>
    </summary>
    <updated>2010-01-26T19:03:34Z</updated>
    <category scheme="https://mancoosi.org/~abate/tags/ocaml" term="ocaml"/>
    <author>
      <name>abate</name>
    </author>
    <source>
      <id>https://mancoosi.org/~abate/taxonomy/term/5/0</id>
      <link href="https://mancoosi.org/~abate/taxonomy/term/5/0" rel="alternate" type="text/html"/>
      <link href="https://mancoosi.org/~abate/taxonomy/term/5/0/feed" rel="self" type="application/rss+xml"/>
      <title>Pietro Abate homepage - ocaml</title>
      <updated>2010-02-09T14:00:25Z</updated>
    </source>
  </entry>
</feed>
