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

<channel>
	<title>Il y a du thé renversé au bord de la table &#187; OCaml</title>
	<atom:link href="http://dutherenverseauborddelatable.wordpress.com/category/ocaml/feed/" rel="self" type="application/rss+xml" />
	<link>http://dutherenverseauborddelatable.wordpress.com</link>
	<description>De l'actualité, de l'informatique, de l'enseignement, d'intenses réflexions et quelques autres absurdités</description>
	<pubDate>Wed, 16 Jul 2008 10:21:30 +0000</pubDate>
	<generator>http://wordpress.org/?v=MU</generator>
	<language>fr</language>
			<item>
		<title>Extrapol update</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/07/04/extrapol-update/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/07/04/extrapol-update/#comments</comments>
		<pubDate>Fri, 04 Jul 2008 11:09:01 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[Extrapol]]></category>

		<category><![CDATA[In English / En anglais]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[Sûreté / Security]]></category>

		<category><![CDATA[abstract interpretation]]></category>

		<category><![CDATA[applied research]]></category>

		<category><![CDATA[c++]]></category>

		<category><![CDATA[caml]]></category>

		<category><![CDATA[checking]]></category>

		<category><![CDATA[code analysis]]></category>

		<category><![CDATA[comprehension]]></category>

		<category><![CDATA[computer science]]></category>

		<category><![CDATA[dependent types]]></category>

		<category><![CDATA[free software]]></category>

		<category><![CDATA[fundamental research]]></category>

		<category><![CDATA[library]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[mac]]></category>

		<category><![CDATA[mandatory access control]]></category>

		<category><![CDATA[model]]></category>

		<category><![CDATA[open-source]]></category>

		<category><![CDATA[policies]]></category>

		<category><![CDATA[program analysis]]></category>

		<category><![CDATA[release]]></category>

		<category><![CDATA[research]]></category>

		<category><![CDATA[science]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[security analysis]]></category>

		<category><![CDATA[security policies]]></category>

		<category><![CDATA[selinux]]></category>

		<category><![CDATA[semantics]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[source code analysis]]></category>

		<category><![CDATA[standard library]]></category>

		<category><![CDATA[static analysis]]></category>

		<category><![CDATA[threat]]></category>

		<category><![CDATA[threat analysis]]></category>

		<category><![CDATA[type systems]]></category>

		<category><![CDATA[type theory]]></category>

		<category><![CDATA[types and effects]]></category>

		<category><![CDATA[vulnerability analysis]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=107</guid>
		<description><![CDATA[A quick work regarding the current status of Extrapol and its release.
Development of Extrapol progresses. With our current set of sample, Extrapol works flawlessly. We&#8217;re now adding features, improving error reporting and de-hard-wiring the model of the C standard library from the tool and moving it towards an external configuration file as well as progressively [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p>A quick work regarding the current status of Extrapol and its release.</p>
<p style="text-align:justify;">Development of Extrapol progresses. With our current set of sample, Extrapol works flawlessly. We&#8217;re now adding features, improving error reporting and de-hard-wiring the model of the C standard library from the tool and moving it towards an external configuration file as well as progressively moving towards larger and more realistic samples. Development will come to an abrupt (and temporary) halt at the end of this week, though, due to personal matters (i.e. I&#8217;m getting married).</p>
<p style="text-align:justify;">The release planned for next week, on the other hand, is canceled. As the research field of applied security is very competitive, and after careful discussion with the rest of my research team, we have decided to only release a version of Extrapol after the scientific content has been accepted for publication in a conference or journal. At the request of one of the institutes which founds this research, I will also refrain from posting detailed information on the theory and algorithms behind Extrapol, until these are cleared by the institute and accepted for publication. Without entering the details, Extrapol is expected to serve in critical infrastructures, which explains the need for clearance.</p>
<p style="text-align:justify;">However, rest assured that there <em>will</em> be a release and it <em>will</em> be open-source (presumably licenced under a combination of MIT and LGPL). The only question is when &#8212; and this probably won&#8217;t happen before November.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/107/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/107/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/107/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/107/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/107/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=107&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/07/04/extrapol-update/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Improving exception-management in OCaml</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/07/02/improving-exception-management-in-ocaml/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/07/02/improving-exception-management-in-ocaml/#comments</comments>
		<pubDate>Wed, 02 Jul 2008 14:46:28 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[In English / En anglais]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[camlp4]]></category>

		<category><![CDATA[catch]]></category>

		<category><![CDATA[code generation]]></category>

		<category><![CDATA[code rewriting]]></category>

		<category><![CDATA[compiler support]]></category>

		<category><![CDATA[coverage]]></category>

		<category><![CDATA[error]]></category>

		<category><![CDATA[error management]]></category>

		<category><![CDATA[exceptional situation]]></category>

		<category><![CDATA[exceptions]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<category><![CDATA[guarantees]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[languages]]></category>

		<category><![CDATA[ml]]></category>

		<category><![CDATA[monad]]></category>

		<category><![CDATA[performance]]></category>

		<category><![CDATA[preprocessor]]></category>

		<category><![CDATA[Programmation Fonctionnelle]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[programming languages]]></category>

		<category><![CDATA[rewriting]]></category>

		<category><![CDATA[sml]]></category>

		<category><![CDATA[static analysis]]></category>

		<category><![CDATA[syntactic sugar]]></category>

		<category><![CDATA[try]]></category>

		<category><![CDATA[type-safe]]></category>

		<category><![CDATA[typed]]></category>

		<category><![CDATA[types]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=105</guid>
		<description><![CDATA[Catch me if you can is a small library for OCaml 3.10. The latest release is version 0.2, which you may find <a href="http://www.univ-orleans.fr/lifo/Members/David.Teller/software/exceptions/catch_0_2.tgz">here</a>. This library improves management of errors in OCaml. It is released under the LGPL licence. It has been written by David Teller, Arnaud Spiwack, Till Varoquaux and Gabriel Scherer.]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><h2 style="text-align:justify;">Short version</h2>
<p style="text-align:justify;">Catch me if you can is a small library for OCaml 3.10. The latest release is version 0.2, which you may find <a href="http://www.univ-orleans.fr/lifo/Members/David.Teller/software/exceptions/catch_0_2.tgz">here</a>. This library improves management of errors in OCaml. It is released under the LGPL licence. It has been written by David Teller, Arnaud Spiwack, Till Varoquaux and Gabriel Scherer.</p>
<p><span id="more-105"></span></p>
<hr />
<h2><strong>Long version<br />
</strong></h2>
<p align="justify">As all languages of the ML family &#8212; and most modern languages indeed &#8212; OCaml permits the management of exceptional situations using <em>exceptions</em>. This mechanism lets programmer register protected sections of code, as well as <em>exception handlers</em> to handle any exception which may be <em>raised</em> during the execution of a protected section. Whenever an exception is <em>raised</em>, the protected section of code is immediately stopped and the corresponding exception handler is executed instead. In addition, exceptions may convey some information regarding the nature of the exceptional circumstance.</p>
<p align="justify">In OCaml, the mechanism is fast, it&#8217;s convenient and it&#8217;s type-safe, much like the rest of the language (barring any type-unsafe interaction with C). However, a few things are missing. If we consider the rest of the language, exceptions are both heavyweight and clumsy: each exception must be declared before being used and there&#8217;s no way to introduce a polymorphic type parameter in the exception. In addition, languages such as Java offer to important features missing in OCaml: automatic case coverage and exception hierarchies. While <a href="http://caml.inria.fr/pub/old_caml_site/ocamlexc/ocamlexc.htm">a nice tool</a> exists  to provide case coverage for exceptions in OCaml, this tool is complex and  unfortunately unmaintained.</p>
<p align="justify"><em>Catch me if you can</em> offers an alternative mechanism, comparable to ML exceptions, to handle errors. In comparison with OCaml&#8217;s native exception mechanism, this library adds:</p>
<ul>
<li>automatic inference of exceptions (i.e. no need to declare your exceptions, unless you want to)</li>
<li>more flexible exceptions (i.e. exceptions may have polymorphic type parameters, constraints, etc.)</li>
<li>hierarchies (i.e. an IOException is a sub-case of Exception and a super-case of NetworkException)</li>
<li>case coverage (i.e. the compiler can tell you if you forgot a case or sometimes if you wrote useless ones)</li>
<li>conditional success handlers (i.e. do something with the result in case of success)</li>
<li>conditional success-and-failure handlers (i.e. &#8220;finally&#8221;).</li>
</ul>
<p style="text-align:justify;">To attain this, we replace the mechanism of exceptions by an error monad, we replace exception constructors with polymorphic variants and we introduce a dose of syntactic sugar.</p>
<hr />
<h2>Examples</h2>
<h3>Expression evaluator</h3>
<p>Let&#8217;s write a simple expression evaluator for the following set of expressions:</p>
<pre name="code" class="python">

type expr =
  | Value of float
  | Div     of expr * expr
  | Add    of expr * expr
  | Mult   of expr * expr
  | Subs  of expr * expr
</pre>
<p>These may be evaluated using the following function:</p>
<pre name="code" class="python">

let rec eval = function
 | Value x    -&gt; x
 | Add (x,y) -&gt; eval x +. eval y
 | Mult(x,y)  -&gt; eval x *. eval y
 | Div(x,y)   -&gt; eval x /. eval y
 | Subs(x,y) -&gt; eval x -. eval y
</pre>
<p style="text-align:justify;">Of course, this function is bound to fail in case of division by zero. While this is expected, there is nothing in the source code &#8212; much less in the type of the function &#8212; to let us know which exception will be raised in case of division by zero.</p>
<p>An alternative would be to add manual error checking, as follows:</p>
<pre name="code" class="python">

type (&#039;a, &#039;b) result =
 | Ok of &#039;a
 | Error of &#039;b

let rec eval = function
 | Value x    -&gt; OK x
 | Add (x,y) -&gt; (match eval x with
                      | Error e -&gt; Error e
                      | Ok x&#039; -&gt;  match eval y with
                               | Error e -&gt; Error e
                               | Ok y&#039;    -&gt; Ok (x&#039; +. y&#039;))
 | Mult (x,y) -&gt; (match eval x with
                      | Error e -&gt; Error e
                      | Ok x&#039; -&gt;  match eval y with
                               | Error e -&gt; Error e
                               | Ok y&#039;    -&gt; Ok (x&#039; *. y&#039;))
 | Div (x,y) -&gt; (match eval x with
                      | Error e -&gt; Error e
                      | Ok x&#039; -&gt;  match eval y with
                               | Error e -&gt; Error e
                               | Ok y&#039;    -&gt; if y&#039; = 0. then Error &quot;Division by zero&quot;
                                                else              Ok (x&#039; /. y&#039;))
 | Subs (x,y) -&gt; (match eval x with
                      | Error e -&gt; Error e
                      | Ok x&#039; -&gt;  match eval y with
                               | Error e -&gt; Error e
                               | Ok y&#039;    -&gt; Ok (x&#039; -. y&#039;))
(*eval : expr -&gt; (float, string) result*)
</pre>
<p style="text-align:justify;">After this transformation, the type of the exception appears in the type of <code>eval</code> &#8212; here, we used strings, but anything else would have been fine. Of course, the downside is that this is unreadable. Well, what about the following ?</p>
<pre name="code" class="python">

let rec eval = function
 | Value x    -&gt; return x
 | Add (x,y) -&gt; perform with module Error
                        x&#039; &lt;-- eval x;
                        y&#039; &lt;-- eval y;
                        return (x&#039; +. y&#039 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
 | Mult (x,y) -&gt; perform with module Error
                        x&#039; &lt;-- eval x;
                        y&#039; &lt;-- eval y;
                        return (x&#039; *. y&#039 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
 | Div (x,y) -&gt; perform with module Error
                        x&#039; &lt;-- eval x;
                        y&#039; &lt;-- eval y;
                        if y&#039;=0. then throw &quot;Division by zero&quot;
                        else            return (x&#039; /. y&#039 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
 | Subs (x,y) -&gt; perform with module Error
                        x&#039; &lt;-- eval x;
                        y&#039; &lt;-- eval y;
                        return (x&#039; -. y&#039 <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
(*eval : expr -&gt; (float, string) result*)
</pre>
<p style="text-align:justify;">This extract uses [our customized version of] Pa_monad (included in the package), which brings syntactic support for monads. While this is more verbose than the original version, it&#8217;s also safer, insofar as we can guarantee that exceptions won&#8217;t remain uncaught.</p>
<p>Still too long? Then what about using the appropriate operators?</p>
<pre name="code" class="python">

open Error.Operators
let rec eval = function
 | Value x    -&gt; x
 | Add (x,y) -&gt; eval x +. eval y
 | Mult(x,y) -&gt; eval x *. eval y
 | Div(x,y)   -&gt; eval x /. eval y
 | Subs(x,y) -&gt; eval x -. eval y
</pre>
<p>Except for the module opening, that&#8217;s the same thing as our first listing. Just with the added safety.</p>
<h3>Throwing, catching and hierarchies</h3>
<p>By the way, the type of the result is</p>
<pre name="code" class="python">

(*eval : expr -&gt; (float, [&gt; `Arithmetic of (unit, [&gt; `Div_by_zero of (unit, _) exc ]) exc ]) result*)
</pre>
<p>That is, eval may either succeed and return a float or fail and return an arithmetic exception, which also turns out to be a division by zero. That&#8217;s classes of exceptions.</p>
<p>With our syntactic sugar, raising such an exception is done by</p>
<pre name="code" class="python">

throw (exception Arithmetic (); Div_by_zero ())
</pre>
<p style="text-align:justify;">Note that we could have put some content instead of <code>()</code>. Note that exceptions are typed as they appear in the code and don&#8217;t need to be declared (if you wonder, polymorphic variants are involved in this).</p>
<p>Of course, various kinds of exceptions may be combined, as in the following extract:</p>
<pre name="code" class="python">

match ... with
| 1 -&gt; throw (exception Arithmetic (); Div_by_zero ())
| 2 -&gt; throw (exception Arithmetic (); Overflow &quot;by gosh !&#038;quot <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
| 3 -&gt; throw (exception IO file_descr)
| ...
(*
(&#039;a, [&gt; `Arithmetic of (unit, [&gt; `Div_by_zero of (unit, _) exc
                                     |   `Overflow of (string, _)   exc]) exc
     |   `IO of (int, [`&gt; ]) exc ]) result*)
*)
</pre>
<p>While the type of the expression is difficult to read, catching is easy</p>
<pre name="code" class="python">

attempt ... with
 | val s -&gt; (*success*)
 | Arithmetic (); Div_by_zero () -&gt; (*Division by zero*)
 | Arithmetic (); _                   -&gt; (*Other arithmetic*)
 | IO _                                  -&gt; (*Some IO stuff *)
 | finally _                             -&gt; (*Don&#039;t forget to close the door*)
</pre>
<p>This extract introduces three keywords:</p>
<ul>
<li><code>attempt</code> is our replacement for <code>try</code></li>
<li><code>val</code> is used to pattern-match against the result of a successful evaluation</li>
<li><code>finally</code> is used to pattern-match against the final result, whether this result was obtained after a successful evaluation or after an exception was raised and handled.</li>
</ul>
<h3>Unbreaking tail-recursion</h3>
<p>The following extract is wrong:</p>
<pre name="code" class="python">

let line_count filename =
  let rec loop file count =
  try
    ignore (input_line file);
    loop file (count + 1)
  with
    End_of_file -&gt; count
  in
    loop (open_file filename) 0
</pre>
<p align="justify">Don&#8217;t get me wrong, it will compile and run. The problem is that it&#8217;s not tail-recursive. In other words, it will be much slower and much more memory-consuming than if exceptions had been ignored. Why ? Because exception End_of_file may have been raised from the next call to loop, so the recursive call cannot be optimized into a non-recursive call. Of course, exceptions can&#8217;t be ignored in this extract, as they are required to determine when to stop reading the file. Now, a simple transformation would make the problem go away :</p>
<pre name="code" class="python">

let line_count filename =
  let rec loop file count =
    let should_continue =
    try
      ignore (input_line file);
      true
    with End_of_file -&gt; false
  in
    if should_continue then loop file (count + 1)
    else                    count
  in
    loop (open_file filename) 0
</pre>
<p style="text-align:justify;">Well, the transformation is simple, but it&#8217;s annoying and hard to read. What&#8217;s even more annoying is that it&#8217;s quite common. With Catch me if you can, we would rather write the following:</p>
<pre name="code" class="python">

let input_line2 x = Error.legacy input_line x

let line_count filename =
  let rec loop file count =
    attempt input_line2 file with
      | val _ -&gt; loop file (count + 1)
      | _     -&gt; count
  in
  loop (open_file filename) 0
</pre>
<p style="text-align:justify;">In this extract, legacy is a simple manner of wrapping an existing, one-argument, function and convert it to our new exception style. It&#8217;s not quite as good as wrapping the function manually and giving it an actual exception, but it&#8217;s better than nothing.</p>
<p align="justify">All in all, the resulting function line_count is shorter, easier to read, takes less memory and is also faster than the original.</p>
<h2>What about performance?</h2>
<p style="text-align:justify;">Now, that&#8217;s a complex question. Short answer: there&#8217;s an acceptable performance loss. False short answer: we wrote a <a href="http://www.univ-orleans.fr/lifo/Members/David.Teller/publications/ml2008.pdf">paper</a> on that subject.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/105/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/105/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/105/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/105/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/105/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=105&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/07/02/improving-exception-management-in-ocaml/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>More monad exceptions for OCaml</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/06/26/more-monad-exceptions-for-ocaml/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/06/26/more-monad-exceptions-for-ocaml/#comments</comments>
		<pubDate>Thu, 26 Jun 2008 23:38:51 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[benchmark]]></category>

		<category><![CDATA[camlp4]]></category>

		<category><![CDATA[dynamic errors]]></category>

		<category><![CDATA[error management]]></category>

		<category><![CDATA[errors]]></category>

		<category><![CDATA[exceptions]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[ml]]></category>

		<category><![CDATA[monad]]></category>

		<category><![CDATA[obj.magic]]></category>

		<category><![CDATA[optimization]]></category>

		<category><![CDATA[phantom types]]></category>

		<category><![CDATA[polymorphic variants]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[programming languages]]></category>

		<category><![CDATA[research]]></category>

		<category><![CDATA[rewriting]]></category>

		<category><![CDATA[semantics]]></category>

		<category><![CDATA[sml]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[syntactic sugar]]></category>

		<category><![CDATA[type system]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=102</guid>
		<description><![CDATA[A new version of the exception monad for OCaml is now available for download. It&#8217;s now richer, comes with extensive syntactic sugar and a brand new system of compile-time optimizations. More on this in the corresponding research paper &#8212; and whenever I find the time, on this blog.
       ]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">A new version of the exception monad for OCaml is now available <a href="http://www.univ-orleans.fr/lifo/Members/David.Teller/software/exceptions/catch_0_2.tgz">for download</a>. It&#8217;s now richer, comes with extensive syntactic sugar and a brand new system of compile-time optimizations. More on this in the corresponding <a href="http://www.univ-orleans.fr/lifo/Members/David.Teller/publications/ml2008.pdf">research paper</a> &#8212; and whenever I find the time, on this blog.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/102/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/102/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/102/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/102/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/102/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/102/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/102/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/102/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/102/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/102/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/102/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/102/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=102&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/06/26/more-monad-exceptions-for-ocaml/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Extrapol and Korset</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/06/19/extrapol-and-korset/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/06/19/extrapol-and-korset/#comments</comments>
		<pubDate>Thu, 19 Jun 2008 10:57:05 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[Extrapol]]></category>

		<category><![CDATA[In English / En anglais]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[Sûreté / Security]]></category>

		<category><![CDATA[blackhat]]></category>

		<category><![CDATA[code analysis]]></category>

		<category><![CDATA[complete]]></category>

		<category><![CDATA[dependent types]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[korset]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[research]]></category>

		<category><![CDATA[safety]]></category>

		<category><![CDATA[safety analysis]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[security analysis]]></category>

		<category><![CDATA[security policies]]></category>

		<category><![CDATA[selinux]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[sound]]></category>

		<category><![CDATA[static analysis]]></category>

		<category><![CDATA[type system]]></category>

		<category><![CDATA[type theory]]></category>

		<category><![CDATA[types]]></category>

		<category><![CDATA[types and effects]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=99</guid>
		<description><![CDATA[A colleague recently pointed me towards Korset, a program developed by Ohad Ben-Cohen and Avishai Wool promising features comparable to Extrapol. While I must admit I&#8217;m slightly skeptical about the promise of &#8220;provable zero false alarm&#8221; &#8212; since the problem is undecidable, usually people tend to develop &#8220;provably complete&#8221; rather than &#8220;provably sound&#8221; analysis &#8212; [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">A colleague recently pointed me towards <a href="http://www.linuxsymposium.org/2008/view_bio.php?id=2348">Korset</a>, a program developed by Ohad Ben-Cohen and Avishai Wool promising features comparable to Extrapol. While I must admit I&#8217;m slightly skeptical about the promise of &#8220;provable zero false alarm&#8221; &#8212; since the problem is undecidable, usually people tend to develop &#8220;provably complete&#8221; rather than &#8220;provably sound&#8221; analysis &#8212; it sounds like an interesting development.</p>
<p style="text-align:justify;">Now, from what I understand, Korset will be presented to Blackhat in a few months, and the rules of the conference forbid the developers from giving away any detail. Until then, we have no way of comparing the unreleased Extrapol and the equally unreleased Korset.</p>
<p style="text-align:justify;"><strong>Note:</strong> the tarball for the first prototype of Extrapol is waiting on my hard-drive for release clearance. I hope I&#8217;ll be able to release it next Tuesday or Wednseday. Stay tuned.</p>
<p style="text-align:justify;">
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/99/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/99/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/99/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/99/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=99&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/06/19/extrapol-and-korset/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Extrapol source code available (not)</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/06/17/extrapol-source-code-available/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/06/17/extrapol-source-code-available/#comments</comments>
		<pubDate>Tue, 17 Jun 2008 16:08:16 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[Extrapol]]></category>

		<category><![CDATA[In English / En anglais]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[Sûreté / Security]]></category>

		<category><![CDATA[batteries included]]></category>

		<category><![CDATA[ast]]></category>

		<category><![CDATA[c++]]></category>

		<category><![CDATA[code analysis]]></category>

		<category><![CDATA[dependent types]]></category>

		<category><![CDATA[effets]]></category>

		<category><![CDATA[gcc]]></category>

		<category><![CDATA[lexer]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[parser]]></category>

		<category><![CDATA[quality]]></category>

		<category><![CDATA[safety]]></category>

		<category><![CDATA[scanner]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[security analysis]]></category>

		<category><![CDATA[security policies]]></category>

		<category><![CDATA[security policy]]></category>

		<category><![CDATA[selinux]]></category>

		<category><![CDATA[source code]]></category>

		<category><![CDATA[sourec analysis]]></category>

		<category><![CDATA[static analysis]]></category>

		<category><![CDATA[subversion]]></category>

		<category><![CDATA[svn]]></category>

		<category><![CDATA[type system]]></category>

		<category><![CDATA[types]]></category>

		<category><![CDATA[types and effects]]></category>

		<category><![CDATA[types with effects]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=96</guid>
		<description><![CDATA[A quick note to inform you that the repository for Extrapol is now public. The source code as available on the repository does not have a licence yet and will not compile as such, due to dependencies on libraries available somewhere else. Stay tuned for an actual release.
Update: Sorry, repository cut off by the administrator. [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">A quick note to inform you that the <a href="http://">repository</a> for Extrapol is now public. The source code as available on the repository does not have a licence yet and will not compile as such, due to dependencies on libraries available <a href="http://forge.ocamlcore.org/projects/batteries/">somewhere else</a>. Stay tuned for an actual release.</p>
<p style="text-align:justify;"><strong>Update:</strong> Sorry, repository cut off by the administrator. I&#8217;ll inform you when the sources are back.</p>
<p style="text-align:justify;">Note rapide pour vous informer que le <a href="https://www.sds-project.fr/svn/extrapol/trunk/specs/ml">code source</a> d&#8217;Extrapol est maintenant disponible au public. Il ne s&#8217;agit pas encore d&#8217;une version officielle &#8212; en particulier, le code n&#8217;a pas encore de licence et il manque des bibliothèques (<a href="http://forge.ocamlcore.org/projects/batteries/">disponibles ailleurs</a>). Plus de détails dès qu&#8217;une version officielle est disponible.</p>
<p style="text-align:justify;"><strong>Additif:</strong> Désolé, je viens d&#8217;apprendre que le dépôt de source a été isolé par l&#8217;administrateur. Je vous tiendrai au courant dès que le code source est de nouveau public.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/96/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/96/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/96/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/96/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/96/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=96&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/06/17/extrapol-source-code-available/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Extrapol, première partie : de C aux effets</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/06/09/extrapol-premiere-partie-de-c-aux-effets/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/06/09/extrapol-premiere-partie-de-c-aux-effets/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 17:51:15 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[En français / In French]]></category>

		<category><![CDATA[Enseignement]]></category>

		<category><![CDATA[Extrapol]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[Sûreté / Security]]></category>

		<category><![CDATA[selinux]]></category>

		<category><![CDATA[logiciel libre]]></category>

		<category><![CDATA[windows]]></category>

		<category><![CDATA[open-source]]></category>

		<category><![CDATA[linux]]></category>

		<category><![CDATA[informatique]]></category>

		<category><![CDATA[politiques de sécurité]]></category>

		<category><![CDATA[sécurité]]></category>

		<category><![CDATA[sûreté]]></category>

		<category><![CDATA[administration système]]></category>

		<category><![CDATA[système]]></category>

		<category><![CDATA[système d'exploitation]]></category>

		<category><![CDATA[sûr]]></category>

		<category><![CDATA[unix]]></category>

		<category><![CDATA[privilèges]]></category>

		<category><![CDATA[sds]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=85</guid>
		<description><![CDATA[A short summary of Extrapol.]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">Après un billet dans la langue de Turing, voici une présentation d&#8217;Extrapol en version française. En quelques mots, le projet Extrapol (pour <em>Extraction de Politiques de Sécurité</em>) vise à combler un vide dans le jeu d&#8217;outils dont dispose l&#8217;administrateur pour maintenir un système dans un état sûr.</p>
<p><span id="more-85"></span></p>
<p style="text-align:justify;">Ainsi, il existe un grand nombre de logiciels qui permettent de surveiller un processus durant son exécution (<em>analyse dynamique</em>) ou après son exécution (<em>analyse de traces</em>) afin de comprendre le comportement de programme et ainsi de vérifier que la politique de sécurité en vigueur sur le système est bien respectée. À l&#8217;inverse, les outils d&#8217;analyse statique disponibles cherchent généralement à répondre à des questions sans rapport direct avec la sécurité système, telles que &#8220;ai-je écrit une bêtise ?&#8221; ou &#8220;puis-je prouver que mon programme fonctionne ?&#8221;</p>
<h2>Que fait ce programme ?</h2>
<p style="text-align:justify;">Les outils d&#8217;analyse dynamique, qu&#8217;il s&#8217;agisse de SELinux, de la protection mémoire Unix, de la gestion des privilèges Windows ou des autorisations Java ou .Net, visent tous à répondre à deux questions :</p>
<ol>
<li>Qu&#8217;est en train de faire ce programme ?</li>
<li>Est-ce légal ?</li>
</ol>
<p style="text-align:justify;">La réponse à la deuxième question est donnée par une notion de politique de sécurité, qui se réduit généralement à un ensemble d&#8217;autorisations de la forme &#8220;le sujet S a le droit d&#8217;entreprendre l&#8217;action A sur l&#8217;objet O&#8221;. Pour répondre à la première question, la technique générale consiste à intercaler entre le programme et les APIs concernées par la surveillance une couche dont le seul rôle est de prendre en compte les appels. Sans entrer dans les détails, les outils d&#8217;analyse de trace posent des questions similaires en s&#8217;appuyant sur des notions et des techniques comparables.</p>
<p style="text-align:justify;">Logiquement, nous avons décidé de suivre le même chemin pour Extrapol :</p>
<ol>
<li>Que va faire ce programme ?</li>
<li>Puis-je savoir dès maintenant si c&#8217;est légal ?</li>
</ol>
<p>Pour répondre à la deuxième question, nous nous proposons d&#8217;utiliser exactement la même notion de politique de sécurité que celle qui est employée dans les systèmes d&#8217;exploitation actuels &#8212; plus précisément, à terme, nous nous proposons de permettre à Extrapol d&#8217;utiliser directement les fichiers de configurations de SELinux ou d&#8217;AppArmor. Quant à la première question, nous allons en chercher la réponse par des techniques d&#8217;analyse de types sur les programmes écrits en C. Voyons cela sur un exemple :</p>
<pre name="code" class="c">

void* read_some_stuff()
{
   FILE* file = fopen(&quot;/home/foo/bar.log&quot;, &quot;r&quot;);
   void* buf  = malloc(1024*sizeof(int));
   fread(buf , sizeof(int), 1024, file);
   return buf;
}
</pre>
<p style="text-align:justify;">Que fait donc cette fonction ? Sans nous attacher à la qualité du code &#8212; une pléthore d&#8217;outils existe déjà pour essayer de vérifier celle-ci &#8212; nous pouvons déterminer aisément que</p>
<ul>
<li>il s&#8217;agit d&#8217;une fonction appelée <code>read_some_stuff</code></li>
<li>si cette fonction est appelée, elle ouvrira en lecture le fichier nommé <code>/home/foo/bar.log</code></li>
<li>si cette fonction est appelée, elle consultera une partie du fichier nommé<br />
<code>/home/foo/bar.log</code></li>
<li>si cette fonction est appelée, elle renverra une information tirée du fichier nommé<br />
<code>/home/foo/bar.log</code></li>
</ul>
<p>En termes de sécurité, ce programme ne doit donc être accepté que dans un contexte dans lequel la politique de sécurité en vigueur sur le système autorise la consultation du fichier <code>/home/foo/bar.log</code>. Regardons ce que nous dit Extrapol au sujet de ce programme :</p>
<pre name="code" class="python">

read_some_stuff: Function
        effect                 : &quot;open&quot; (Constant &quot;/home/foo/bar.log&quot; , Constant &quot;r&quot; )
        effect                 : &quot;read&quot; (Constant &quot;/home/foo/bar.log&quot; )
        return                 : &quot;data read from file&quot; (Constant &quot;/home/foo/bar.log&quot; )
End
</pre>
<p>Soit, en français,</p>
<ul>
<li><code>read_some_stuff</code> est une fonction</li>
<li>cette fonction ne prend aucun argument</li>
<li>cette fonction a pour <em>effet</em> d&#8217;ouvrir le fichier nommé<br />
<code>"/home/foo/bar.log"</code> pour consultation</li>
<li>cette fonction a pour <em>effet</em> de consulter des informations depuis le fichier nommé <code>"/home/foo/bar.log"</code></li>
<li>le <em>résultat</em> de cette fonction est un ensemble d&#8217;informations provenant du fichier nommé <code>"/home/foo/bar.log"</code>.</li>
</ul>
<p>Pour cet exemple, la réponse d&#8217;Extrapol est plus longue que le programme original et probablement pas beaucoup plus lisible. Regardons le résultat sur un extrait un peu plus complexe :</p>
<pre name="code" class="c">

#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;

int do_open(char* file_name)
{
  int fd = (int)fopen(file_name, O_RDONLY);
  return fd;
}

int do_read(int fd)
{
  char* buf;
  buf    = (char*)malloc(1024*sizeof(char));
  int rd = 0;
  for(int i = 0; i &lt; 1024; ++i)
    rd = rd + fread(buf, i, 1, fd);

  return buf;
}
</pre>
<p>Sans surprise, Extrapol analysera les deux fonctions et présentera un bilan pour chacune.</p>
<ul>
<li>L&#8217;analyse de <code>do_open</code> produira :
<pre name="code" class="php">

do_open: Function
        input arg file_name    : Bottom
        effect                 : &quot;open&quot; (Identifier &quot;file_name&quot;, Constant &quot;0&quot; )
        return                 : &quot;FILE&quot; (Identifier &quot;file_name&quot; )
End
</pre>
<p>c&#8217;est-à-dire,</p>
<ul>
<li><tt>do_open</tt> est une fonction</li>
<li><tt>do_open</tt> accepte un argument, ici <code>file_name</code></li>
<li>le contenu de cet argument ne sera pas modifié</li>
<li>le contenu de cet argument n&#8217;a pas besoin d&#8217;avoir une structure particulière</li>
<li>appeler cette fonction aura un effet sur le système : ouvrir ouvrir pour consultation le fichier dont le nom a été donné dans <code>file_name</code></li>
<li>la fonction renvoie une information abstraite, dans ce cas un fichier dont le nom a été donné dans <code>file_name</code>.</li>
</ul>
</li>
<li>L&#8217;analyse de <code>do_read</code> produira :
<pre name="code" class="php">

do_read: Function
        input arg fd           : &quot;FILE&quot; (Identifier &quot;extrapol_generated_699 (formerly &lt;anonymous&gt; ) &quot; )
        effect                 : &quot;read&quot; (Identifier &quot;extrapol_generated_699 (formerly &lt;anonymous&gt; ) &quot; )
        return                 : &quot;data read from file&quot; (Identifier &quot;extrapol_generated_699 (formerly &lt;anonymous&gt; ) &quot; )
End
</pre>
<p>c&#8217;est-à-dire,</p>
<ul>
<li><tt>do_read</tt> est une fonction</li>
<li><tt>do_read</tt> accepte un argument, ici <code>fd</code></li>
<li>le contenu de cet argument ne sera pas modifié</li>
<li>cet argument doit être une structure abstraite, dans ce cas précis un fichier</li>
<li>pour le reste de la fonction, nous appellerons le nom du fichier <code>extrapol_generated_699 (formerly &lt;anonymous&gt;)"</code> &#8212; Extrapol a été obligé d&#8217;inventer cette appellation pas très attrayante pour désigner le nom du fichier</li>
<li>cette fonction a un effet sur le système : consulter le fichier dont le nom est représenté par <code>extrapol_generated_699 (formerly &lt;anonymous&gt; )</code></li>
<li>cette fonction renvoie une information abstraite, dans ce cas quelque chose qui a été lu depuis le fichier dont le nom est représenté par <code>extrapol_generated_699 (formerly &lt;anonymous&gt; )</code></li>
</ul>
</li>
</ul>
<p style="text-align:justify;">Maintenant, ces fonctions peuvent être utilisées et leur usage peut être analysé de la même manière que si elles avaient fait partie de la libc. Ainsi, complétons notre extrait par la fonction <code>main</code> suivante :</p>
<pre name="code" class="c">

int main(int argc, char **argv) {
  assert(argc &gt;= 1);
  int   fd  = do_open(argv[0]);
  char* buf = do_read(fd);
  free(buf);
  return 0;
}
</pre>
<p>En retour, Extrapol nous répondra :</p>
<pre name="code" class="php">

main: Function
        input arg argc         : &quot;command-line argument&quot; ()
        input arg argv         : &quot;command-line argument&quot; ()
        input vararg           : &quot;command-line argument&quot; ()
        effect                 : &quot;read&quot; (Identifier &quot;argv&quot; )
        effect                 : &quot;open&quot; (Identifier &quot;argv&quot;, Constant &quot;0&quot; )
        return                 : Constant &quot;0&quot;
End
</pre>
<p style="text-align:justify;">En d&#8217;autres termes, le programme aura pour effet d&#8217;ouvrir puis de lire un fichier dont le nom est passé en ligne de commande.</p>
<p style="text-align:justify;">
<h2>Comment ça marche ?</h2>
<p style="text-align:justify;">Pour ce billet, je ferai semblant de comprendre cette question comme « comment utiliser Extrapol ? » La réponse est simple. Extrapol prend en entrée un ou plusieurs fichiers source C (passés ou non par le préprocesseur) et une base de connaissances sur les fonctions considérées comme primitives. Cette base de connaissance est un fichier ASCII dans le même format que les sorties d&#8217;Extrapol. Ainsi, <code>malloc</code> sera décrit par</p>
<pre name="code" class="c">

malloc: Function
  input arg size: Bottom
  return: Bottom
End
</pre>
<p style="text-align:justify;">En d&#8217;autres termes, <code>malloc</code> est une fonction qui accepte un argument (&#8221;<code>size</code>&#8220;) quelconque et renvoie une valeur dont il est possible de faire n&#8217;importe quoi. Une fonction telle que <code>fread</code> sera un peu plus compliquée. Commençons par regarder le manuel de cette fonction :</p>
<pre name="code" class="c">

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
</pre>
<p>Pour Extrapol, il s&#8217;agit d&#8217;une fonction à 4 arguments et une valeur de retour. Commençons par la fin.</p>
<ul>
<li>La valeur de retour peut être n&#8217;importe quoi, nous n&#8217;allons faire <em>aucune garantie</em>. En Extrapol, c&#8217;est ce que nous notons <code>Top</code> &#8212; par opposition à <code>Bottom</code>, qui signifierait au contraire qu&#8217;il n&#8217;y a aucune contrainte sur la valeur. Si nécessaire, nous pourrions raffiner ceci.</li>
<li>Le dernier argument est un fichier. Nous avons vu un peu plus tôt comment représenter les fichiers : ce sont des structures abstraites que nous avons décidé, par convention, d&#8217;appeler <code>FILE</code>, comme dans la bibliothèque standard de C. Plus précisément, nous avons décidé de les noter <code>"FILE" (toto)</code> où <code>toto</code> permet de déterminer le nom du fichier. Nous appelons <code>"FILE"</code> un <em>constructor</em>, au sens de la réécriture ou de la programmation fonctionnelle. Il s&#8217;agit en tout et pour tout d&#8217;une chaîne de caractères dont nous nous servons pour différencier les valeurs abstraites. Le <code>toto</code> correspondant est l&#8217;<em>argument</em> donné au constructeur.</li>
<li>L&#8217;avant-dernier paramètre de la fonction est le nombre de blocs à lire. Nous allons juste l&#8217;ignorer, c&#8217;est-à-dire ne mettre aucune contrainte, c&#8217;est-à-dire <code>Bottom</code>.</li>
<li>Le deuxième argument est une taille, que nous allons aussi ignorer, c&#8217;est-à-dire de nouveau <code>Bottom</code>.</li>
<li>Enfin, le premier paramètre est utilisé en sortie &#8212; fonctionnellement, c&#8217;est une forme spéciale de <code>return</code>. Nous allons donc le marquer <code>output</code>. Nous pourrions nous arrêter là et ne mettre aucune garantie sur le contenu de ce paramètre, mais ici nous allons légèrement raffiner et spécifier qu&#8217;il s&#8217;agit d&#8217;informations certes inconnues, mais lues depuis un fichier. Comme précédemment, il s&#8217;agit d&#8217;une structure abstraite, donc d&#8217;un constructeur, que nous allons appeler <code>"data read from file"</code>. Comme argument, nous allons passer le nom du fichier d&#8217;où viennent les informations. Nous obtenons donc <code>"data read from file"(toto)</code>. La valeur de <code>toto</code> sera déterminée lors de l&#8217;invocation de la fonction grâce à la valeur du dernier argument.</li>
<li>Oh, et avant d&#8217;oublier, cette fonction a un effet sur le système : elle lit quelque chose depuis <code>toto</code>. Appelons cet effet <code>"read"(toto)</code></li>
</ul>
<p>Ou, en Extrapol dans le texte :</p>
<pre name="code" class="php">

fread: Function
   output arg ptr: &quot;data read from file&quot; ( Identifier &quot;path&quot; )
   input arg size : Bottom
   input arg nmemb: Bottom
   input arg stream: &quot;FILE&quot; ( Identifier &quot;path&quot; )
   return: Top
   effect: &quot;read&quot; ( Identifier &quot;path&quot; )
End
</pre>
<p style="text-align:justify;">Une fois données cette base de connaissances et des fichiers C, Extrapol va passer les fichiers au pré-processeur, analyser lexicalement et syntaxiquement le contenu des fichiers, puis procéder par déductions successives à partir de la structure du programme et de la base de connaissances. Chaque fonction analysée est ajoutée à la base de connaissances pour pouvoir être réutilisée dans la suite du programme. Extrapol continue soit jusqu&#8217;à avoir tout analysé, soit jusqu&#8217;à un problème interne (typiquement une fonction avec le mauvais nombre d&#8217;arguments ou une fonction utilisée sans avoir été définie).Enfin, Extrapol affiche le résultat de ses déductions, à un format ré-utilisable pour réinjection dans la base de connaissances.</p>
<p style="text-align:justify;">Si vous êtes curieux, les principes derrière Extrapol sont</p>
<ul>
<li>le lambda-calcul et, plus généralement, la programmation fonctionnelle</li>
<li>les systèmes de types avec effets</li>
<li>les systèmes de types dépendants</li>
<li>l&#8217;inférence de types à la Hindley-Milner .</li>
</ul>
<p style="text-align:justify;">Tout ceci sera détaillé dans un ou plusieurs autres billets &#8212; et dans un article de journal scientifique que je viens de commencer.</p>
<h2>Est-ce que ça marche ?</h2>
<p>La réponse à cette question est un clair et franc &#8220;oui, non et peut-être&#8221; :</p>
<ul>
<li>Tout n&#8217;est pas implanté. En particulier, pour le moment, Extrapol n&#8217;est pas capable de déduire quoi que ce soit d&#8217;intéressant sur les variables globales. De même, Extrapol n&#8217;aboutira pour le moment que si les fonctions sont introduites dans l&#8217;ordre dans lequel elles sont utilisées. Rien de terriblement difficile à ajouter à Extrapol, cela n&#8217;a juste pas été prioritaire jusqu&#8217;à présent.</li>
<li>Extrapol n&#8217;est capable de gérer ni la récursivité ni les pointeurs sur fonctions. Pour le moment, la théorie derrière Extrapol ne prend pas en compte ces aspects du langage C.</li>
<li>Tous les exemples cités ci-dessus fonctionnent, ainsi que quelques dizaines d&#8217;autres.</li>
<li>Nous n&#8217;avons pas encore confronté Extrapol avec des logiciels complets. Le jour où Extrapol comprendra, mettons tar ou ls, nous déboucherons le champagne.</li>
</ul>
<h2>Comment est-ce écrit ?</h2>
<p>Il y a actuellement deux versions d&#8217;Extrapol :</p>
<ul>
<li>Extrapol/Java, version implantée en Java par Bastien Jansen, Steve-William Kissi et David Teller. Environ 18.000 lignes de code.</li>
<li>Extrapol/ML, version expérimentale, implantée en OCaml par David Teller. Environ 4.000 lignes de code.</li>
</ul>
<p style="text-align:justify;">Les deux versions seront libérées sous peu (normalement d&#8217;ici la mi-juin), dès que nous serons arrivés à régler des problèmes techniques dans <a href="http://www.sds-project.fr">notre serveur de projet</a> et dès que nous aurons fini par décider d&#8217;une licence. A priori, ce sera probablement Cecill B pour Extrapol/Java et LGPL pour Extrapol/ML.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/85/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/85/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/85/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/85/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/85/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=85&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/06/09/extrapol-premiere-partie-de-c-aux-effets/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Extrapol, part 1: from C to Effects</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/06/03/extrapol-part-1-from-c-to-effects/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/06/03/extrapol-part-1-from-c-to-effects/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 17:41:01 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[Extrapol]]></category>

		<category><![CDATA[In English / En anglais]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[Recherche / Research]]></category>

		<category><![CDATA[Sûreté / Security]]></category>

		<category><![CDATA[c++]]></category>

		<category><![CDATA[coding]]></category>

		<category><![CDATA[dependent types]]></category>

		<category><![CDATA[dynamic analysis]]></category>

		<category><![CDATA[ensib]]></category>

		<category><![CDATA[free software]]></category>

		<category><![CDATA[glibc]]></category>

		<category><![CDATA[inference]]></category>

		<category><![CDATA[lambda-calculus]]></category>

		<category><![CDATA[licence]]></category>

		<category><![CDATA[open-source]]></category>

		<category><![CDATA[programming]]></category>

		<category><![CDATA[programming languages]]></category>

		<category><![CDATA[prototype]]></category>

		<category><![CDATA[s-expressions]]></category>

		<category><![CDATA[security]]></category>

		<category><![CDATA[selinux]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[specifications]]></category>

		<category><![CDATA[static analysis]]></category>

		<category><![CDATA[tias]]></category>

		<category><![CDATA[trace analysis]]></category>

		<category><![CDATA[type inference]]></category>

		<category><![CDATA[type system]]></category>

		<category><![CDATA[types with effects]]></category>

		<category><![CDATA[typing]]></category>

		<category><![CDATA[verification]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=78</guid>
		<description><![CDATA[Here comes the long-promised description of Extrapol, my main ongoing research project. In a few words, our objective with Extrapol is to fill a hole in the current suite of tools built to ensure the security of systems. While there's an ample amount of stuff designed to analyse the behaviour of processes either during their execution (dynamic analysis) or after their completion (trace analysis), there is little work on applying static analysis to actual system security.]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">
<p style="text-align:justify;">Here comes the long-promised description of Extrapol, my main ongoing research project. In a few words, our objective with Extrapol is to fill a hole in the current suite of tools built to ensure the security of systems. While there&#8217;s an ample amount of stuff designed to analyse the behaviour of processes either during their execution (dynamic analysis) or after their completion (trace analysis), there is little work on applying static analysis to actual system security.</p>
<p><span id="more-78"></span></p>
<h2>What does this program do?</h2>
<p style="text-align:justify;">Whether we&#8217;re talking about SELinux, AppArmor, the Unix memory protection, ACLs, every form of dynamic analysis is trying to find the answer to two questions:</p>
<ol>
<li>what is this program doing?</li>
<li>is that legal?</li>
</ol>
<p style="text-align:justify;">With Extrapol, the questions are similar, although we&#8217;re asking them earlier &#8212; and restricting ourselves to C programs:</p>
<ol>
<li>what is this program going to do whenever it gets executed?</li>
<li>is that legal?</li>
<li>if information is missing, where will that information come from?</li>
</ol>
<p>Let&#8217;s look at an example and see what gives:</p>
<pre name="code" class="c">

void* read_some_stuff()
{
   FILE* file = fopen(&quot;/home/foo/bar.log&quot;, &quot;r&quot;);
   void* buf  = malloc(1024*sizeof(int));
   fread(buf , sizeof(int), 1024, file);
   return buf;
}
</pre>
<p style="text-align:justify;">Now, what does this function do? Now, regardless of the quality of the code, from a cursory read, it&#8217;s quite clear that it</p>
<ul>
<li>opens a file named &#8220;/home/foo/bar.log&#8221; for reading</li>
<li>allocates some memory</li>
<li>read some of the content of that file</li>
<li>return a pointer to the contents of that file.</li>
</ul>
<p style="text-align:justify;">In terms of security, the program should only be executed by a user who has the authorization to read file &#8220;/home/foo/bar.log&#8221; and only if that user is willing to let the program read the contents of that file. Let&#8217;s see what Extrapol tells us about the extract:</p>
<pre name="code" class="python">

read_some_stuff: Function
        effect                 : &quot;open&quot; (Constant &quot;/home/foo/bar.log&quot; , Constant &quot;r&quot; )
        effect                 : &quot;read&quot; (Constant &quot;/home/foo/bar.log&quot; )
        return                 : &quot;data read from file&quot; (Constant &quot;/home/foo/bar.log&quot; )
End
</pre>
<p>In clear(er) English, Extrapol has just given us the following informations:</p>
<ul>
<li>read_some_stuff is a function</li>
<li>read_some_stuff does not take any argument</li>
<li>if executed, this function will have the secondary effect of opening a file named &#8220;/home/foo/bar.log&#8221; for reading</li>
<li>if executed, this function will also have the secondary effect of reading stuff from a file named <tt>&#8220;/home/foo/bar.log&#8221;</tt></li>
<li>the result of calling this function is some data read from the file named <tt>&#8220;/home/foo/bar.log&#8221;</tt></li>
</ul>
<p style="text-align:justify;">While the result is somewhat larger than the original program, of course, we can apply Extrapol to more complex programs. Say, from</p>
<pre name="code" class="c">

#include &lt;stdio.h&gt;
#include &lt;sys/types.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;

int do_open(char* file_name)
{
  int fd = (int)fopen(file_name, O_RDONLY);
  return fd;
}

int do_read(int fd)
{
  char* buf;
  buf    = (char*)malloc(1024*sizeof(char));
  int rd = 0;
  for(int i = 0; i &lt; 1024; ++i)
    rd = rd + fread(buf, i, 1, fd);

  return buf;
}
</pre>
<p>Well, in that case, Extrapol will analyze both functions and produce a summary of each.</p>
<ul>
<li> The analysis of <code>do_open</code> will result in:
<pre name="code" class="php">

do_open: Function
        input arg file_name    : Bottom
        effect                 : &quot;open&quot; (Identifier &quot;file_name&quot;, Constant &quot;0&quot; )
        return                 : &quot;FILE&quot; (Identifier &quot;file_name&quot; )
End
</pre>
<p>that is,</p>
<ul>
<li><tt>do_open</tt> is a function</li>
<li><tt>do_open</tt> accepts one argument <code>file_name</code></li>
<li>the content of this argument won&#8217;t be modified</li>
<li>this argument doesn&#8217;t seem to require to contain anything specific</li>
<li>the function has one system effect: opening for reading the file whose name was given as <code>file_name</code></li>
<li>the function returns some abstract data, in that case a file whose name name was given as <code>file_name</code>.</li>
</ul>
</li>
<li> The analysis of <code>do_read</code> will result in:
<pre name="code" class="php">

do_read: Function
        input arg fd           : &quot;FILE&quot; (Identifier &quot;extrapol_generated_699 (formerly &lt;anonymous&gt; ) &quot; )
        effect                 : &quot;read&quot; (Identifier &quot;extrapol_generated_699 (formerly &lt;anonymous&gt; ) &quot; )
        return                 : &quot;data read from file&quot; (Identifier &quot;extrapol_generated_699 (formerly &lt;anonymous&gt; ) &quot; )
End
</pre>
<p>that is,</p>
<ul>
<li><tt>do_read</tt> is a function</li>
<li><tt>do_read</tt> accepts one argument <code>fd</code></li>
<li>the content of this argument won&#8217;t be modified</li>
<li>this argument must be abstract data, in that case a file</li>
<li>for the rest of this function we will call the filename <code>extrapol_generated_699 (formerly &lt;anonymous&gt;)"</code></li>
<li>the function has one system effect: reading from the file whose name was given as <code>extrapol_generated_699 (formerly &lt;anonymous&gt; )</code></li>
<li>the function returns some abstract data, in that case data read from the file whose name was given as <code>extrapol_generated_699 (formerly &lt;anonymous&gt; )</code></li>
</ul>
</li>
</ul>
<p style="text-align:justify;">Now, chances are that we may want to use both functions. As it turns out, whenever a function has been analysed, Extrapol places the information it has deduced in its knowledge base (the <em>environment</em>) and may use it for further deductions.</p>
<p>Now, let&#8217;s feed the following additional source to Extrapol:</p>
<pre name="code" class="c">

int main(int argc, char **argv) {
  assert(argc &gt;= 1);
  int   fd  = do_open(argv[0]);
  char* buf = do_read(fd);
  free(buf);
  return 0;
}
</pre>
<p>In return, Extrapol will answer:</p>
<pre name="code" class="php">

main: Function
        input arg argc         : &quot;command-line argument&quot; ()
        input arg argv         : &quot;command-line argument&quot; ()
        input vararg           : &quot;command-line argument&quot; ()
        effect                 : &quot;read&quot; (Identifier &quot;argv&quot; )
        effect                 : &quot;open&quot; (Identifier &quot;argv&quot;, Constant &quot;0&quot; )
        return                 : Constant &quot;0&quot;
End
</pre>
<p style="text-align:justify;">In other words, the effect of the full program will be to open and read from a file whose name was provided as a command-linen argument.</p>
<p style="text-align:justify;">
<h2>How does this work ?</h2>
<p style="text-align:justify;">For today&#8217;s entry, I&#8217;ll take that question with the meaning of &#8220;How do I use it ?&#8221; Well, it&#8217;s simple. Extrapol takes as input one or more C source files (they don&#8217;t have to be pre-processed) and a knowledge base of primitive functions. This knowledge base is an ASCII file with the same format as Extrapol&#8217;s answers.</p>
<p style="text-align:justify;">For instance, to obtain the above demos, we provided Extrapol with the following piece of information for function <code>malloc</code>:</p>
<pre name="code" class="c">

malloc: Function
  input arg size: Bottom
  return: Bottom
End
</pre>
<p style="text-align:justify;">In other words, <code>malloc</code> is a function accepting one argument named <code>size</code>. Nothing special is expected from <code>size</code> and the returned value is compatible with any value.</p>
<p style="text-align:justify;">Now, <code>fread</code> is a more complex function. Here&#8217;s the prototype of the function, as presented in its <code>man</code> page:</p>
<pre name="code" class="c">

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
</pre>
<p>For Extrapol, that&#8217;s a function with 4 arguments and a return value. Let&#8217;s start from the end.</p>
<ul>
<li>The return value could be anything, we won&#8217;t make any guarantee (that&#8217;s called <code>Top</code> &#8212; we could refine that).</li>
<li>The last argument is a file. We&#8217;ve seen earlier how to deal with files, they&#8217;re abstract structures, which we&#8217;ve decided by convention to call <code>"FILE"(foobar)</code>, where <code>foobar</code> is either the name of the file or a pointer to a variable/argument which contains that name. In that context, <code>"FILE"</code> is called a <em>constructor</em>, by the way. It&#8217;s just a character string which we use to differentiate abstract values. Correspondingly, <code>foobar</code> is the <em>argument</em> of <code>"FILE"</code>.</li>
<li>The second to last argument is a number of blocks to read. We&#8217;re just going to ignore it. In other words, that argument is compatible with any value. That&#8217;s <code>Bottom</code>.</li>
<li>The second argument is a size. We&#8217;re also going to ignore it, so <code>Bottom</code> again.</li>
<li>Finally, the first argument is an output argument &#8212; functionally, it&#8217;s a special form of <code>return</code>, so we&#8217;re going to mark that argument as <code>output</code>. We could just specify that it may contain anything and refuse to make any guarantee, but here, we&#8217;re going to refine a bit and specify that it&#8217;s abstract data, read from the file. Let&#8217;s call the constructor <code>"data read from file"</code> and give it as argument the name of the file. This gives <code>"data read from file"(foobar)</code>.</li>
<li>Oh, yeah, and before we forget, this function has a side-effect we&#8217;re interested in: it reads some content from that file <code>foobar</code>. Let&#8217;s call that effect <code>"read"(foobar)</code></li>
</ul>
<p>Or, in full Extrapol syntax:</p>
<pre name="code" class="php">

fread: Function
   output arg ptr: &quot;data read from file&quot; ( Identifier &quot;path&quot; )
   input arg size : Bottom
   input arg nmemb: Bottom
   input arg stream: &quot;FILE&quot; ( Identifier &quot;path&quot; )
   return: Top
   effect: &quot;read&quot; ( Identifier &quot;path&quot; )
End
</pre>
<p style="text-align:justify;">Now, from a set of C source files and this knowledge base, Extrapol will pre-process C, parse it, remove unused symbols then examine the source code and proceed by success deductions until either</p>
<ul>
<li>something goes wrong (typically, a function is used without being defined)</li>
<li>every function has been examined.</li>
</ul>
<p style="text-align:justify;">Extrapol then outputs the result of his deductions, in a format fit for reinjection inside the knowledge base.</p>
<p>If you are curious, the theories behind this notion of deduction are</p>
<ul>
<li>lambda-calculus</li>
<li>dependent types</li>
<li>types with effects</li>
<li>Hindley-Milner-style type inference.</li>
</ul>
<p style="text-align:justify;">This will be detailed further in another blog entry &#8212; and in a journal paper, whenever I find the time to complete it.</p>
<h2>Does it work ?</h2>
<p style="text-align:justify;">The answer is yes, no and maybe.</p>
<ul>
<li>
<p style="text-align:justify;">Maybe: testing on real applications is something yet to do. Currently, Extrapol works on our sample set, a set containing no entry larger than 100 lines. We&#8217;ll know more when we find the courage to test, say, <code>tar</code> or <code>df</code>.</p>
</li>
<li>Yes: everything written above, and a dozen other samples, work.</li>
<li>No: some features are not implemented yet. Function pointers won&#8217;t work, nor will recursivity. I haven&#8217;t put together the theory behind these constructions yet, so I don&#8217;t know yet how hard all of this will be. In addition, for the current prototype, we can&#8217;t deduce anything interesting on global variables yet, and functions need to be declared in the order in which they are used. These two aspects will be easy to fix, they just don&#8217;t have the highest priority.</li>
</ul>
<h2>How is it written ?</h2>
<p>There are currently two different versions of Extrapol:</p>
<ul>
<li>Extrapol/Java is a Java-based implementation of the specification, by Steve-William Kissi, Bastien Jansen and David Teller. It is about 18,000 lines of code and, at this very moment, lags slightly behind the experimental version, Extrapol/ML.</li>
<li>Extrapol/ML is the set of specifications, written in OCaml by David Teller &#8212; as well as the experimental version. It is about 3,000 lines of code, purely functional except for logging.</li>
</ul>
<p style="text-align:justify;">Both versions are meant as open-source, although the licence hasn&#8217;t been 100% decided. Extrapol/Java may end up MIT-style with Extrapol/ML ending up LGPL + linking exception.</p>
<h2>Can I play with it ?</h2>
<p style="text-align:justify;">As soon as we&#8217;ve decided the licence, we&#8217;ll release the current prototypes. Ideally, this should happen before mid-June.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/78/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/78/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/78/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/78/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/78/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=78&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/06/03/extrapol-part-1-from-c-to-effects/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Batteries Included: Lazy Lists version 0.3</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/05/18/batteries-included-lazy-lists-version-03/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/05/18/batteries-included-lazy-lists-version-03/#comments</comments>
		<pubDate>Sun, 18 May 2008 18:40:52 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[parser]]></category>

		<category><![CDATA[open-source]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[Functional Programming]]></category>

		<category><![CDATA[caml]]></category>

		<category><![CDATA[batteries included]]></category>

		<category><![CDATA[lazy evaluation]]></category>

		<category><![CDATA[lazy programming]]></category>

		<category><![CDATA[programming languages]]></category>

		<category><![CDATA[extlib]]></category>

		<category><![CDATA[computing]]></category>

		<category><![CDATA[parsing]]></category>

		<category><![CDATA[parser combinator]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=79</guid>
		<description><![CDATA[An updated version of the Lazy List module for OCaml has just been uploaded to Batteries Included and submitted to ExtLib. See the release notes for more details.
In addition, I am currently using this module to write a parser combinator library for OCaml. This library has reached early testing stage and will hopefully be added [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">An updated version of the Lazy List module for OCaml has just been uploaded to <a href="https://forge.ocamlcore.org/frs/?group_id=17">Batteries Included</a> and submitted to <a href="http://www.google.fr/url?sa=t&amp;ct=res&amp;cd=1&amp;url=http%3A%2F%2Fcode.google.com%2Fp%2Focaml-extlib%2F&amp;ei=v3cwSNH2MqPw-AL39cWIAg&amp;usg=AFQjCNEjWtWFbDXOLrRn-qxFA8-MlL8Ikg&amp;sig2=JV6e1hqE0-KmC5HpgwIeWQ">ExtLib</a>. See the release notes for more details.</p>
<p style="text-align:justify;">In addition, I am currently using this module to write a parser combinator library for OCaml. This library has reached early testing stage and will hopefully be added to Batteries Included soon.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/79/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/79/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/79/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=79&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/05/18/batteries-included-lazy-lists-version-03/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Batteries Included Preview: Enumerations</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/05/13/batteries-included-preview-enumerations/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/05/13/batteries-included-preview-enumerations/#comments</comments>
		<pubDate>Tue, 13 May 2008 19:34:28 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[En français / In French]]></category>

		<category><![CDATA[OCaml]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=75</guid>
		<description><![CDATA[I have made available the first preview of a second module for OCaml Batteries Included module: Enum. This module builds upon ExtLib&#8217;s enumerations (which it means to replace, if it is accepted upstream) and provides support for representation-independent iterators. These iterators are used pervasively in ExtLib and will also be used pervasively in the rest [...]]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">I have made available the first preview of a second module for OCaml Batteries Included module: Enum. This module builds upon ExtLib&#8217;s enumerations (which it means to replace, if it is accepted upstream) and provides support for representation-independent iterators. These iterators are used pervasively in ExtLib and will also be used pervasively in the rest of Batteries Included, as a manner of converting data from/to data structures and as a base for syntax extensions.</p>
<p style="text-align:justify;">With respect to ExtLib&#8217;s current implementation, this release adds</p>
<ul>
<li>numerous powerful constructors and manipulation functions</li>
<li>functions inspired from SDFlow and dedicated to cooperative</li>
<li>better management of infinite iterators</li>
<li>better management of iterators created using <code>from</code></li>
<li>syntactic sugar.</li>
</ul>
<p style="text-align:justify;">As an example of the last point, let us note that it is now possible, without any Camlp4 extension, to replace <code>for</code> loops with a more (stream-)functional counterpart. That is, instead of</p>
<pre name="code" class="python">

for i = 1 to n do
    (*...*)
done
</pre>
<p>one may now write</p>
<pre name="code" class="python">

iter (fun i -&gt; (* ... *) )
  (5 -- 10)
</pre>
<p>for an imperative loop or</p>
<pre name="code" class="python">

map (fun i -&gt; (* ... *) )
  (5 -- 10)
</pre>
<p>for a lazy transformation, etc. It won&#8217;t improve performance and it doesn&#8217;t look more readable at first glance, but it allows short expressions such as :</p>
<pre name="code" class="python">

iter printf (5 -- 10) (*to print all numbers between 5 and 10*)
map ( ~ ) (5 --10) (*to obtain enumeration -5, -6, -7, -8, -9, -10 *)
fold ( + ) 0 ( 5 -- 10 )(*to sum all numbers between 5 and 10*)
</pre>
<p>etc. Everything is computed lazily, without allocating any intermediate data structure.</p>
<p>Code may be found <a href="https://forge.ocamlcore.org/frs/?group_id=17">here</a>.</p>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/75/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/75/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/75/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/75/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/75/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=75&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/05/13/batteries-included-preview-enumerations/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
		<item>
		<title>Quelques mots de programmation paresseuse</title>
		<link>http://dutherenverseauborddelatable.wordpress.com/2008/05/11/quelques-mots-de-programmation-paresseuse/</link>
		<comments>http://dutherenverseauborddelatable.wordpress.com/2008/05/11/quelques-mots-de-programmation-paresseuse/#comments</comments>
		<pubDate>Sun, 11 May 2008 20:20:22 +0000</pubDate>
		<dc:creator>yoric</dc:creator>
		
		<category><![CDATA[En français / In French]]></category>

		<category><![CDATA[Enseignement]]></category>

		<category><![CDATA[Informatique / Computer science]]></category>

		<category><![CDATA[OCaml]]></category>

		<category><![CDATA[programmation]]></category>

		<category><![CDATA[open-source]]></category>

		<category><![CDATA[lazy]]></category>

		<category><![CDATA[flux]]></category>

		<category><![CDATA[listes paresseuses]]></category>

		<category><![CDATA[haskell]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Programmation Fonctionnelle]]></category>

		<category><![CDATA[caml]]></category>

		<category><![CDATA[batteries included]]></category>

		<category><![CDATA[lazy evaluation]]></category>

		<category><![CDATA[lazy programming]]></category>

		<category><![CDATA[batteries]]></category>

		<category><![CDATA[osr]]></category>

		<category><![CDATA[langages de programmation]]></category>

		<category><![CDATA[programmation paresseuse]]></category>

		<category><![CDATA[évaluation paresseuse]]></category>

		<category><![CDATA[programming languages]]></category>

		<category><![CDATA[itérateurs]]></category>

		<category><![CDATA[générateurs]]></category>

		<category><![CDATA[objective caml]]></category>

		<category><![CDATA[generics]]></category>

		<category><![CDATA[extlib]]></category>

		<guid isPermaLink="false">http://dutherenverseauborddelatable.wordpress.com/?p=73</guid>
		<description><![CDATA[These last few days, I've been working a lot with and on OCaml, both for project ExtraPol (which I'll eventually present on this blog, promised) and Batteries Included (the on-going renovation of OCaml's standard library). In particular, I've just finalized a module for managing lazy lists. Lazy ? Indeed, lazy.

Let's take a few minutes to explore the notion of laziness in programming.]]></description>
			<content:encoded><![CDATA[<div class='snap_preview'><br /><p style="text-align:justify;">Ces jours-ci, je travaille beaucoup avec et sur OCaml, que ce soit pour le projet ExtraPol (dont je finirai bien par vous glisser quelques mots) ou pour <a href="https://forge.ocamlcore.org/mail/admin/index.php?group_id=17">Batteries Included</a> (la rénovation en cours de la bibliothèque standard de OCaml). En particulier, je viens de finaliser un module de <a href="https://forge.ocamlcore.org/frs/shownotes.php?release_id=12">gestion des listes paresseuses</a>. Paresseuses ? Oui, paresseuses.</p>
<p style="text-align:justify;">Attardons-nous un moment sur le concept de <em>paresse</em> en programmation.</p>
<p><span id="more-73"></span></p>
<h2>En Java (ou C++ ou C# ou &#8230;)</h2>
<p style="text-align:justify;">Presque tous les langages de programmation permettent, de manière restreinte, de définir des expressions paresseuses, c&#8217;est-à-dire des expressions dont le résultat n&#8217;est calculé que s&#8217;il peut influencer l&#8217;exécution du programme. Ainsi, en Java, nous pourrons définir la méthode <code>isEquals</code> suivante :</p>
<pre name="code" class="java">

bool isEquals(Object x)
{
  return x &amp;&amp; x.equals(myObject);
}
</pre>
<p style="text-align:justify;">Ici, au cours de l&#8217;exécution de cette fonction, <code>x.equals(myObject)</code> ne sera ffectivement évalué que si <code>x</code> n&#8217;est pas <code>null</code>. Java définit ainsi trois opérateurs paresseux <code>&amp;&amp;</code>, <code>||</code> et <code>?:</code> : dans chacun des trois cas, à l&#8217;exécution du programme, la première opérande est évaluée avant de décider que faire de la deuxième (et de la troisième, dans le cas de <code>?:</code>). Ces constructions sont très utiles, mais sont loin de couvrir toutes les circonstances dans lesquelles la paresse peut s&#8217;avérer utile.</p>
<p style="text-align:justify;">Ainsi, imaginons un instant que nous souhaitons écrire une bibliothèque de journalisation, dont le rôle est d&#8217;enregistrer des messages dans un fichier au fur et à mesure de l&#8217;exécution du programme. Ajoutons une contrainte : les messages ne doivent être effectivement enregistrés que lorsque le journal est activé, par exemple parce que l&#8217;utilisateur est en mode de débogage :</p>
<pre name="code" class="java">

void log(String s)
{
   if(LOG) stream.println(s);
}
</pre>
<p>La méthode <code>log</code> sera typiquement invoquée des centaines de fois durant l&#8217;exécution du code, sous la forme suivante :</p>
<pre name="code" class="java">

void myFunction(int i, int j, int k)
{
   myLog.log(&quot;Entering myFunction(&quot;+i+&quot;, &quot;+j+&quot;, &quot;+j+&quot;)&quot;);
   //...
   myLog.log(&quot;Leaving myFunction()&quot;);
}
</pre>
<p style="text-align:justify;">Des centaines de fois, nous aurons donc besoin de calculer le résultat de <code>"Entering myFunction("+i+", "+j+", "+j+")"</code>, soit trois conversions d&#8217;entiers en chaînes de caractères, 6 concaténations de chaînes de caractères et un gaspillage de mémoire vive que nous pourrions éviter lorsque <code>LOG</code> est <code>false</code>. Comment faire pour éviter ce gaspillage ? La première possibilité consiste à exposer la valeur de <code>LOG</code> à tout le programme et à laisser le programmeur écrire plutôt</p>
<pre name="code" class="c">

void myFunction(int i, int j, int k)
{
   if(LOG) myLog.log(&quot;Entering myFunction(&quot;+i+&quot;, &quot;+j+&quot;, &quot;+j+&quot;)&quot;);
   //...
   if(LOG) myLog.log(&quot;Leaving myFunction()&quot;);
}
</pre>
<p style="text-align:justify;">Malheureusement, cette transformation nous oblige à contaminer tout le programme avec ce champ <code>LOG</code>, au détriment de la lisibilité et de l&#8217;extensibilité. En C ou C++, on pourrait cacher ce <code>LOG</code> derrière une macro, cette fois au détriment du débogage, de la modularité et de la robustesse. En Java, si nous n&#8217;avons pas une telle possibilité, nous pouvons utiliser des classes anonymes  pour arriver aux mêmes fins :</p>
<p>Commençons par modifier notre bibliothèque de journalisation :</p>
<pre name="code" class="java">

public interface LazyString
{
   public String toString();
}

void log(Object s)
{
   if(LOG) stream.println(s.toString());
}
</pre>
<p style="text-align:justify;">L&#8217;interface LazyString n&#8217;est guère contraignante : elle se contente de promettre que les objets qui l&#8217;implantent dispoent bien d&#8217;une méthode publique String toString(), qui servira à extraire de l&#8217;objet une chaîne de caractères. La différence avec ce qui précède est que nous pouvons nous débrouiller pour que la construction de la chaîne de caractères n&#8217;ait lieu qu&#8217;au moment où la méthode println est invoquée. En particulier, cette construction n&#8217;aura jamais lieu si <code>LOG</code> est false. Pour utiliser cette nouvelle version du journal, nous pourrons réécrire myFunction de la manière suivante :</p>
<pre name="code" class="java">

void myFunction(int i, int j, int k)
{
   myLog.log(new LazyString() { public String toString() { return &quot;Entering myFunction(&quot;+i+&quot;, &quot;+j+&quot;, &quot;+j+&quot;)&quot; });
   //...
   myLog.log(&quot;Leaving myFunction()&quot;);
}
</pre>
<p style="text-align:justify;">Est-ce la fin de l&#8217;histoire ? Pas tout à fait. Pour le moment, en Java, nous ne pouvons pas améliorer la syntaxe lors de l&#8217;appel de <code>log</code> &#8212; en tant que langage, Java est connu pour sa lourdeur syntaxique. En l&#8217;absence d&#8217;un préprocesseur digne de ce nom, nous ne pourrons rien faire de ce côté-là. Par contre, nous pouvons nous attaquer à un autre problème, qui se posera dès que nous serons confrontés à une méthode <code>log</code> à peine peu plus complexe :</p>
<pre name="code" class="java">

void log(Object s)
{
   if(LOG_TO_FILE) file_stream.println(s.toString());
   if(LOG_TO_WINDOW) text_pane.out.println(s.toString());
   if(LOG_TO_STATUSBAR) statusbar.setText(s.toString());
}
</pre>
<p style="text-align:justify;">Ici, <code>s.toString()</code> sera invoqué trois fois et calculera trois fois le même résultat. Pour un exemple aussi simple que le nôtre, ce n&#8217;est pas encore bien grave, mais on peut imaginer des contextes dans lesquels le calcul serait suffisamment long pour que ce délai soit inacceptable.</p>
<p style="text-align:justify;">Qu&#8217;à cela ne tienne, il suffit de réécrire <code>log</code> de manière à retenir la valeur de <code>s.toString()</code>. Voire mieux, nous pouvons encapsuler tout ceci dans une classe plus générique :</p>
<pre name="code" class="java">

public interface Result&lt;T&gt;
{
   public T getValue();
}
public abstract class Lazy&lt;T&gt;
{
   private boolean computed = false;
   private T value = null;
   /**
    * Proceeds to the actual computation.
    * This method will only be called once.
    */
   protected abstract T value();
   public final synchronized T getValue()
   {
      if(computed == false)
      {
        value       = value();
        computed = true;
      }
      return value;
   }
}

public abstract class LazyString extends Lazy&lt;String&gt;
{
   public String toString()
   {
      return this.getValue();
   }
}
</pre>
<p>En modifiant <code>myFunction</code> pour utiliser cette nouvelle version de <code>LazyString</code>, nous obtenons :</p>
<pre name="code" class="java">

void myFunction(int i, int j, int k)
{
   myLog.log(new LazyString() { protected String value() { return &quot;Entering myFunction(&quot;+i+&quot;, &quot;+j+&quot;, &quot;+j+&quot;)&quot; });
   //...
   myLog.log(&quot;Leaving myFunction()&quot;);
}
</pre>
<p style="text-align:justify;">Qu&#8217;avons-nous gagné ? Nous avons maintenant sous la main une interface Result&lt;T&gt; qui permet de représenter une opération. Si l&#8217;objet qui implante Result&lt;T&gt; est en fait un Lazy&lt;T&gt;, le calcul ne sera effectué que si son résultat est effectivement consulté. Si le résultat est consulté plusieurs fois (potentiellement par plusieurs threads différents), le calcul n&#8217;est toujours effectué qu&#8217;une seul fois.</p>
<p style="text-align:justify;">Nous venons d&#8217;ajouter une dose d&#8217;évaluation paresseuse à Java.</p>
<p style="text-align:justify;">Pour aller plus loin, regardons du côté de la programmation fonctionnelle &#8212; et des structures de données paresseuses.</p>
<h2>Du côté de la programmation fonctionnelle</h2>
<p>Commençons par réécrire en OCaml la première version de nos fonctions :</p>
<pre name="code" class="python">

let log s = if should_log then output stream s
</pre>
<p style="text-align:justify;">Nous venons de définir, comme en Java, une fonction nommée log, qui accepte comme paramètre un argument s &#8212; ici, une chaîne de caractères. Le contenu de la fonction log instruit d&#8217;écrire s sur un certain flux stream, si une certaine valeur booléenne should_log est vraie. Comme en Java, nous invoquerons cette fonction depuis my_function, à l&#8217;aide de :</p>
<pre name="code" class="python">

let my_function i j k =
  log (sprintf &quot;Entering my_function %i %i %i&quot; i j k);
  (* ... *)
  log &quot;Leaving my_function&quot;
</pre>
<p style="text-align:justify;">Jusque-là, à part les parenthèses et l&#8217;utilisation de la fonction <code>sprintf</code>, rien de bien différent. De nouveau, il est nécessaire de convertir i, j et k en chaînes de caractères et de procéder à quelques concaténations.</p>
<p style="text-align:justify;">À partir d&#8217;ici, comme en Java, nous pouvons définir équivalent de Lazy&lt;T&gt;, que nous appellerions probablement <code>'a lazy</code>, doté d&#8217;un constructeur qui acceptera en argument une fonction dont le résultat est un <code>'a</code>, etc. La transformation de notre code pour convertir log en appel paresseux est globalement similaire à ce que nous ferions en Java. De fait, tout ceci n&#8217;est pas nécessaire puisque puisque la programmation paresseuse est en fait une primitive du langage. Le mot-clé <code>lazy</code> introduit une expression de type <code>'a Lazy.t</code>, c&#8217;est-à-dire dont le résultat est de type <code>'a</code> et ne sera calculé que s&#8217;il est nécessaire. La fonction <code>force : 'a Lazy.t -&gt; 'a</code> permet alors de consulter le résultat d&#8217;une valeur ainsi mise en réserve, en la calculant au passage si nécessaire. De fait, notre version définitive ressemblera à</p>
<pre name="code" class="python">

open Lazy
let log s =
  if should_log_1 then output stream_1 (force s);
  if should_log_2 then output stream_2 (force s);
  if should_log_3 then output stream_3 (force s)

let my_function i j k =
  log (lazy (sprintf &quot;Entering my_function %i %i %i&quot; i j k));
  (* ... *)
  log (lazy &quot;Leaving my_function&#038;quot <img src='http://s.wordpress.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> 
</pre>
<p style="text-align:justify;">Notons au passage qu&#8217;il ne serait pas possible de réécrire directement lazy sous la forme d&#8217;une fonction OCaml. Pour réinventer <code>lazy</code>, il serait nécessaire de passer par Camlp4 ou d&#8217;accepter des notations légèrement plus lourdes.</p>
<h2>Et alors ?</h2>
<p style="text-align:justify;">Il va falloir que je vous avoue quelque chose : je me moque complètement de la fonction <code>log</code>. Dans la programmation paresseuse, le plus intéressant, c&#8217;est bien les structures de données.</p>
<p>Tenez, en Java, nous pouvons très bien redéfinir la notion d&#8217;itérateurs de la manière suivante :</p>
<pre name="code" class="java">

public interface MyIterator&lt;T&gt;
{
  public Lazy&lt;MyIterator&lt;T&gt;&gt; next();
  public T value;
}
</pre>
<p>Un itérateur est ici un objet capable de contenir une valeur&#8230; et de renvoyer un autre itérateur, qui représente la suite de l&#8217;itération. On écrira de même en OCaml :</p>
<pre name="code" class="python">

type &#039;a my_iterator = Iterator of &#039;a * &#039;a my_iterator Lazy.t
</pre>
<p>Complétons cette définition pour nous autoriser à construire des itérations <em>finies</em> :</p>
<pre name="code" class="python">

type &#039;a node =
 | Nil
 | Cons of &#039;a * &#039;a lazy_list
type &#039;a lazy_list = (&#039;a node) Lazy.t
</pre>
<p style="text-align:justify;">Nous venons de définir la notion de <em>liste paresseuse</em>. Une liste paresseuse est une valeur paresseuse qui, une fois évaluée, produit soit le résultat <code>Nil</code> (la liste vide), soit un résultat de la forme <code>Cons(h, t)</code> où <code>h</code> est une valeur et <code>t</code> est la suite de la liste paresseuse.</p>
<p style="text-align:justify;">À partir de cette définition, nous pouvons construire une fonction <code>range</code>, qui servira à représenter un intervalle d&#8217;entiers :</p>
<pre name="code" class="python">

let rec range i j =
 if i &gt;= j then Nil
 else            range (i+1) j
</pre>
<p>Ainsi, en OCaml, <code>range 0 100000</code> calculera les nombres 0, 1, &#8230;, 100000 au fur et à mesure qu&#8217;ils seront demandés.</p>
<p style="text-align:justify;">À partir de là, nous pouvons définir les transformations habituelles sur les structures de données. Ainsi, pour convertir (paresseusement) une liste paresseuse en une autre, comme pour les listes habituelles, nous pouvons définir la fonction <code>map</code> :</p>
<pre name="code" class="python">

let rec map f l = match force l with
  | Nil            -&gt; lazy Nil
  | Cons (h,t) -&gt; lazy Cons (f h, map f t)
</pre>
<p style="text-align:justify;">Cette fonction <code>map</code>, qui sera l&#8217;un des premiers outils que nous placerons dans notre bibliothèque de gestion des listes paresseuses, applique une fonction successivement à chaque élément d&#8217;une liste paresseuse, de manière à obtenir une nouvelle liste paresseuse. Pour doubler tous les éléments de notre intervalle précédent, nous écrirons donc</p>
<pre name="code" class="python">

map (( * ) 2) (range 0 100000)
</pre>
<p style="text-align:justify;">De la même manière, nous pouvons définir le nécessaire pour filtrer les éléments d&#8217;une liste afin de n&#8217;en garder que ceux qui vérifient une propriété donnée, le tout sous la forme d&#8217;une fonction <code>filter</code>, qui rejoindra <code>map</code> dans notre bibliothèque standard.</p>
<pre name="code" class="python">

let rec filter f l = match Lazy.force l with
  | Nil -&gt; lazy Nil
  | Cons(h,t) -&gt; lazy (Cons (f h, filter t))
</pre>
<p style="text-align:justify;">Et à ce prix-là, définissons une fonction <code>iter</code>, tout aussi standard, qui nous permettra d&#8217;appliquer une fonction impérative à tous les éléments d&#8217;une liste paresseuse, de la même manière que la boucle for de Python ou la nouvelle boucle for de Java :</p>
<pre name="code" class="python">

let rec iter f l = match force l with
  | Nil            -&gt; ()
  | Cons (h,t) -&gt; f h; iter t
</pre>
<p style="text-align:justify;">En combinant tout ce qui précède, nous pouvons faire afficher les carrés parfaits de l&#8217;ensemble des nombres pairs des nombres de l&#8217;intervalle [0; 100000].</p>
<pre name="code" class="python">

let is_square x =
  let y = int_of_float (sqrt (float_of_int x)) in
  x = y * y

iter print_int (filter is_square (map (( * ) 2) (range 0 100000)))
</pre>
<p style="text-align:justify;">Comme la liste n&#8217;est consultée qu&#8217;une seule fois, grâce à la magie de la paresse et du ramasse-miettes, tout ceci se fera fait sans avoir à allouer la mémoire vive nécessaire pour retenir tous les entiers entre 0 et 100000.</p>
<p style="text-align:justify;">Jusqu&#8217;ici, toutes les opérations que nous avons vues auraient pu être implantées, peut-être avec quelques difficultés, en utilisant des <em>itérateurs</em> ou des <em>générateurs</em>, tels que ceux que définissent les bibliothèques Java, C#, JavaScript, Python, OCaml etc. Tout comme les listes paresseuses, les itérateurs et générateurs permettent de représenter des suites d&#8217;informations qui ne seront effectivement calculées que lorsqu&#8217;elles seront effectivement consultées. Mais à la différence des listes paresseuses, les itérateurs/générateurs oublient les informations immédiatement après les avoir fournies. Si les itérateurs et générateurs sont très utiles &#8212; et probablement plus optimisés que les listes paresseuses pour les exemples précédents &#8212; leur champ d&#8217;application s&#8217;arrête dès que les données peuvent être utilisées plusieurs fois.</p>
<p style="text-align:justify;">Ainsi, considérons l&#8217;une des applications majeures des itérateurs/générateurs et des listes paresseuses : l&#8217;analyse de langages, et plus particulièrement l&#8217;analyse lexicale et syntaxique d&#8217;un code source. Le plus fréquemment, on commence par considérer le fichier d&#8217;entrée comme un itérateur/générateur de caractères. Un filtre, l&#8217;<em>analyseur lexical</em>, s&#8217;applique alors à cet itérateur pour le transformer en itérateur de <em>lexèmes</em> &#8212; c&#8217;est le rôle d&#8217;outils tels que Lex, Flex ou, aussi surprenant que cela puisse paraître, Sax. Ce deuxième itérateur est alors consommé par un <em>analyseur syntaxique</em>, dont le rôle est de produire un arbre de syntaxe abstraite, qui représentera le code source en mémoire vive &#8212; c&#8217;est, cette fois, le rôle d&#8217;outils tels que Bison, Yacc ou DOM. Ces derniers, ainsi que [presque tous] leurs concurrents, consultent à l&#8217;avance k lexèmes depuis l&#8217;itérateur de lexème, pour un certain k fixé lors de la conception de l&#8217;analyseur, émettent des hypothèses en partant de ces k lexèmes, et ne peuvent pas revenir en arrière, en cas d&#8217;erreur, de plus de k pas. À l&#8217;inverse, et de manière très schématique, les combinateurs de parseurs construits sur des listes paresseuses, tels que Parsec (pour Haskell) ou PLC (pour OCaml), ne sont pas limités par ces k lexèmes d&#8217;avance, puisqu&#8217;ils peuvent à volonté revenir en arrière dans la liste. Un élément ne disparaît de la liste paresseuse que lorsque sa valeur ne peut plus influencer l&#8217;exécution du programme. Cette conception à base de listes paresseuses se paye en termes de performances et de consommation de mémoire mais offre beaucoup plus de flexibilité, notamment la possibilité de construire ou de modifier dynamiquement des analyseurs syntaxiques.</p>
<p style="text-align:justify;">Avant de conclure sur la comparaison entre itérateurs et listes paresseuses, précisons brièvement qu&#8217;il est aisé de construire l&#8217;un par-dessus l&#8217;autre : un itérateur est une liste paresseuse qui oublie ses éléments au fur et à mesure qu&#8217;ils sont consommés, alors qu&#8217;une liste paresseuse est un itérateur qui retient ses éléments jusqu&#8217;à intervention du ramasse-miettes. Ainsi, dans la bibliothèque sur laquelle je travaille, la conversion d&#8217;une liste paresseuse en itération s&#8217;est écrite, jusqu&#8217;à une récente optimisation :</p>
<pre name="code" class="python">

let enum l =
  let reference = ref l in
    Enum.from (fun () -&gt; match next !reference with
			 | Cons(x,t) -&gt; reference := t; x
			 | Nil          -&gt; raise Enum.No_more_elements )
</pre>
<p style="text-align:justify;">Dans cet extrait de code, nous commençons par déclarer une variable modifiable nommée <code>reference</code> et qui désignera initialement le premier élément de la liste. Nous définissons alors une fonction anonyme qui, lorsqu&#8217;elle sera appelée, renverra l&#8217;élément actuel désigné par <code>reference</code>, ou, si nous avons dépassé la fin de la liste, lancera une exception <code>Enum.No_more_elements</code> pour signaler que l&#8217;itérateur est terminé. La fonction <code>Enum.from</code> construit l&#8217;itérateur dont le comportement est donné par cette fonction.</p>
<p style="text-align:justify;">À l&#8217;inverse, pour convertir un itérateur en liste paresseuse, nous employons la fonction suivante :</p>
<pre name="code" class="python">

let of_enum e =
  let rec aux () =
    lazy (match Enum.get e with
      |	Some x -&gt; Cons (x, aux () )
      | None    -&gt; Nil )
  in aux ()
</pre>
<p style="text-align:justify;">Dans l&#8217;extrait, nous commençons par définir une boucle que nous nommons <code>aux</code> et dons le contenu est paresseux. À chaque fois qu&#8217;un nouvel élément de la liste est consulté, nous consommons la valeur du prochain élément de notre itérateur. Si celui-ci existe, nous l&#8217;appelons <code>x</code>, et ce <code>x</code> constitue le prochain élément de notre liste, tandis que la suite de la liste sera donnée par le résultat de la prochaine invocation de la boucle <code>aux</code>. Dans le cas contraire, la liste est terminée.</p>
<h2>Références :</h2>
<ul>
<li>Pour plus de détails sur la distinction entre générateurs, itérateurs et listes paresseuses, je vous invite à consulter <a href="http://home.pipeline.com/~hbaker1/Iterator.html">Iterators: Signs of Weakness in Object-Oriented Languages, par Henry G. Baker</a>.</li>
<li>Pour plus de détails sur le module de listes paresseuses de Batteries Included, le code source est disponible <a href="https://forge.ocamlcore.org/frs/shownotes.php?release_id=12">sur OCaml Forge</a>. Le code source du module Enum, qui définit des itérateurs pour OCaml, est disponible avec le reste de la bibliothèque ExtLib, <a href="http://code.google.com/p/ocaml-extlib/">sur Google Code</a>.</li>
<li>Pour plus de détails sur la programmation paresseuse en OCaml, le <a href="http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lazy.html">guide de référence</a> est à votre disposition.</li>
<li>Enfin, rendons à César ce qui appartient à César. Si l&#8217;évaluation paresseuse vous intéresse, vous êtes vivement encouragés à vous informer sur le langage de programmation Haskell, dans lequel toutes les évaluations sont paresseuses par défaut.</li>
</ul>
<img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/dutherenverseauborddelatable.wordpress.com/73/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/dutherenverseauborddelatable.wordpress.com/73/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dutherenverseauborddelatable.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dutherenverseauborddelatable.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dutherenverseauborddelatable.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dutherenverseauborddelatable.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dutherenverseauborddelatable.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dutherenverseauborddelatable.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dutherenverseauborddelatable.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dutherenverseauborddelatable.wordpress.com/73/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dutherenverseauborddelatable.wordpress.com/73/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dutherenverseauborddelatable.wordpress.com/73/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dutherenverseauborddelatable.wordpress.com&blog=1202429&post=73&subd=dutherenverseauborddelatable&ref=&feed=1" /></div>]]></content:encoded>
			<wfw:commentRss>http://dutherenverseauborddelatable.wordpress.com/2008/05/11/quelques-mots-de-programmation-paresseuse/feed/</wfw:commentRss>
	
		<media:content url="http://a.wordpress.com/avatar/yoric-128.jpg" medium="image">
			<media:title type="html">yoric</media:title>
		</media:content>
	</item>
	</channel>
</rss>