﻿<?xml version="1.0" encoding="utf-8"?><rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><ttl>60</ttl><title>nLeyten</title><link>http://nleyten.com</link><lastBuildDate>Thu, 11 Mar 2010 16:27:59 GMT</lastBuildDate><pubDate>Thu, 11 Mar 2010 16:27:59 GMT</pubDate><language>en</language><copyright /><itunes:subtitle> </itunes:subtitle><itunes:author /><itunes:summary /><description /><itunes:owner><itunes:name /><itunes:email>darioteixeira@yahoo.com</itunes:email></itunes:owner><itunes:explicit>no</itunes:explicit><itunes:category text="Arts" /><item><title>Ocsigen by example, Part 7: Co-services</title><link>http://nleyten.com/2009/04/01/ocsigen-by-example-part-7-coservices.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;
&lt;p&gt; Today's example focuses on co-services.  A co-service
is basically a service that shares its URL with a
"parent" service, but which may have different parameters.
Co-services are often used together with sessions to
personalise a given URL for one specific user. &lt;/p&gt;

&lt;p&gt; Since co-services share the same URL, how does
Eliom know which one is being invoked?  That distinction
is made via a special hidden parameter.  However, it is
nothing that you should be worried about, as it happens
transparently to the developer. &lt;/p&gt;

&lt;p&gt; The code below is a minimalistic illustration of the
possible use for a co-service.  I suggest that you use the
"view source" functionality of your browser to observe
the hidden parameter contained in the page. &lt;/p&gt;

&lt;pre&gt;(************************************************************************)&lt;br&gt;(* Coservice demonstration.                                             *)&lt;br&gt;(************************************************************************)&lt;br&gt;&lt;br&gt;open XHTML.M&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Declaration of the "foobar" service.  Note that we are not&lt;br&gt;    registering it yet, and therefore we do not provide the handler&lt;br&gt;    at this point.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let foobar_service =&lt;br&gt;    Eliom_services.new_service&lt;br&gt;        ~path: [""]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        ()&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Declaration of the "foobar2" service, which is actually a&lt;br&gt;    coservice for "foobar".  Coservices share the same path as&lt;br&gt;    the main service, but may have different parameters.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let foobar2_service = &lt;br&gt;    Eliom_services.new_coservice&lt;br&gt;        ~fallback: foobar_service&lt;br&gt;        ~get_params: (Eliom_parameters.int "amount")&lt;br&gt;        ()&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Handler for "foobar" service.  It displays the current value of&lt;br&gt;    the counter and provides links to reload itself or to invoke the&lt;br&gt;    coservice with different parameters.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let counter = ref 0&lt;br&gt;&lt;br&gt;let foobar_handler sp () () = &lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "")) [])&lt;br&gt;        (body [p    [&lt;br&gt;                pcdata "counter is equal to ";&lt;br&gt;                pcdata (string_of_int !counter);&lt;br&gt;                br ();&lt;br&gt;                Eliom_predefmod.Xhtml.a foobar_service sp [pcdata "reload"] ();&lt;br&gt;                br ();&lt;br&gt;                Eliom_predefmod.Xhtml.a foobar2_service sp [pcdata "increment by 1"] 1;&lt;br&gt;                br ();&lt;br&gt;                Eliom_predefmod.Xhtml.a foobar2_service sp [pcdata "increment by 2"] 2;&lt;br&gt;                ]]))&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Handler for the "foobar2" service (the coservice of "foobar").&lt;br&gt;    Note that this handler just increments the counter by the amount&lt;br&gt;    specified in the GET parameter and then invokes the handler of&lt;br&gt;    "foobar" to display the actual page.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let foobar2_handler sp amount () =&lt;br&gt;    counter := !counter + amount;&lt;br&gt;    foobar_handler sp () ()&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Registration of the services.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let () =&lt;br&gt;    Eliom_predefmod.Xhtml.register foobar_service foobar_handler;&lt;br&gt;    Eliom_predefmod.Xhtml.register foobar2_service foobar2_handler&lt;/pre&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/04/01/ocsigen-by-example-part-7-coservices.aspx#Comments</comments><guid isPermaLink="false">1397379b-f538-4e09-b131-b24de612f0da</guid><pubDate>Wed, 01 Apr 2009 19:57:00 GMT</pubDate></item><item><title>Ocsigen by example, Part 6: POST services</title><link>http://nleyten.com/2009/03/24/ocsigen-by-example-part-6-post-services.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; In the &lt;a href="http://nleyten.com/2009/03/19/ocsigen-by-example-part-5-get-forms.aspx"&gt;previous
instalment&lt;/a&gt; of this series, the example illustrated the
creation of a form for a GET service.  This time we'll
see a similar example, but one whose service uses POST
instead of GET.  &lt;/p&gt;

&lt;p&gt; GET and POST are just two of the verbs part of
the HTTP specification (other verbs are HEAD, PUT,
DELETE, etc).  The main visible difference is that a
GET request encodes the parameters into the URL, whereas
POST does so in the body of the request.  It is therefore
common that web developers pick one or the other based
solely on this distinction.  This criterion is however
fundamentally wrong.  GET should be used &lt;b&gt;only&lt;/b&gt;
for services that do not cause side-effects, and which
are typically idempotent.  Using GET disregarding
this rule may subject your users to possible &lt;a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery"&gt;cross-site
request forgery&lt;/a&gt; attacks. &lt;/p&gt;

&lt;p&gt; As illustrated by the code below, the first thing
to notice about POST services is that they require the
declaration of the GET fallback service.  The reason
is because POST services encode parameters in the body
of the request, and therefore their parameters are not
recorded if the user bookmarks the URL.  This requirement
may seem annoying at first, but it fits very well with
the emphasis on correctness that permeates Ocsigen/Eliom
(and the Ocaml ecosystem in general).  Another thing to
notice is that function Eliom_predefmod.Xhtml.post_form
(the POST counterpart of Eliom_predefmod.Xhtml.get_form)
also requires the GET parameters for the service. &lt;/p&gt;

&lt;p&gt; When trying this example, I suggest you reload the
"coucou" URL after its first invocation via the form.
You will see that upon the second invocation the
fallback page is displayed, because no POST parameters
were specified. (Depending on the browser, simply hitting
"reload" will resend the POST parameters; therefore, select
the URL and press ENTER for a clean invocation). &lt;/p&gt;

&lt;pre&gt;(************************************************************************)&lt;br&gt;(* Services with POST parameters.                                       *)&lt;br&gt;(************************************************************************)&lt;br&gt;&lt;br&gt;open XHTML.M&lt;br&gt;open Eliom_parameters&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  This service is just the fallback for the "coucou" service, and&lt;br&gt;    is never meant to be directly invoked.  Eliom forces one to declare&lt;br&gt;    these fallbacks because browsers bookmark only the GET parameters&lt;br&gt;    and not the POST ones.  There is therefore a chance the service is&lt;br&gt;    invoked without any POST parameters.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let fallback_handler _ () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Fallback")) [])&lt;br&gt;        (body [p [pcdata "You've invoked the fallback service for coucou"]]))&lt;br&gt;&lt;br&gt;let fallback_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: ["coucou"]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        fallback_handler&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Service "coucou" takes no GET parameters and one POST parameter.&lt;br&gt;    Note that during the service registration the service path is not&lt;br&gt;    indicated, since it will be the same as the fallback's.  The same&lt;br&gt;    goes for the GET parameters.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let coucou_handler _ () foo =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Coucou")) [])&lt;br&gt;        (body [p [pcdata ("The POST parameter is " ^ foo)]]))&lt;br&gt;&lt;br&gt;let coucou_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_post_service&lt;br&gt;        ~fallback: fallback_service&lt;br&gt;        ~post_params: (Eliom_parameters.string "foo")&lt;br&gt;        coucou_handler&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  This function creates a form for the "coucou" service.  Note that&lt;br&gt;    proper XHTML forms should be divided into fieldsets, and that any&lt;br&gt;    input widget should have a matching label, as indicated via its ID.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let coucou_form enter_foo =&lt;br&gt;    let enter_foo_label = "enter_foo"&lt;br&gt;    in  [&lt;br&gt;        fieldset&lt;br&gt;            [&lt;br&gt;            label ~a:[a_for enter_foo_label] [pcdata "String foo:"];&lt;br&gt;            Eliom_predefmod.Xhtml.string_input ~a:[a_id enter_foo_label] ~input_type:`Text ~name:enter_foo ();&lt;br&gt;            Eliom_predefmod.Xhtml.string_input ~input_type:`Submit ~value:"Click" ()&lt;br&gt;            ]&lt;br&gt;        ]&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "main" service creates a form for the "coucou" POST service.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let main_handler sp () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Main")) [])&lt;br&gt;        (body   [&lt;br&gt;            p [pcdata "Please fill in this form:"];&lt;br&gt;            Eliom_predefmod.Xhtml.post_form coucou_service sp coucou_form ()&lt;br&gt;            ]))&lt;br&gt;&lt;br&gt;let main_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: [""]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        main_handler&lt;br&gt;&lt;/pre&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/03/24/ocsigen-by-example-part-6-post-services.aspx#Comments</comments><guid isPermaLink="false">ddee1869-c4cd-4bfa-b3e0-b3d57b7c10e5</guid><pubDate>Tue, 24 Mar 2009 16:57:00 GMT</pubDate></item><item><title>Ocsigen by example, Part 5: GET forms</title><link>http://nleyten.com/2009/03/19/ocsigen-by-example-part-5-get-forms.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;
&lt;p&gt; We've previously seen that Eliom ensures
that hyperlinks to services are type-safe, ie, you
cannot for example provide an alphabetic string (or no
parameters at all) to a service that expects an integer.
This type-safety is also extended to the creation and
validation of XHTML forms.  You can therefore provide
together with a service a function that creates forms for
that service.  Eliom — or rather the compiler —
makes sure the types are in harmony.  Moreover, bear in
mind that before invoking a service with any parameters,
Eliom first checks that the parameters have values as
expected.  It will therefore raise an error if the user
provided us with an alphabetic string in a form field
that required an integer or a float, for example (it is of
course possible to provide a custom handler for this sort
of error situations instead of relying on the default one
— check the &lt;a href="http://www.ocsigen.org/eliom"&gt;
Eliom tutorial&lt;/a&gt; for details). &lt;/p&gt;

&lt;p&gt;Another cool feature is the possibility of Eliom
services accepting custom types, and not just the
predefined integers, floats, strings, etc.  Again, check
the tutorial for details. &lt;/p&gt;

&lt;p&gt; The code below demonstrates the use of GET forms.
It defines a "coucou" service taking three GET parameters
of different types, and defines also a function
"coucou_form" to create the contents of a form for
"coucou".  In service "main", this function is used as a
parameter to Eliom_predefmod.Xhtml.get_form to actually
create the form. &lt;/p&gt;

&lt;pre&gt;(************************************************************************)&lt;br&gt;(* Demonstration of forms for services with GET parameters.             *)&lt;br&gt;(************************************************************************)&lt;br&gt;&lt;br&gt;open XHTML.M&lt;br&gt;open Eliom_parameters&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Service "coucou" takes three GET parameters and no POST parameters.&lt;br&gt;*)&lt;br&gt;let coucou_handler _ (i, (j, s)) () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Coucou")) [])&lt;br&gt;        (body [p&lt;br&gt;            [&lt;br&gt;            pcdata "You sent: ";&lt;br&gt;            strong [pcdata (string_of_int i)];&lt;br&gt;            pcdata ", ";&lt;br&gt;            strong [pcdata (string_of_float j)];&lt;br&gt;            pcdata " and ";&lt;br&gt;            strong [pcdata s]&lt;br&gt;            ]]))&lt;br&gt;&lt;br&gt;&lt;br&gt;let coucou_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: ["coucou"]&lt;br&gt;        ~get_params: (Eliom_parameters.int "i" ** (Eliom_parameters.float "j" ** Eliom_parameters.string "s"))&lt;br&gt;        coucou_handler&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  This function is used for building forms for service "coucou".&lt;br&gt;    Note that its parameter is a nested pair defined in the same&lt;br&gt;    fashion as the GET parameters for "coucou".  Also note that&lt;br&gt;    proper XHTML forms should make use of fieldsets for logically&lt;br&gt;    dividing the form, and that field labels should be declared&lt;br&gt;    with the &lt;label&gt; element and associated to the form field they&lt;br&gt;    refer to via the ID attribute.  Declaring labels this way helps&lt;br&gt;    to improve usability (think of screen readers for blind users).&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let coucou_form (enter_i, (enter_j, enter_s)) =&lt;br&gt;    let enter_i_label = "enter_i"&lt;br&gt;    and enter_j_label = "enter_j"&lt;br&gt;    and enter_s_label = "enter_s"&lt;br&gt;    in  [&lt;br&gt;        fieldset&lt;br&gt;            [&lt;br&gt;            label ~a:[a_for enter_i_label] [pcdata "Int i:"];&lt;br&gt;            Eliom_predefmod.Xhtml.int_input ~a:[a_id enter_i_label] ~input_type:`Text ~name:enter_i ();&lt;br&gt;            label ~a:[a_for enter_j_label] [pcdata "Float j:"];&lt;br&gt;            Eliom_predefmod.Xhtml.float_input ~a:[a_id enter_j_label] ~input_type:`Text ~name:enter_j ();&lt;br&gt;            label ~a:[a_for enter_s_label] [pcdata "String s:"];&lt;br&gt;            Eliom_predefmod.Xhtml.string_input ~a:[a_id enter_s_label] ~input_type:`Text ~name:enter_s ();&lt;br&gt;&lt;br&gt;            Eliom_predefmod.Xhtml.string_input ~input_type:`Submit ~value:"Click" ()&lt;br&gt;            ]&lt;br&gt;        ]&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "main" service simply displays the form that submits data&lt;br&gt;    to service "coucou".  Note that the actual form is created by&lt;br&gt;    the Eliom_predefmod.Xhtml.get_form function using the form&lt;br&gt;    creation function "coucou_form" previously defined.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let main_handler sp () () =&lt;br&gt;    let form = Eliom_predefmod.Xhtml.get_form coucou_service sp coucou_form&lt;br&gt;    in Lwt.return&lt;br&gt;        (html&lt;br&gt;            (head (title (pcdata "Main")) [])&lt;br&gt;            (body [p [pcdata "Form for coucou:"]; form]))&lt;br&gt;&lt;br&gt;&lt;br&gt;let main_service = &lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: [""]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        main_handler&lt;br&gt;&lt;/label&gt;&lt;/pre&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/03/19/ocsigen-by-example-part-5-get-forms.aspx#Comments</comments><guid isPermaLink="false">3ff2f500-df64-45ba-bed2-21bcdacac9f5</guid><pubDate>Thu, 19 Mar 2009 19:33:00 GMT</pubDate></item><item><title>Ocsigen by example, Part 4: suffix parameters</title><link>http://nleyten.com/2009/03/17/ocsigen-by-example-part-4-suffix-parameters.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;
&lt;p&gt; In the examples we've seen so far, GET parameters
were passed using the standard scheme (RFC 3986), ie,
an ampersand delimited list of key-value assignments.
As an alternative, Eliom offers also the possibility of
encoding parameters as slash-delimited suffixes to the
main URL.  For many applications this produces friendlier
and cleaner looking URLs. &lt;/p&gt;

&lt;p&gt; As an example, consider a service "foobar" taking
three integers as parameter: "year", "month", and "day".
In the standard scheme, the service could be invoked with
today's date by calling "foobar?year=2009&amp;amp;month=3&amp;amp;day=17".
Using the suffix scheme, the same invocation becomes
"foobar/2009/3/17".  You trade the flexibility of
specifying parameters by any order for the improved
legibility.&lt;/p&gt;

&lt;p&gt; The code sample below shows the definition of the
service "foobar" using suffix parameters.  Note that only
the declaration of the service needs to change; any links
towards this service created with Eliom_predefmod.Xhtml.a
will automatically reflect the new convention (yet another
reason to always use Eliom_predefmod.Xhtml.a!). &lt;/p&gt;

&lt;pre&gt;(************************************************************************)&lt;br&gt;(* Example for suffix parameters.                                       *)&lt;br&gt;(************************************************************************)&lt;br&gt;&lt;br&gt;open XHTML.M&lt;br&gt;open Eliom_parameters&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "foobar" service takes three GET parameters, all integers.&lt;br&gt;    It illustrates the use of Eliom_parameters.suffix to construct&lt;br&gt;    friendlier looking URLs.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let foobar_handler _ (year, (month, day)) () =&lt;br&gt;    let date = (string_of_int year) ^ "/" ^ (string_of_int month) ^ "/" ^ (string_of_int day)&lt;br&gt;    in Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Foobar")) [])&lt;br&gt;        (body [p [pcdata ("The date specified by the GET parameters is " ^ date)]]))&lt;br&gt;&lt;br&gt;&lt;br&gt;let foobar_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: ["foobar"]&lt;br&gt;        ~get_params: (Eliom_parameters.suffix&lt;br&gt;                    (Eliom_parameters.int "year" **&lt;br&gt;                    (Eliom_parameters.int "month" **&lt;br&gt;                    Eliom_parameters.int "day")))&lt;br&gt;        foobar_handler&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "main" service just provides a link to the "foobar" service.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let main_handler sp () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;            (head (title (pcdata "Main")) [])&lt;br&gt;            (body [p [Eliom_predefmod.Xhtml.a foobar_service sp [pcdata "Click for foobar"] (2009, (3, 17))]]))&lt;br&gt;&lt;br&gt;let main_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: [""]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        main_handler&lt;br&gt;&lt;/pre&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/03/17/ocsigen-by-example-part-4-suffix-parameters.aspx#Comments</comments><guid isPermaLink="false">7f2227a8-a2d1-435e-aa10-80be96e6c13f</guid><pubDate>Tue, 17 Mar 2009 17:52:00 GMT</pubDate></item><item><title>Ocsigen by example, Part 3: delayed service registration</title><link>http://nleyten.com/2009/03/15/ocsigen-by-example-part-3-delayed-service-registration.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;
&lt;p&gt; In the example from &lt;a href="http://nleyten.com/2009/03/13/ocsigen-by-example-part-2-hello-world.aspx"&gt;the
previous article&lt;/a&gt;, the various services are registered
with Eliom upon declaration.  Note that we used the
function Eliom_predefmod.Xhtml.register_new_service
for this purpose.  It is however also possible to
separate these two actions, by first just declaring a
service, and registering it later.  You may use function
Eliom_services.new_service for the former action, and function
Eliom_predefmod.Xhtml.register for the latter. &lt;/p&gt;

&lt;p&gt; Why is the separation between the declaration and
registration actions useful?  The most obvious application
lies in services that call each other.  Without this
feature, you would most likely would need to resort to a
"let rec ... and ..." construct, which isn't always the
most practical. &lt;/p&gt;

&lt;p&gt; The code below depicts two services, "coucou" and
"foobar", which call each other.  Note that we begin by
just declaring each service and that we only register them
in the end. &lt;/p&gt;

&lt;pre&gt;(************************************************************************)&lt;br&gt;(* Example for delayed registration.                                    *)&lt;br&gt;(************************************************************************)&lt;br&gt;&lt;br&gt;open XHTML.M&lt;br&gt;open Eliom_parameters&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  We begin by declaring services "coucou" and "foobar".  The first&lt;br&gt;    takes no parameters, while the second takes a float as a GET&lt;br&gt;    parameter.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let coucou_service =&lt;br&gt;    Eliom_services.new_service&lt;br&gt;        ~path: ["coucou"]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        ()&lt;br&gt;&lt;br&gt;let foobar_service =&lt;br&gt;    Eliom_services.new_service&lt;br&gt;        ~path: ["foobar"]&lt;br&gt;        ~get_params: (Eliom_parameters.float "x")&lt;br&gt;        ()&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  We now build the handler functions for each service.  Note how&lt;br&gt;    each handler creates a link to the other service.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let coucou_handler sp () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Coucou")) [])&lt;br&gt;        (body [p&lt;br&gt;            [&lt;br&gt;            pcdata "Here's a ";&lt;br&gt;            Eliom_predefmod.Xhtml.a foobar_service sp [pcdata "link"] 3.1416;&lt;br&gt;            pcdata " to service foobar";&lt;br&gt;            ]]))&lt;br&gt;&lt;br&gt;&lt;br&gt;let foobar_handler sp x () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Foobar")) [])&lt;br&gt;        (body [p&lt;br&gt;            [&lt;br&gt;            pcdata ("The parameter X is " ^ (string_of_float x));&lt;br&gt;            br ();&lt;br&gt;            pcdata "Here's a ";&lt;br&gt;            Eliom_predefmod.Xhtml.a coucou_service sp [pcdata "link"] ();&lt;br&gt;            pcdata " to service coucou";&lt;br&gt;            ]]))&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  Finally we register the declared services and assign to each&lt;br&gt;    one its handler function.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let () =&lt;br&gt;    Eliom_predefmod.Xhtml.register coucou_service coucou_handler;&lt;br&gt;    Eliom_predefmod.Xhtml.register foobar_service foobar_handler&lt;/pre&gt;

&lt;p&gt;&lt;b&gt;Postscriptum:&lt;/b&gt; If you're on the bleeding edge, you
may have noted that the ocsigen.conf file I presented &lt;a href="http://nleyten.com/2009/03/12/ocsigen-by-example-part-1-basic-setup.aspx"&gt;in
the first chapter of this series&lt;/a&gt; needs a tweak in order
to work with latest development version of Ocsigen (soon
to be version 1.2).  The change is minimal: basically,
the "hostname" attribute for the host configuration is
now called "defaulthostname".  Here's the revised file:

&lt;/p&gt;&lt;pre&gt;&amp;lt;ocsigen&amp;gt;&lt;br&gt;    &amp;lt;server&amp;gt;&lt;br&gt;        &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;&lt;br&gt;        &amp;lt;charset&amp;gt;utf-8&amp;lt;/charset&amp;gt;&lt;br&gt;        &amp;lt;mimefile&amp;gt;/etc/mime.types&amp;lt;/mimefile&amp;gt;&lt;br&gt;        &amp;lt;debugmode/&amp;gt;&lt;br&gt;        &amp;lt;findlib path="/home/dario/.local/lib/ocsigen/METAS"/&amp;gt;&lt;br&gt;        &amp;lt;findlib path="."/&amp;gt;&lt;br&gt;&lt;br&gt;        &amp;lt;extension findlib-package="ocsigen_ext.ocsipersist-sqlite"/&amp;gt;&lt;br&gt;        &amp;lt;extension findlib-package="ocsigen_ext.eliom"/&amp;gt;&lt;br&gt;        &amp;lt;extension findlib-package="ocsigen_ext.staticmod"/&amp;gt;&lt;br&gt;&lt;br&gt;        &amp;lt;host defaulthostname="localhost"&amp;gt;&lt;br&gt;            &amp;lt;site dir=""&amp;gt;&lt;br&gt;                &amp;lt;eliom findlib-package="module"/&amp;gt;&lt;br&gt;                &amp;lt;static dir="./"/&amp;gt;&lt;br&gt;            &amp;lt;/site&amp;gt;&lt;br&gt;        &amp;lt;/host&amp;gt;&lt;br&gt;    &amp;lt;/server&amp;gt;&lt;br&gt;&amp;lt;/ocsigen&amp;gt;&lt;/pre&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/03/15/ocsigen-by-example-part-3-delayed-service-registration.aspx#Comments</comments><guid isPermaLink="false">6762628e-f172-4d69-bcd7-9a82e01a4ec2</guid><pubDate>Sun, 15 Mar 2009 18:07:00 GMT</pubDate></item><item><title>Ocsigen by example, Part 2: hello world</title><link>http://nleyten.com/2009/03/13/ocsigen-by-example-part-2-hello-world.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; The second instalment of this
series presents the first actual Eliom
code sample.  You can use the Makefile shown in &lt;a href="http://nleyten.com/2009/03/12/ocsigen-by-example-part-1-basic-setup.aspx"&gt;the
first part&lt;/a&gt; to compile it, and the META.module
and ocsigen.conf files for starting the Ocsigen web
server. &lt;/p&gt;

&lt;p&gt; This example contains three different services:
first, the hello-worldish service "coucou" (so named
as a homage of sorts to the convention used in the &lt;a href="http://www.ocsigen.org/eliom"&gt;Eliom tutorial&lt;/a&gt;);
second, the "foobar" service, which illustrates the
use of GET parameters; and third, the "main" service,
which makes use of Eliom_predefmod.Xhtml.a to create type
safe hyperlinks to the first two services.  I suggest
you fiddle with the types of the GET parameters —
you'll see that Eliom makes good use of the type safety
of the Ocaml language by making it impossible to create
hyperlinks that pass the wrong type to a service. &lt;/p&gt;

&lt;pre&gt;(************************************************************************)&lt;br&gt;(* Simple "Hello World!" Eliom examples.                                *)&lt;br&gt;(************************************************************************)&lt;br&gt;&lt;br&gt;open XHTML.M&lt;br&gt;open Eliom_parameters&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "coucou" service takes no arguments, and just displays a&lt;br&gt;    welcome message with the client's IP address.  The IP can be&lt;br&gt;    obtained via the "sp" (server parameters) parameter that is&lt;br&gt;    passed to every handler.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let coucou_handler sp () () =&lt;br&gt;    let greeting = "Hello " ^ (Eliom_sessions.get_remote_ip sp) ^ "!"&lt;br&gt;    in Lwt.return&lt;br&gt;        (html&lt;br&gt;        (head (title (pcdata "Coucou")) [])&lt;br&gt;        (body [p [pcdata greeting]]))&lt;br&gt;&lt;br&gt;let coucou_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: ["coucou"]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        coucou_handler&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "foobar" service takes two GET parameters, an integer "i"&lt;br&gt;    and a string "s".  Note that the handler is declared as an&lt;br&gt;    anonymous function instead of as a separate function like we&lt;br&gt;    did with "coucou".  Though sometimes useful, this practice can&lt;br&gt;    lead to confusing code; for this reason, this is the only time&lt;br&gt;    we'll use it in this tutorial series.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let foobar_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: ["foobar"]&lt;br&gt;        ~get_params: (Eliom_parameters.int "i" ** Eliom_parameters.string "s")&lt;br&gt;        (fun _ (i, s) () -&amp;gt;&lt;br&gt;            Lwt.return&lt;br&gt;                (html&lt;br&gt;                (head (title (pcdata "Foobar")) [])&lt;br&gt;                (body [p [pcdata ("The GET parameters are: " ^ (string_of_int i) ^ " and " ^ s)]])))&lt;br&gt;&lt;br&gt;&lt;br&gt;(************************************************************************)&lt;br&gt;(*  The "main" service just provides links to both the "coucou" and&lt;br&gt;    "foobar" services.  Try changing the types of the parameters to&lt;br&gt;    see that the compiler catches any typing inconstencies.&lt;br&gt;*)&lt;br&gt;&lt;br&gt;let main_handler sp () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;            (head (title (pcdata "Main")) [])&lt;br&gt;            (body   [&lt;br&gt;                p   [&lt;br&gt;                    pcdata "Here's a ";&lt;br&gt;                    Eliom_predefmod.Xhtml.a coucou_service sp [pcdata "link"] ();&lt;br&gt;                    pcdata " to the coucou service"&lt;br&gt;                    ];&lt;br&gt;                p   [&lt;br&gt;                    pcdata "And here's a ";&lt;br&gt;                    Eliom_predefmod.Xhtml.a foobar_service sp [pcdata "link"] (10, "hello");&lt;br&gt;                    pcdata " to the foobar service"&lt;br&gt;                    ]&lt;br&gt;                ]))&lt;br&gt;&lt;br&gt;let main_service =&lt;br&gt;    Eliom_predefmod.Xhtml.register_new_service&lt;br&gt;        ~path: [""]&lt;br&gt;        ~get_params: Eliom_parameters.unit&lt;br&gt;        main_handler&lt;/pre&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/03/13/ocsigen-by-example-part-2-hello-world.aspx#Comments</comments><guid isPermaLink="false">5204a6c2-64f1-4192-98a9-d88e159112c7</guid><pubDate>Fri, 13 Mar 2009 18:17:00 GMT</pubDate></item><item><title>Ocsigen by example, Part 1: basic setup</title><link>http://nleyten.com/2009/03/12/ocsigen-by-example-part-1-basic-setup.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;
&lt;p&gt; This article is the first of a series I'll be doing on
&lt;a href="http://www.ocsigen.org/"&gt;Ocsigen&lt;/a&gt; programming.
Ocsigen is both a web server and the umbrella name for an
Ocaml-based framework that brings the power and safety of
functional programming to the world of web development.
Strictly speaking, this tutorial is about Eliom, the actual
programming framework part of Ocsigen.  However, because
the two are closely related, and because the name "Ocsigen"
has much better recognition, I've used it as a title. &lt;/p&gt;

&lt;p&gt; Note that the Ocsigen site already offers &lt;a href="http://www.ocsigen.org/eliom"&gt;a very comprehensive
tutorial&lt;/a&gt; on Eliom.  This series of articles is not
intended to compete with it.  In fact, I won't be doing any
tutoring at all and I'll assume that readers are familiar
with the existing tutorial.  The goal of this series
is simply to present self-contained and documented code
samples illustrating various aspects of Eliom programming.
These are taken from my own self-study experiments with
Eliom, and I'm only sharing them with the hope they might
be useful to others.  &lt;/p&gt;

&lt;p&gt;
Let's start with the development setup.  All the examples in
this series can be compiled with the same Makefile and
invoked with the same ocsigen.conf configuration file for
the server and META file with findlib information.  For the
sake of simplicity, you can put all of these files in the same
directory and just run the Ocsigen web server from that directory
in debug mode by invoking "ocsigen -v -c ocsigen.conf" for the
byte-code version or "ocsigen.opt -v -c ocsigen.conf" for the
native-code version (if you're running Ocaml &amp;gt;= 3.11).  The Makefile
is as follows:
&lt;/p&gt;

&lt;pre&gt;NAME=module&lt;br&gt;&lt;br&gt;all: $(NAME).cma $(NAME).cmxs&lt;br&gt;&lt;br&gt;%.cma: %.cmo&lt;br&gt;	ocamlc -a -o $@ $+&lt;br&gt;&lt;br&gt;%.cmxa: %.cmx&lt;br&gt;	ocamlopt -a -o $@ $+&lt;br&gt;&lt;br&gt;%.cmxs: %.cmxa&lt;br&gt;	ocamlopt -shared -linkall -I `pwd` -o $@ $&amp;lt;&lt;br&gt;&lt;br&gt;%.cmo: %.ml&lt;br&gt;	ocamlfind ocamlc -thread -package lwt,ocsigen -c $&amp;lt;&lt;br&gt;&lt;br&gt;%.cmx: %.ml&lt;br&gt;	ocamlfind ocamlopt -thread -package lwt,ocsigen -c $&amp;lt;&lt;br&gt;&lt;br&gt;clean:&lt;br&gt;	rm -f $(NAME).cm[ioax] $(NAME).cmx[as] $(NAME).[oa]&lt;br&gt;&lt;/pre&gt;

&lt;p&gt; As for the ocsigen.conf file, it can be defined like
the code below (just change the findlib path according
to your installation).  Note the we're using port 8080 so
the server can be started by any user: &lt;/p&gt;

&lt;pre&gt;&amp;lt;ocsigen&amp;gt;&lt;br&gt;    &amp;lt;server&amp;gt;&lt;br&gt;        &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;&lt;br&gt;        &amp;lt;charset&amp;gt;utf-8&amp;lt;/charset&amp;gt;&lt;br&gt;        &amp;lt;mimefile&amp;gt;/etc/mime.types&amp;lt;/mimefile&amp;gt;&lt;br&gt;        &amp;lt;debugmode/&amp;gt;&lt;br&gt;        &amp;lt;findlib path="/home/dario/.local/lib/ocsigen/METAS"/&amp;gt;&lt;br&gt;        &amp;lt;findlib path="."/&amp;gt;&lt;br&gt;&lt;br&gt;        &amp;lt;extension findlib-package="ocsigen_ext.ocsipersist-sqlite"/&amp;gt;&lt;br&gt;        &amp;lt;extension findlib-package="ocsigen_ext.eliom"/&amp;gt;&lt;br&gt;        &amp;lt;extension findlib-package="ocsigen_ext.staticmod"/&amp;gt;&lt;br&gt;&lt;br&gt;        &amp;lt;host hostname="dual"&amp;gt;&lt;br&gt;            &amp;lt;site dir=""&amp;gt;&lt;br&gt;                &amp;lt;eliom findlib-package="module"/&amp;gt;&lt;br&gt;                &amp;lt;static dir="./"/&amp;gt;&lt;br&gt;            &amp;lt;/site&amp;gt;&lt;br&gt;        &amp;lt;/host&amp;gt;&lt;br&gt;    &amp;lt;/server&amp;gt;&lt;br&gt;&amp;lt;/ocsigen&amp;gt;&lt;br&gt;&lt;/pre&gt;

&lt;p&gt; Finally, note that because we rely on findlib for the
installation of the module containing the actual code for
the web site, we must provide a META file indicating the
dependencies and the names of the compiled code units.
As per the ocsigen.conf declaration, the name of this file
must be META.module: &lt;/p&gt;

&lt;pre&gt;directory = "."&lt;br&gt;requires = ""&lt;br&gt;archive(plugin,byte) = "module.cma"&lt;br&gt;archive(plugin,native) = "module.cmxs"&lt;br&gt;&lt;/pre&gt;

&lt;p&gt; And that's it as far as the development setup is
concerned.  The next article will present the first real
example.  Stay tuned! &lt;/p&gt;
</description><category>ocaml</category><category>ocsigen</category><comments>http://nleyten.com/2009/03/12/ocsigen-by-example-part-1-basic-setup.aspx#Comments</comments><guid isPermaLink="false">d5dff42d-3efb-413e-a2b8-f552b47cb5f0</guid><pubDate>Thu, 12 Mar 2009 17:58:00 GMT</pubDate></item><item><title>Moglen on the origins of copyright and patents</title><link>http://nleyten.com/2009/01/30/moglen-on-the-origins-of-copyright-and-patents.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;
I mentioned Eben Moglen &lt;a href="http://nleyten.com/2006/10/14/proposition-3.aspx"&gt;before&lt;/a&gt; on this blog.
If you are still not familiar with any of his writings, I strongly suggest you listen
to &lt;a href="http://www.softwarefreedom.org/podcast/2009/jan/20/0x05/"&gt;this episode&lt;/a&gt;
of the &lt;a href="http://www.softwarefreedom.org/podcast/"&gt;Software Freedom Law Show&lt;/a&gt;
podcast.  It features a recording of one of Eben's recent talks on the origins of
copyright and patents.  It is well worth it, I promise.
&lt;/p&gt;
</description><category>patents</category><category>eben moglen</category><category>copyright</category><comments>http://nleyten.com/2009/01/30/moglen-on-the-origins-of-copyright-and-patents.aspx#Comments</comments><guid isPermaLink="false">35117539-0d91-454c-9575-7a52b06c9375</guid><pubDate>Fri, 30 Jan 2009 16:25:00 GMT</pubDate></item><item><title>A moment of Zen</title><link>http://nleyten.com/2008/12/22/a-moment-of-zen.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; I recommend a moment of Zen before breakfast.  Here's one for the
holidays: &lt;/p&gt;

&lt;p&gt; Consider the set &lt;i&gt;S&lt;/i&gt; of all possible files of length &lt;i&gt;n&lt;/i&gt;.  A
file compressor (such as &lt;a href="http://en.wikipedia.com/wiki/Gzip"&gt;Gzip&lt;/a&gt;,
&lt;a href="http://en.wikipedia.org/wiki/7-Zip"&gt;7-Zip&lt;/a&gt;, and many others) is
a programme that given any randomly chosen file from &lt;i&gt;S&lt;/i&gt;, returns a
new file whose size is on average &lt;b&gt;greater than or equal to&lt;/b&gt; &lt;i&gt;n&lt;/i&gt;.

&lt;/p&gt;&lt;p&gt; Meditate on the statement above until you realise its truth.  Then,
grasshopper, you shall be enlightened. &lt;/p&gt;

&lt;p&gt;&lt;i&gt;Note:&lt;/i&gt; The "equal to" part is necessary because there is an entire
family of compressors (the &lt;i&gt;identity&lt;/i&gt; compressor being the most
obvious one) that always return a file the same size as the one provided
as input. &lt;/p&gt;
</description><category>zen</category><category>breakfast</category><comments>http://nleyten.com/2008/12/22/a-moment-of-zen.aspx#Comments</comments><guid isPermaLink="false">071a36ba-46c4-4c85-8273-8ae9e9aaf473</guid><pubDate>Mon, 22 Dec 2008 17:24:00 GMT</pubDate></item><item><title>Introducing Camlhighlight</title><link>http://nleyten.com/2008/11/24/introducing-camlhighlight.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; &lt;a href="http://nleyten.com/2008/10/29/blah-blah-blah.aspx"&gt;Last time&lt;/a&gt;,
I told you about &lt;a href="http://blahcaml.forge.ocamlcore.org/"&gt;Blahcaml&lt;/a&gt;,
a library that wraps &lt;a href="http://gva.noekeon.org/blahtexml/"&gt;Blahtex&lt;/a&gt;,
thus providing facilities for converting equations in TeX format
into MathML.  The news is that in the meantime I've completed the
missing pieces in Blahcaml (namely proper error reporting), and &lt;a href="http://forge.ocamlcore.org/frs/download.php/96/blahcaml-1.2.tgz"&gt;released
version 1.2&lt;/a&gt;.  Functionality-wise, I consider the library "finished".
Please let me know if you find any glaring omissions or bugs.  &lt;/p&gt;

&lt;p&gt; Another feature I want for &lt;a href="http://forge.ocamlcore.org/projects/lambdoc/"&gt;Lambdoc&lt;/a&gt; is the
ability to display syntax-highlighted source code.  And so I spent some time
investigating the available options for highlighting source code within Ocaml.
Note that I wanted a generic highlighter, one that could handle most common
programming and markup languages.  Because there is no Ocaml library up
to the task, I looked at the C/C++ options and even at the possibility of
co-opting Vim for the task.  &lt;/p&gt;

&lt;p&gt; Using Vim is a seductive idea given the high-quality of Vim's
syntax-highlighting, but unfortunately flounders on Vim's manifest
unsuitability to be used inside scripts.  Yes, you can invoke Vim from the
command line with a sequence of commands, but I saw no way of camouflaging
the fact that Vim's interface still pops up, even if for a split-second.&lt;/p&gt;

&lt;p&gt; On the C/C++ side the options are &lt;a href="http://www.gnu.org/software/src-highlite/"&gt;GNU
Source-highlight&lt;/a&gt; and &lt;a href="http://www.andre-simon.de/doku/highlight/en/highlight.html"&gt;Highlight&lt;/a&gt;.
While both are command line applications, their core routines can easily be
extracted and made into a library.  Moreover, their licenses are friendly to
this operation.  The downside is that the quality of the highlight of either
application is not as good as Vim's, at least as far as highlighting Ocaml
is concerned.&lt;/p&gt;

&lt;p&gt; I've chosen &lt;a href="http://www.andre-simon.de/doku/highlight/en/highlight.html"&gt;Highlight&lt;/a&gt;
for the time being.  The wrapper library is called &lt;a href="http://camlhighlight.forge.ocamlcore.org/"&gt;Camlhighlight&lt;/a&gt; and is now
at version 0.5.  While there are still some features missing, it's already
quite usable.  The library has functions for generating an Ocsigen-friendly &lt;a href="http://www.ocsigen.org/docu/1.1.0/XHTML.M.html"&gt;XHTML.M&lt;/a&gt;
output, both in &lt;a href="http://camlhighlight.forge.ocamlcore.org/samples/fancy.html"&gt;fancy&lt;/a&gt;
and more &lt;a href="http://camlhighlight.forge.ocamlcore.org/samples/plain.html"&gt;plain&lt;/a&gt;
style (it's possible to customise whether or not one wants line numbers
and/or zebra stripes).&lt;/p&gt;
</description><category>lambdoc</category><category>ocaml</category><category>blahcaml</category><category>camlhighlight</category><comments>http://nleyten.com/2008/11/24/introducing-camlhighlight.aspx#Comments</comments><guid isPermaLink="false">fbef1e9c-81f6-47e5-94cd-d72c839c2da4</guid><pubDate>Mon, 24 Nov 2008 15:41:00 GMT</pubDate></item><item><title>Blah, blah, blah</title><link>http://nleyten.com/2008/10/29/blah-blah-blah.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;
&lt;p&gt; Lambdoc supports mathematical expressions in both TeX and MathML format.
The former was chosen because it is the &lt;i&gt;de facto&lt;/i&gt; standard for inputting
mathematics in a human-friendly manner (for slightly unconventional definitions
of both "human" and "friendly").  The latter because several graphical tools
for designing math expressions now have the capability of converting their
own internal (often proprietary) formats into MathML. &lt;/p&gt;

&lt;p&gt; Though browser support for MathML is still largely broken,
that will hopefully change with the imminent release of the &lt;a href="http://www.stixfonts.org/project.html"&gt;STIX fonts&lt;/a&gt;.  So rather than
doing a server-side rendering of all maths into images and serving those to
the client (the solution that Wikipedia currently uses), I have chosen to
take the plunge into the MathML world and serve that instead.  It follows
that I must somehow convert all those equations in TeX format into MathML. &lt;/p&gt;

&lt;p&gt; Now, I was hoping this task would be a no-brainer.
The tool that the Wikipedia itself currently uses is &lt;a href="http://en.wikipedia.org/wiki/Texvc"&gt;texvc&lt;/a&gt;, which is written —
drumroll — in Ocaml.  Unfortunately, texvc's forte is the conversion
of TeX into images, having only very minimal support for converting TeX into
MathML (it basically chokes on any expression more complex than "x = y").
I was therefore forced to look into alternatives. &lt;/p&gt;

&lt;p&gt; I ended up settling on &lt;a href="http://gva.noekeon.org/blahtexml/"&gt;Blahtex&lt;/a&gt;.  It is being developed
with the intention of being integrated into the Mediawiki package that
powers Wikipedia.  Moreover, besides the commonplace rendering of TeX
equations into images, Blahtex also aims at converting TeX into MathML, and
is already very competent at that task.  Unfortunately, and unline texvc,
Blahtex is developed in C++.  This is how I ended up spending some time
learning about the ways of interfacing C/C++ code with Ocaml. &lt;/p&gt;

&lt;p&gt; Ocaml has very good support for interfacing with C code (and
indirectly also with C++, since inside a C++ programme you can declare
functions to have C-style linking).  You can invoke C functions from
the Ocaml side, Ocaml functions from the C side, and mix and match as
per your requirements.  The authorative reference on this lore is the &lt;a href="http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html"&gt;Ocaml manual
itself&lt;/a&gt;, though I recommend that newcomers start with Florent Monnier's &lt;a href="http://www.linux-nantes.org/%7Efmonnier/OCaml/ocaml-wrapping-c.php"&gt;excellent
tutorial&lt;/a&gt;.  While not rocket science, the interfacing does require some
attention, particularly on matters where Ocaml's garbage collector is involved.
Moreover, when writing the C stubs we are constantly reminded that we have
left the safety of Ocaml shores and that we now find ourselves in "Here Be
Dragons" territory. &lt;/p&gt;

&lt;p&gt; Another issue that need handling was Blahtex's lack of any sanity checks
on its input.  Since web applications are the most obvious application of
a TeX to MathML converter, it worried me that a crafty user could pull a &lt;a href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;cross-site scripting
attack&lt;/a&gt; via a math expression.  To solve this issue I chose an approach that
though heavy-handed is simple to implement and offers beneficial side-effects:
the Ocaml side can ensure the sanity of the generated MathML by validating
it against the official &lt;a href="http://www.w3.org/TR/MathML2/"&gt;MathML2
DTD&lt;/a&gt; from the W3C.  During this process I discovered that the very capable
though complex &lt;a href="http://projects.camlcity.org/projects/pxp.html"&gt;PXP
library&lt;/a&gt; is the only Ocaml XML parser that can handle the complexity of
the MathML2 DTD. &lt;/p&gt;

&lt;p&gt; The end result is &lt;a href="http://blahcaml.forge.ocamlcore.org/"&gt;Blahcaml&lt;/a&gt;, a library that
offers basic bindings to Blahtex, but with added (optional) sanity checking.
I have just released version 1.0, and though it still hasn't been through
a lot of testing, it's performing nicely and can be considered stable.
Try it out and let me know if you find any problems! &lt;/p&gt;
</description><category>lambdoc</category><category>Blahcaml</category><category>ocaml</category><category>Blahtex</category><comments>http://nleyten.com/2008/10/29/blah-blah-blah.aspx#Comments</comments><guid isPermaLink="false">731792c6-10c8-4bd1-b94a-13717993b279</guid><pubDate>Wed, 29 Oct 2008 16:59:00 GMT</pubDate></item><item><title>Nleyten@1500,1600: Lambdoc takes shape</title><link>http://nleyten.com/2008/09/23/nleyten15001600-lambdoc-takes-shape.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; It's been a while since I've given an update on the
developments at my Subversion repository.  In the meantime the
revision log has passed the 1500 and 1600 mark, and a substantial
part of it has been moved to a public repository hosted at the &lt;a
href="http://forge.ocamlcore.org/"&gt;OcamlForge&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt; Revision 1500 reads "Added Sexplib (de)serialization functions for Lambdoc
documents" while 1600 reads "Added support for appendix sections".  Both of
these reflect where development has been taking place in the last few months:
I've been working on &lt;a href="http://lambdoc.forge.ocamlcore.org/"&gt;Lambdoc&lt;/a&gt;,
a library that adds support for semantic-rich documents within the &lt;a
href="http://www.ocsigen.org/"&gt;Ocsigen&lt;/a&gt; framework.  The centrepiece of this
library is Lambtex, a markup language inspired by LaTeX, but with simpler,
more consistent syntax and designed with web applications in mind.  I'm still
putting the finishing touches on Lambdoc, and I promise I'll make a much more
comprehensive description of the library once it is ready for prime-time. &lt;/p&gt;

&lt;p&gt; &lt;strong&gt;Postscriptum:&lt;/strong&gt; Concerning the ongoing financial meltdown,
a note to the friends who know me well: &lt;strong&gt;a)&lt;/strong&gt; yes, I do feel
a certain degree of schadenfreude and vindication: do you believe me now
when I say that capitalism is inherently flawed and that it will destroy
itself? &lt;strong&gt;b)&lt;/strong&gt; don't worry, because my potential smugness is more
than tempered by the realisation that we're all together on the same boat.
Unfortunately, us long time critics of capitalism don't live in a bubble
that protects us from its nefarious effects; &lt;strong&gt;c)&lt;/strong&gt; look at
the bright side: society now has a chance to finally move on unimpeded
by the dogma of liberal capitalism and faith in the "invisible hand";  if
nothing else, those Economist-following, Ayn Rand-worshipping crowds will
be a lot more silent &amp;mdash; that alone almost makes a financial collapse
bearable! &lt;strong&gt;d)&lt;/strong&gt; the crisis is far from over: I would pay
close attention to what will be happening to the dollar; &lt;strong&gt;e)&lt;/strong&gt;
These are indeed interesting times &amp;mdash; pass the popcorn! &lt;/p&gt;
</description><category>lambdoc</category><category>ocaml</category><category>Economy</category><category>lambtex</category><comments>http://nleyten.com/2008/09/23/nleyten15001600-lambdoc-takes-shape.aspx#Comments</comments><guid isPermaLink="false">a2179a9a-5b68-448c-a335-d7613bacaef1</guid><pubDate>Tue, 23 Sep 2008 20:48:00 GMT</pubDate></item><item><title>Use Ocaml, save the world</title><link>http://nleyten.com/2008/05/23/use-ocaml-save-the-world.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; &lt;i&gt;(Note: this post is written in a tongue-in-cheek
manner;  take it too seriously at your own peril).
&lt;/i&gt; &lt;/p&gt;

&lt;p&gt; Since this blog is syndicated in the Ocamlcore
Planet, readers may be wondering about the implications
for our favourite language of the coming energy crisis &lt;a href="http://nleyten.com/2008/05/23/peak-oil-revisited.aspx"&gt;I
just wrote about&lt;/a&gt;.  And in general, just how
well are different computer languages adapted to an
energy-constrained economy? &lt;/p&gt;

&lt;p&gt; There are two different factors to consider: a) how
efficient is the language at converting CPU cycles into
useful work, and b) how efficient is the language at
converting programmer time into useful programmes. &lt;/p&gt;

&lt;p&gt; The importance of the first factor should be
self-evident.  If not, note that computers consume
an increasing percentage of our energy, and that data
centres all over the world also require a significant
amount of power.  Moreover, there is a wide disparity
in the amount of time different languages require to
complete the same task.  This difference boils down to
different approaches to programme execution (compiled
languages tend to be more efficient than interpreted ones)
and the quality of the code generated by compilers.  The &lt;a href="http://shootout.alioth.debian.org/"&gt;Computer Language
Shootout&lt;/a&gt;, though not without its flaws, provides &lt;a href="http://shootout.alioth.debian.org/debian/benchmark.php?test=all&amp;amp;lang=all"&gt;some
ballpark figures&lt;/a&gt; on the efficiency of different
languages. As you can see, Ocaml fares very well on the
existing benchmarks. &lt;/p&gt;

&lt;p&gt; The second factor, though it may not be obvious at
first sight, may indeed be even more relevant to this
discussion.  Programmer time requires energy not only
to sustain the &lt;i&gt;Homo sapiens&lt;/i&gt; specimen that does
the programming, but also because programming is to a
large extent done in front of an energy-hungry computer.
Therefore, by making the programmer more productive,
a computer language can result in significant energy
savings. &lt;/p&gt;

&lt;p&gt; Measuring language productivity is a difficult
task.  Nevertheless, I would like to posit that the
availability of a strong static type checker such
as Ocaml's — one that catches most common
mistakes at compile-time — is a plus in this
regard.  Even more so if we consider runtime errors
as a loss of productivity.  Another good proxy for
language productivity is indicated by the terseness of
its programmes.  Again, the Computer Language Shootout &lt;a href="http://shootout.alioth.debian.org/debian/benchmark.php?test=all&amp;amp;lang=all&amp;amp;calc=Calculate&amp;amp;xfullcpu=0&amp;amp;xmem=0&amp;amp;xloc=1"&gt;may
be of assistance&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt; So, how well does Ocaml fare when these two
factors are taken into account?  Very well, I am pleased
to say.  In fact, using some reasonable parametrisation, &lt;a href="http://shootout.alioth.debian.org/debian/benchmark.php?test=all&amp;amp;lang=all&amp;amp;calc=Calculate&amp;amp;xfullcpu=1&amp;amp;xmem=0&amp;amp;xloc=5&amp;amp;binarytrees=1&amp;amp;chameneosredux=1&amp;amp;fannkuch=1&amp;amp;fasta=1&amp;amp;knucleotide=1&amp;amp;mandelbrot=1&amp;amp;nbody=1&amp;amp;nsieve=1&amp;amp;nsievebits=1&amp;amp;partialsums=1&amp;amp;pidigits=1&amp;amp;recursive=1&amp;amp;regexdna=1&amp;amp;revcomp=1&amp;amp;spectralnorm=1&amp;amp;hello=0&amp;amp;sumcol=1&amp;amp;threadring=1"&gt;the
results&lt;/a&gt; of the Shootout show Ocaml as the top rated
language.  We can therefore conclude that Ocaml will
also have a role to play in saving civilisation from an
energy crisis.  &lt;/p&gt;
</description><category>Energy Crisis</category><category>Peak Oil</category><category>ocaml</category><comments>http://nleyten.com/2008/05/23/use-ocaml-save-the-world.aspx#Comments</comments><guid isPermaLink="false">77aecf8b-220e-45c9-89cc-7e02168ac497</guid><pubDate>Fri, 23 May 2008 18:47:00 GMT</pubDate></item><item><title>Peak Oil revisited</title><link>http://nleyten.com/2008/05/23/peak-oil-revisited.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt; More than a year ago &lt;a
href="http://nleyten.com/2007/03/18/ohmygodwereallnotgonnadie.aspx"&gt;I
posted here my ramblings&lt;/a&gt; on the possibility of world
oil production being at, or close to, its peak.  At the
time, the topic of "Peak Oil" was still rather obscure,
and there were still many advocating that the world's
production capacity could continue to grow for decades
to come.  They were the ones saying that the price would
soon drop down to $20 or $30 a barrel.  Needless to say,
since then events have precipitated, and just last week
the price of oil jumped above the psychological barrier
(for computer scientists, anyway!) of $127 a barrel (127
being of course the largest integer quantity that can be
expressed with only 7 bits).  It seems like a perfect time
to revisit and update those predictions. &lt;/p&gt;

&lt;p&gt; On the whole, I have nothing to detract from what I
wrote 14 months ago.  I may have been overly optimistic
in some areas (more on that below) and events seem to be
happening faster than what I expected, but I still expect
the picture to remain more-or-less the same.  While I may
be now slightly less optimistic about our prospects for
the coming couple of decades, overall I still think that
the transition away from fossil fuels will occur without
the catastrophic collapse of civilisation presaged by
those with an inclination for doom. &lt;/p&gt;

&lt;p&gt; Note, however, that these are far from
being cornucopian predictions.  If reality
scares you, perhaps you should be visiting &lt;a
href="http://www.disney.com/"&gt;this site&lt;/a&gt; instead. &lt;/p&gt;

&lt;h2&gt;Is the peak real and happening now?&lt;/h2&gt;

&lt;p&gt; In other words, how can we be sure the rise in prices
reflects a real constraint on the production side instead
of just speculation and/or conscious throttling on the
part of exporting nations in order to drive up revenue?
Moreover, even if the constraints are real, couldn't
this just be a temporary situation caused by a past
underestimation of the current demand needs (bear in mind
the huge rise in demand in the past few years by China and
others), and that everything will be resolved as soon as
production catches up? &lt;/p&gt;

&lt;p&gt; Well, regardless of the actual numbers, we should
reflect anyway on the utter and complete absurdity of
having these crucial statistics about the wealth of the
world economy be dependent on whims and state secrets
of despotic regimes (Saudi Arabia, for one).  This is a
shortsightedness for which we could pay very dearly. &lt;/p&gt;

&lt;p&gt; In any case, what leads me to believe we are now on
the peak's "bumpy" plateau is the following: &lt;/p&gt;

&lt;ul&gt;

&lt;li&gt; Discoveries peaked in the 60s and despite all
technological advancements, have been declining ever since.
Recent discoveries (despite all the media attention they
get) are pathetic in comparison to the fields discovered
decades ago, and are typically made off-shore in very
deep waters (read expensive, dangerous, and desperate
locations).  This fact alone shows that oil production is
bound to peak sooner or later, though of course does not
prove it is actually occurring now. &lt;/li&gt;

&lt;li&gt; The number of countries past their peak keeps
increasing.  Three well-known recent examples are Mexico,
Norway and the United Kingdom.  The latter went in less
than a decade from being a major exporter to a net importer
of oil; as for Mexico, predictions are that in less than
ten years it will cease exports altogether (bad news
for the US, which imports a huge amount of oil from its
southern neighbour). &lt;/li&gt;

&lt;li&gt; The two big exporters, Saudi Arabia and Russia, seem
unable to increase their production.  Many argue they may
also be close to peaking. &lt;/li&gt;

&lt;li&gt; There are indeed a couple of &lt;a
href="http://en.wikipedia.org/wiki/Oil_megaprojects"&gt;oil
megaprojects&lt;/a&gt; coming online in the next couple
of years, but afterwards the situation seems dire.
We seem to be now in what has been called a &lt;a
href="http://www.theoildrum.com/node/2757"&gt;"Peak Lite"&lt;/a&gt;
scenario.  This means that even though the absolute peak
may not yet have been reached, the oil industry is starting
to show the symptoms of a post-peak situation.  Namely,
production is unable to keep up with demand, leading to
a significant increase in prices. &lt;/li&gt;

&lt;li&gt; Currently, world production sits &lt;a
href="http://europe.theoildrum.com/node/4018"&gt;at about 87
million barrels per day&lt;/a&gt;.  If you take into account the
new projects coming online, and the rates of depletion
in existing fields, it is possible that this number may
yet increase slightly within the next couple of years.
However, I very much doubt it will ever reach 90 mbpd.
Couple this with the ongoing increase in demand and the
Export Land Model (more on that below), and I would bet
against oil ever going below $100 a barrel (barring a
major global recession, of course). &lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;Aggravating circumstances&lt;/h2&gt;

&lt;ul&gt;

&lt;li&gt; I didn't factor in the so-called &lt;a
href="http://en.wikipedia.org/wiki/Export_Land_Model"&gt;"Export
Land Model" (ELM)&lt;/a&gt;, but in retrospect I should have.
In short, because the internal demand for oil in the
big exporting countries is increasing at a fast pace,
the amount of oil available for export decreases at
a much faster rate than what could be expected from
depletion alone.  This means that once past the peak, the
decline in oil available for export may be much steeper
than anticipated.  In other words, the transition away
from fossil fuels could feel more like shock therapy than
a smooth ride. &lt;/li&gt;

&lt;li&gt; Society is still by and large in denial.  Moreover,
most people (including politicians and journalists)
are completely clueless about basic principles of
thermodynamics and the orders of magnitude involved in
energy discussions.  To give you a concrete example that
illustrates most people's complete detachment from the
workings of the physical world, some weeks ago a leading
Portuguese news magazine published a vision of society
in 15 years time;  they talked of "cars running on wind
power", and showed a picture of a tiny wind turbine on
top of a futuristic-looking car!  It would almost be funny
if the consequences of this kind of thinking were not so
tragic. &lt;/li&gt;

&lt;li&gt; &lt;a href="http://en.wikipedia.org/wiki/EROEI"&gt;Energy
Return on Energy Invested (EROEI)&lt;/a&gt; is a problem
that goes beyond oil.   Not only do fossil fuels offer
relatively cheap and very dense energy, but you get a huge
return for each unit of energy you invest in extracting
them.  In the early days of the oil industry, when
extraction was as simple as digging a hole in the backyard,
EROEI was as high as 100:1.  Today, because drilling at
huge depths and off-shore is quite energy-intensive, the
EROEI for oil has decreased to 20:1 or 15:1.  And note
that for renewables and nuclear, the EROEI is even
much lower than that.  (As a side note, take heed that
scholars have pointed out that a decrease in EROEI was a
contributing factor in the decline of the Roman empire.
&lt;a href="http://bloggingheads.tv/diavlogs/11143"&gt;One of the
most interesting interviews&lt;/a&gt; I've listened to recently
addresses this issue: it features Thomas Homer-Dixon
discussing his latest book, "The Upside of Down"; I very
strongly recommend listening to it). &lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;Consequences for industry, commerce, and tourism&lt;/h2&gt;

&lt;p&gt; I won't repeat what I wrote last year.  I merely wish
to emphasise a few points that I find most relevant: &lt;/p&gt;

&lt;ul&gt;

&lt;li&gt; Locality will become much more important.
With transportation costs rising significantly, many
current assumptions will no longer be valid.  This will
have impacts on industry (suddenly it won't make as much
sense to produce cheap plastic toys in China), agriculture
(such as importing out-of-season fruit half-way across
the globe), and of course, tourism.  I think you can
find countless other examples where the assumption
that transportation costs are near zero have shaped our
economy. &lt;/li&gt;

&lt;li&gt; The airline industry as we know it is seriously
screwed.  Note however that "screwed" is not the same as
"doomed to extinction" like many are quick to predict.
Fares are still ludicrously cheap by historical standards,
and even if five years from now they are 3-4 times higher,
there will still be a sizable amount of air travel
going on.  Nevertheless, air travel will take a serious
hit from the effects of Peak Oil, and I reiterate that
current plans for expanding and building new airports will
look very foolish in less than ten years time.

&lt;p&gt; In addition, the travel industry will undoubtedly
adapt and many of its facets will look fairly different
in 10 or 15 years from now.  Part of the adaptations will
be purely technological (as an example, consider that &lt;a
href="http://en.wikipedia.org/wiki/Turboprop"&gt;turboprop&lt;/a&gt;
planes are more fuel efficient than jets), others will come
from purely a business choice (the "no frills" concept will
go away, because in a context of much higher fares due
to fuel costs, the cost of frills will be proportionally
tiny, thus giving an advantage to companies that do
provide them), and others may stem from a rethinking
of the very concept of travel.  Consider for example
the possibilities offered by the eventual return of the
airship (as in the "Hindenburg", hopefully minus the fire
and oh-the-humanity).  Presently, the "getting there" part
of air travelling consists of just the ordeal of having to
sit in a confined space for hours on end.  What if instead
the holiday trip were to start the moment you stepped on
a comfortable and spacious airship?  It wouldn't matter
so much if a trip took a couple of days instead of a few
hours. &lt;/p&gt;

&lt;/li&gt;

&lt;li&gt; I doubt that economy will fare well
during the first 5-10 years of the transition.
The scenario I find most likely is a return of the &lt;a
href="http://en.wikipedia.org/wiki/Stagflation"&gt;stagflation&lt;/a&gt;
that plagued the 1970s.  However, note that the economy
doing badly for an extended period of time is not the same
as catastrophic economic collapse.  Last time I checked,
there were no zombie hordes roaming the streets during the
1970s (though they would explain the whole &lt;em&gt;Disco&lt;/em&gt;
phenomenon). &lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;Winners and losers&lt;/h2&gt;

&lt;p&gt; In the grand scope of things we'll all be losers.
Even if somehow an energy-rich country were able to
isolate itself from the events on the rest of the world,
it would still lose simply because the misfortune of any
single country reflects the moral collective failure of
all humanity. &lt;/p&gt;

&lt;p&gt; With the above caveat in mind, some countries are
without a doubt better prepared than others to face
an energy crisis.  Here's my take on some noteworthy
examples: &lt;/p&gt;

&lt;ul&gt;

&lt;li&gt; I stick to my previous observation that China will
suffer serious growing pains.  I realise that the consensus
among many is that this will be "the century of China",
but I beg to differ.  On the short term, the rise in oil
prices will impact its status as the "world's factory"
(note that its export-based economy is dependent on the
assumption that transport costs are negligible).  On the
longer term, China faces a serious sustainability crisis.
The challenges of the energy crisis will combine with
the effects of climate change, soil erosion, and aquifer
depletion.  Bear in mind that this a country that needs
to feed 1.3 billion people. &lt;/li&gt;

&lt;li&gt; The picture for India is similar to that of China,
though India's environmental problems are not yet quite
as severe.  On the other hand, there is the further
complication that India's population time bomb is far from
being under control. &lt;/li&gt;

&lt;li&gt; Most of the developing world is in serious trouble.
Note, however, that the energy crisis is only one
small part of the problems faced: climate change,
environmental degradation, and &amp;mdash; the elephant in the
room &amp;mdash; overpopulation.  Many countries are indeed just
disasters waiting to happen (Haiti comes immediately to
mind; it's just one hurricane away from catastrophe).
Also, I wouldn't be surprised to see Somalia-style
collapses of individual states. &lt;/li&gt;

&lt;li&gt; Countries rich in resources and with fairly low
population densities are likely to fare relatively well.
Brazil and Canada come to mind.  Note, however, that I
would not include Australia in that list.  Though rich
in energy resources, Australia is bound to face problems
stemming mainly from the degradation of its very fragile
environment and the effects of climate change. &lt;/li&gt;

&lt;li&gt; Europe as a whole should fare relatively well,
though there are of course stark differences in the
degree of preparedness of different countries.  France,
thanks to its reliance on nuclear power, extensive train
network, and ongoing projects to build and expand tram
and light rail lines is an example to follow.  The United
Kingdom, on the other hand, will be a victim of years
of neglect in its public transit system (particularly
railways), and its electric power production capacity.
In short, problems stemming from what has been termed &lt;a
href="http://www.eurotrib.com/story/2008/4/7/23343/79841"&gt;"The
Anglo Disease"&lt;/a&gt;. &lt;/li&gt;

&lt;li&gt; As it currently stands, the United States is very
badly prepared for an energy crisis.  I would really,
really, like to think that Americans will soon wake up
and put their ingenuity to work.  They would embark
on a "Manhattan plan" for fuel alternatives, abandon
the suburbia experiment, and redesign their cities in a
public-transit and walk-friendly manner.  A friend of mine
likes to remind me of a quote by Churchill, who said that
"You can always count on Americans to do the right thing
&amp;mdash; after they've tried everything else".

&lt;p&gt; Unfortunately, recent history does not bode well for
the type of reaction we can expect from the US.  And note
that I'm not just referring to the invasion of Iraq
(is there still anyone who maintains the illusion that
its purpose was not to take control of the sizable Iraqi
reserves?).  No, that is simply a reflection of the path
Americans chose to take in the 1980 election.  Back then,
they were given the choice between a candidate aware of
the future energy crisis and who advocated some near-term
sacrifices to move their economy away from fossil fuels
(that candidate was Jimmy Carter), and a candidate who
instead told the Americans to screw conservation, that it
was "morning in America", and that it felt much better
to simply bury their heads in the sand and not to worry
about the future.  The latter candidate was Ronald Reagan,
who has you might recall won by a landslide victory.
(On a related note, it is disheartening to see Hillary
Clinton &amp;mdash; otherwise the most intellectually capable of
all three major candidates &amp;mdash; follow the short-sighted
and populist gimmick proposed by McCain of dropping the
gas tax for the holidays). &lt;/p&gt;

&lt;p&gt; Note, however, that I wouldn't be so quick to dismiss
the US entirely.  It's a huge country, rich in resources
(one can sometimes forget that even though it is well past
its peak, the US is still the third largest producer of
oil in the world), a major agricultural exporter, and with
a population density that is sufficiently low to make the
country sustainable in the long term. &lt;/p&gt;

&lt;p&gt; In a sense, the biggest challenges the US faces are a
crooked political system, and a blind faith on capitalism
and the invisible hand of the markets.  The biggest danger
for the US (and the rest of the world) is that the energy
crisis is successfully exploited by the usual ensemble
of populist and extremist politicians.  Despite this, I
reckon that Americans will eventually do the right thing
&amp;mdash; they've been trying everything else up till now,
after all. &lt;/p&gt;

&lt;p&gt; (A brief note on populism: the energy crisis we're
facing is in large part a consequence of past populist
and short-sighted policies; it is somewhat ironic and
definitely discouraging to note that the very same populism
that got us into trouble in the first place is the one that
typically profits the most from situations of crisis). &lt;/p&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;In the short term&lt;/h2&gt;

&lt;p&gt; Though there may be indeed a speculative component
to the current price and therefore some ease up won't be
surprising, I very much doubt oil ever again get below $100
(again, barring a major recession). &lt;/p&gt;

&lt;p&gt; OPEC will have their annual meeting in September.
If any, the increases in production announced will be small
and insufficient to meet the rise in demand.  A couple of
months later, the International Energy Agency (the watchdog
organisation over matters of energy) is scheduled to issue
a report concerning oil reserves.  I expect their current
rosy predictions that production could grow all the way to
2030 to be revised.  This is likely to be the moment that
"Peak Oil" and "Energy Crisis" enter the mainstream media.
Hopefully not to long afterwards, the true nature of the
problem &amp;mdash; that these are just aspects of a much broader
"Sustainability Crisis" &amp;mdash; will become the focus of
society's concerns. &lt;/p&gt;
</description><category>Peak Oil</category><category>sustainability</category><comments>http://nleyten.com/2008/05/23/peak-oil-revisited.aspx#Comments</comments><guid isPermaLink="false">33b718cc-ca76-427e-a405-918522a9aaa7</guid><pubDate>Fri, 23 May 2008 13:39:00 GMT</pubDate></item><item><title>Oh, the humanity!</title><link>http://nleyten.com/2008/04/24/oh-the-humanity.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;

&lt;a
href="http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#htoc37"&gt;Labelled&lt;/a&gt;
and &lt;a
href="http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#htoc38"&gt;optional&lt;/a&gt;
arguments, and &lt;a
href="http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html#htoc41"&gt;polymorphic
variants&lt;/a&gt; rank among Ocaml's most interesting features.
They can lead, however, to some pretty funky error
messages.  Here's one example:

&lt;/p&gt;

&lt;pre&gt;
File "main.ml", line 160, characters 38-44:
Error: This expression has type
         (unit, unit,
          [ `Attached of
              [ `Internal of ([&amp;lt; `Coservice | `Service ] as 'a) * [ `Get ] ]
              Eliom_services.a_s ],
          [&amp;lt; Eliom_services.suff ] as 'b, 'c, unit, [ `Registrable ])
         Eliom_services.service -&amp;gt;
         (Eliom_sessions.server_params -&amp;gt;
          ('d, Litiom_blocks.out_t) Litiom_blocks.t -&amp;gt;
          Eliom_predefmod.Xhtml.page Lwt.t) -&amp;gt;
         (unit, unit,
          [ `Attached of
              [ `Internal of [&amp;lt; `Coservice | `Service ] * [ `Get ] ]
              Eliom_services.a_s ],
          [&amp;lt; Eliom_services.suff ] as 'e, 'f, unit, [ `Registrable ])
         Eliom_services.service -&amp;gt;
         (Eliom_sessions.server_params -&amp;gt;
          ('g, Litiom_blocks.out_t) Litiom_blocks.t -&amp;gt;
          Eliom_predefmod.Xhtml.page Lwt.t) -&amp;gt;
         carry:unit -&amp;gt;
         Eliom_sessions.server_params -&amp;gt;
         (unit, int,
          [&amp;gt; `Attached of
               [&amp;gt; `Internal of [&amp;gt; `Coservice ] * [&amp;gt; `Post ] ]
               Eliom_services.a_s ],
          'e, 'f, [ `One of int ] Eliom_parameters.param_name,
          [&amp;gt; `Registrable ])
         Eliom_services.service
       but is here used with type
         (unit, unit,
          [ `Attached of [ `Internal of 'a * [ `Get ] ] Eliom_services.a_s ],
          'b, 'c, unit, [ `Registrable ])
         Eliom_services.service -&amp;gt;
         (Eliom_sessions.server_params -&amp;gt;
          ('d, Litiom_blocks.out_t) Litiom_blocks.t -&amp;gt;
          Eliom_predefmod.Xhtml.page Lwt.t) -&amp;gt;
         carry:unit -&amp;gt;
         Eliom_sessions.server_params -&amp;gt;
         (unit, 'h, [&amp;lt; Eliom_services.post_service_kind ],
          [&amp;lt; Eliom_services.suff ], 'i,
          [&amp;lt; int Eliom_parameters.setoneopt ] Eliom_parameters.param_name,
          [&amp;lt; Eliom_services.registrable ])
         Eliom_services.service
&lt;/pre&gt;

&lt;p&gt;

Obvious, isn't? &lt;img src="http://nleyten.com/emoticons/wink.png" border="0" /&gt;

&lt;/p&gt;
</description><category>ocaml</category><comments>http://nleyten.com/2008/04/24/oh-the-humanity.aspx#Comments</comments><guid isPermaLink="false">49078793-4168-4599-bf41-2435856bd7da</guid><pubDate>Thu, 24 Apr 2008 23:55:00 GMT</pubDate></item><item><title>Simple benchmarks on the Ocsigen server</title><link>http://nleyten.com/2008/04/21/simple-benchmarks-on-the-ocsigen-server.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;

I have looked for a web
framework shootout similar to the one that exists for &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;amp;lang=all&amp;amp;calc=Calculate&amp;amp;xfullcpu=1&amp;amp;xmem=0&amp;amp;xloc=1&amp;amp;binarytrees=1&amp;amp;chameneosredux=1&amp;amp;fannkuch=1&amp;amp;fasta=1&amp;amp;knucleotide=1&amp;amp;mandelbrot=1&amp;amp;meteor=1&amp;amp;nbody=1&amp;amp;nsieve=1&amp;amp;nsievebits=1&amp;amp;partialsums=1&amp;amp;pidigits=1&amp;amp;recursive=1&amp;amp;regexdna=1&amp;amp;revcomp=1&amp;amp;spectralnorm=1&amp;amp;hello=1&amp;amp;sumcol=1&amp;amp;threadring=0"&gt;computer
languages&lt;/a&gt;.  Sure, performance is hardly the deciding
factor when choosing a web framework, and benchmarks don't
say anything about features, robustness, and security.
Note, however, that the same can be said about programming
languages in general and that does not prevent people
from using the shootout in pissing contests.  I can, for
example, easily place Ocaml on top of that list just by &lt;a href="http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&amp;amp;lang=all&amp;amp;calc=Calculate&amp;amp;xfullcpu=1&amp;amp;xmem=0&amp;amp;xloc=4&amp;amp;binarytrees=1&amp;amp;chameneosredux=1&amp;amp;fannkuch=1&amp;amp;fasta=1&amp;amp;knucleotide=1&amp;amp;mandelbrot=1&amp;amp;meteor=1&amp;amp;nbody=1&amp;amp;nsieve=1&amp;amp;nsievebits=1&amp;amp;partialsums=1&amp;amp;pidigits=1&amp;amp;recursive=1&amp;amp;regexdna=1&amp;amp;revcomp=1&amp;amp;spectralnorm=1&amp;amp;hello=1&amp;amp;sumcol=1&amp;amp;threadring=0"&gt;
giving a larger weight to the gzip size of the
programme&lt;/a&gt; (a choice not altogether arbitrary: bear in
mind that gzip size is a good indicator of a language's
expressiveness; the smaller, typically the more expressive
a language is).

&lt;/p&gt;

&lt;p&gt;

Another important caveat to consider is that the bottleneck
for the typical web application lies on the database side,
not on the webserver.  In many cases, the webserver does
little more than to fetch and to do minimal processing on
the results provided by the database.

&lt;/p&gt;

&lt;p&gt;

Anyway, though I can't make comparisons between these
numbers and those from other frameworks using other
languages (who in their right mind would want to use
PHP?), it is nevertheless interesting to have an idea of
how well Ocsigen applications perform.  I am therefore
sharing the results of some simple tests I ran on two
different machines: an old Celeron running at 500 Mhz
(a very slow machine by today's standards), and a modern
Intel Pentium Dual E2160 running at 1.80 GHz.  Note that
architecture-wise, the former machine is an x86, while
the latter is an AMD64.

&lt;/p&gt;

&lt;p&gt;

All of the tests concern the generation of dynamic content
using Ocsigen's Eliom.  Though test 1 always produces
the same result and could therefore easily be cached, that
has not been done.  The idea was to test the most demanding
operation for a web application: the dynamic generation
of pages (typically personalised for individual users).
Also, there are two sets of results for each test; one
running Ocsigen in bytecode, and another using native code.
Note that because Ocsigen relies on dynlink, and Ocaml 3.10
does not support the dynamic linking of native code, I had
to use the Ocaml CVS HEAD for the tests.  Native dynlinking
will arrive with Ocaml 3.11 (coming this summer?).

&lt;/p&gt;

&lt;p&gt;

I used &lt;a href="http://www.joedog.org/JoeDog/Siege"&gt;Siege&lt;/a&gt; to
perform the actual benchmarking.  Each test was performed
with 10 concurrent client threads, and ran for 30 minutes.
Siege was executed on the same machine where the Ocsigen
server was located.  The results are presented in terms
of the number of transactions performed &lt;b&gt;per second&lt;/b&gt;.
The higher the better, of course.

&lt;/p&gt;

&lt;h2&gt;Test 1: simple page&lt;/h2&gt;

&lt;p&gt;

This service takes no parameters and simply outputs a page
with a "bench1" header.  This is the Eliom handler that
creates the page:

&lt;/p&gt;&lt;pre style="border: 1px solid black; padding: 0.5em; background: rgb(238, 238, 187) none repeat scroll 0% 50%; font-size: smaller; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;let bench1_handler sp () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;            (head (title (pcdata "bench1")) [])&lt;br&gt;            (body [h1 [pcdata "bench1"]]))&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;

And here are the results obtained:

&lt;/p&gt;

&lt;table&gt;
&lt;tbody&gt;&lt;tr align="left"&gt;
	&lt;th width="150"&gt;&lt;br&gt;&lt;/th&gt;
	&lt;th width="150"&gt;Celeron&lt;/th&gt;
	&lt;th width="150"&gt;Pentium Dual&lt;/th&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
	&lt;th&gt;Bytecode&lt;/th&gt;
	&lt;td&gt;110.41&lt;/td&gt;
	&lt;td&gt;590.49&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
	&lt;th&gt;Native&lt;/th&gt;
	&lt;td&gt;197.32&lt;/td&gt;
	&lt;td&gt;1461.10&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;h2&gt;Test 2: arithmetic on integer parameters&lt;/h2&gt;

&lt;p&gt;

This service takes two integers as a GET parameter, and outputs the
result of some common arithmetic functions performed on those
numbers:

&lt;/p&gt;&lt;pre style="border: 1px solid black; padding: 0.5em; background: rgb(238, 238, 187) none repeat scroll 0% 50%; font-size: smaller; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;let rec gcd a = function&lt;br&gt;    | 0 -&amp;gt; a&lt;br&gt;    | b -&amp;gt; gcd b (a mod b)&lt;br&gt;&lt;br&gt;&lt;br&gt;let lcm a b = (a * b) / (gcd a b)&lt;br&gt;&lt;br&gt;&lt;br&gt;let bench2_handler sp (a, b) () =&lt;br&gt;  Lwt.return&lt;br&gt;    (html&lt;br&gt;      (head (title (pcdata "bench2")) [])&lt;br&gt;        (body&lt;br&gt;          [&lt;br&gt;          h1 [pcdata "bench2:"];&lt;br&gt;          p [pcdata (Printf.sprintf "%d plus %d is %d" a b (a+b))];&lt;br&gt;          p [pcdata (Printf.sprintf "%d minus %d is %d" a b (a-b))];&lt;br&gt;          p [pcdata (Printf.sprintf "%d times %d is %d" a b (a*b))];&lt;br&gt;          p [pcdata (Printf.sprintf "%d divided by %d is %d" a b (a/b))];&lt;br&gt;          p [pcdata (Printf.sprintf "%d mod %d is %d" a b (a mod b))];&lt;br&gt;          p [pcdata (Printf.sprintf "The GCD of (%d,%d) is %d" a b (gcd a b))];&lt;br&gt;          p [pcdata (Printf.sprintf "The LCM of (%d,%d) is %d" a b (lcm a b))]&lt;br&gt;          ]))&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;

Note that the client had to request a page with two
GET parameters.  These were generated randomly with the
special shell variable $RANDOM, and stored in a urls.txt
file read by siege.  $RANDOM produces random integers
between 0 and 32767 (yes, I know there was a chance that
both "b" would be 0, causing an exception;  I checked
the urls.txt beforehand, making sure that didn't happen).
Anyway, here are the results obtained:

&lt;/p&gt;

&lt;table&gt;
&lt;tbody&gt;&lt;tr align="left"&gt;
	&lt;th width="150"&gt;&lt;br&gt;&lt;/th&gt;
	&lt;th width="150"&gt;Celeron&lt;/th&gt;
	&lt;th width="150"&gt;Pentium Dual&lt;/th&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
	&lt;th&gt;Bytecode&lt;/th&gt;
	&lt;td&gt;85.76&lt;/td&gt;
	&lt;td&gt;444.06&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
	&lt;th&gt;Native&lt;/th&gt;
	&lt;td&gt;172.39&lt;/td&gt;
	&lt;td&gt;1215.19&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;


&lt;h2&gt;Test 3: generate page with 100 pseudo-random paragraphs&lt;/h2&gt;

&lt;p&gt;

The final test is a bit more demanding.  It takes no parameters,
and outputs a page consisting of 100 paragraphs containing both
a deterministic and a random component:

&lt;/p&gt;&lt;pre style="border: 1px solid black; padding: 0.5em; background: rgb(238, 238, 187) none repeat scroll 0% 50%; font-size: smaller; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;let random_paragraph =&lt;br&gt;    let rng = Cryptokit.Random.device_rng "/dev/urandom"&lt;br&gt;    and to_hex = Cryptokit.Hexa.encode () in&lt;br&gt;    fun i -&amp;gt;&lt;br&gt;        let random_num = Cryptokit.Random.string rng 80 in&lt;br&gt;        let random_str = Cryptokit.transform_string to_hex random_num in&lt;br&gt;        p [pcdata (Printf.sprintf "This is paragraph %d: %s." i random_str)]&lt;br&gt;&lt;br&gt;&lt;br&gt;let bench3_handler sp () () =&lt;br&gt;    Lwt.return&lt;br&gt;        (html&lt;br&gt;            (head (title (pcdata "bench3")) [])&lt;br&gt;                (body&lt;br&gt;                    [&lt;br&gt;                    h1 [pcdata "bench3:"];&lt;br&gt;                    div (List.init 100 random_paragraph)&lt;br&gt;                    ]))&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;

Results obtained:

&lt;/p&gt;

&lt;table&gt;
&lt;tbody&gt;&lt;tr align="left"&gt;
	&lt;th width="150"&gt;&lt;br&gt;&lt;/th&gt;
	&lt;th width="150"&gt;Celeron&lt;/th&gt;
	&lt;th width="150"&gt;Pentium Dual&lt;/th&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
	&lt;th&gt;Bytecode&lt;/th&gt;
	&lt;td&gt;8.01&lt;/td&gt;
	&lt;td&gt;40.66&lt;/td&gt;
&lt;/tr&gt;
&lt;tr align="left"&gt;
	&lt;th&gt;Native&lt;/th&gt;
	&lt;td&gt;28.67&lt;/td&gt;
	&lt;td&gt;185.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;

First, there is a clear advantage to using native code
(no surprise there!).  Ocaml 3.11 will therefore be
very welcome for Ocsigen users.  Moreover, note that the
byte/native code difference is even more acute on the AMD64
architecture.  There is at the moment still some discussion
on whether or not the AMD64 port should use the "-dlcode"
compiler option by default (this option is necessary for
native dynlinking).  Hopefully further tests will come
to the conclusion that there is little or no performance
impact of using it.

&lt;/p&gt;

&lt;p&gt;

It would be interesting to investigate how other
languages/frameworks fare on similar tests.  Even more
interesting will be to repeat these tests on a more real
world scenario, with an actual application that accesses
a database, etc.  I intend to conduct these soon on
Lambdium-light.

&lt;/p&gt;
</description><category>ocaml</category><category>eliom</category><category>ocsigen</category><comments>http://nleyten.com/2008/04/21/simple-benchmarks-on-the-ocsigen-server.aspx#Comments</comments><guid isPermaLink="false">9eec0a69-f989-4241-8868-88174dfe2171</guid><pubDate>Mon, 21 Apr 2008 14:24:00 GMT</pubDate></item><item><title>Nleyten@1400: Netplexing</title><link>http://nleyten.com/2008/04/17/nleyten1400-netplexing.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;

The &lt;a href="http://projects.camlcity.org/projects/ocamlnet.html"&gt;Ocamlnet&lt;/a&gt;
set of libraries ranks among the many gems available
for Ocaml.  The blurb on the project's page describes it
this way:

&lt;/p&gt;

&lt;blockquote&gt;

Ocamlnet implements a number of Internet protocols (http
client &amp;amp; server, cgi and cgi variants, SunRPC, FTP,
POP, SMTP) and is a strong base for web and Internet
programming. Many protocols can even be driven in an
asychronous way, since Ocamlnet defines a framework for
asynchronous implementations (equeue). There is also a
generic server framework (netplex). There are a number of
accompanying data structures like mail messages, URLs,
buffers, channels, and also routines for character set
conversions.

&lt;/blockquote&gt;

&lt;p&gt;

Netplex is of particular interest for me at the moment.
It is basically a generic server framework, allowing one
to build full-fledged servers with very little effort.
If you've ever built a server from scratch, you will
know that while building a basic server is relatively
straightforward, things start to get complicated if you
intend to move from a simple toy into a production-quality
application.  Pretty soon you'll start having to worry
about keeping pools of slave workers, managing the
workload, and synchronising the entire apparatus.  Netplex
takes care of all of that stuff for you.  The end result
is that you get an efficient, secure, and fully-featured
server with just a few lines of code.

&lt;/p&gt;

&lt;p&gt;

I am using Netplex to build a "parsing server" (aka the
'Parserver').  It is basically a little daemon that sits
in the background providing a service that translates a
document formatted in one of the supported markups (like
Lambtex) into the native representation used by Lambdium.
Placing this service in an external, independent daemon
makes sense for a number of reasons:

&lt;/p&gt;

&lt;ol&gt;

&lt;li&gt;it makes the system more scalable, since we can
easily move the parsing server into its own machine(s)
if necessary.&lt;/li&gt;

&lt;li&gt;it makes the system more secure, since the parsing
daemon can run as 'nobody' as shield the rest of the
system from potential attacks based from the parsing
routines.&lt;/li&gt;

&lt;li&gt;Applications built using the Ocsigen
framework should be built using the &lt;a href="http://www.ocsigen.org/lwt"&gt;Lwt&lt;/a&gt; library for
cooperative threads (Lwt stands for 'Lightweight Threads').
At the present no parser-generator includes support for
Lwt.  It does make sense therefore to place the parsing
outside the main application.&lt;/li&gt;

&lt;/ol&gt;

&lt;p&gt;

As for SVN's 1400 revision log itself, it reads "Defined
the protocol for communication with Parserver".

&lt;/p&gt;
</description><category>ocaml</category><category>ocsigen</category><category>netplex</category><category>lwt</category><category>ocamlnet</category><comments>http://nleyten.com/2008/04/17/nleyten1400-netplexing.aspx#Comments</comments><guid isPermaLink="false">9252b1d1-0d21-468f-a151-4010fedb9bc4</guid><pubDate>Thu, 17 Apr 2008 16:28:00 GMT</pubDate></item><item><title>Ocsigen 1.0.0 released!</title><link>http://nleyten.com/2008/04/01/ocsigen-100-released-today.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;

&lt;a href="http://sympa.pps.jussieu.fr/wws/arc/ocsigen/2008-04/msg00000.html"&gt;
Vincent Balat announced today&lt;/a&gt; on the &lt;a href="http://www.ocsigen.org/"&gt;Ocsigen&lt;/a&gt; mailing-list
the release of version 1.0.0 of that of that web server +
web programming framework.  This is great news, as that
magical "1.0.0" will hopefully attract more users to this
exciting project.  Moreover, I can assure you this is a
rock solid release; in fact, it has been fairly mature
since the 0.6 days, and the 0.99.x series has been in out
and about for almost a year now.  (In case you haven't
noticed, this is the framework I have been using to develop
Lambdium and Lambdium-light).

&lt;/p&gt;

&lt;p&gt;

So, why should you care about Ocsigen?  Well, it offers
much more than a high-performance web server written in
Ocaml (though that's also cool).  Integrated with Ocsigen
comes Eliom, a web programming framework based on the
Ocaml language.  It brings the advantages of a safe,
functional, strongly-typed, and amazingly fast language
to web development.  Here are some of the highlights:

&lt;/p&gt;

&lt;ul&gt;

&lt;li&gt;&lt;b&gt;Static checking of XHTML:&lt;/b&gt; &lt;p&gt;Either using native
Ocaml or Ocamlduce, the type system makes sure at compile
time (no runtime penalties!) that the pages you generate
are valid XHTML.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Web sites consistent by construction:&lt;/b&gt; &lt;p&gt;Again
thanks to Ocaml's type system, there's just no way for
a website to include broken links, type mismatching of
form fields, wrong evaluation of page parameters, and
similar brittleness.  And again, all this is checked at
compile-time.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;One page, one function:&lt;/b&gt; &lt;p&gt;This not only helps to
ensure the modularity and conciseness of web sites, but
it is a more elegant solution to the consistency problem
than the templating offered by other frameworks.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Continuation-based web programming:&lt;/b&gt; &lt;p&gt;This is one
of those features that is a bit hard to explain, but whose
advantages are obvious once you actually start using it.
It does simplify tremendously the correct use of the "back"
button in browsers or "what if" scenarios when users open
multiple tabs from the same form.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Automatic handling of sessions:&lt;/b&gt; &lt;p&gt;Eliom takes
care of most of the low-level stuff, automatically taking
care of session management.  Moreover, it offers you
a wealth of possibilities, including the choice between
volatile or persistent sessions (even if the web server is
restarted!), public versus private sessions, etc.&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;b&gt;Amazing speed without sacrificing
expressiveness:&lt;/b&gt; &lt;p&gt;Ocaml is known to be a very
fast language, comparable to C++ in terms of speed.
Moreover, it is a very high-level language, with a
degree of expressiveness comparable to Python or Ruby.
Wouldn't you like to to have the best of both worlds?
Now you can.&lt;/p&gt;&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;

In short, Ocsigen brings web development from the
infant age into maturity.  So, if you are curious,
or just simply tired of dealing with the slowness
of Ruby on Rails or the epic brain damage that goes
by the name of PHP, I suggest you pay a visit to &lt;a href="http://www.ocsigen.org/"&gt;Ocsigen's site&lt;/a&gt; and
take a look at the tutorial.  The only prerequisite is
that you know the Ocaml language.  But it's well worth it.

&lt;/p&gt;
</description><category>ocaml</category><category>eliom</category><category>ocsigen</category><comments>http://nleyten.com/2008/04/01/ocsigen-100-released-today.aspx#Comments</comments><guid isPermaLink="false">b09ec46a-18c5-406f-8c6d-48007d60b593</guid><pubDate>Tue, 01 Apr 2008 16:46:00 GMT</pubDate></item><item><title>S-expressions for long-term storage of Ocaml values</title><link>http://nleyten.com/2008/03/10/sexpressions-for-longterm-storage-of-ocaml-values.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;

Call it marshalling, pickling, serialisation, or whatever
else you wish; this operation — where a value
(or "variable" in non-FP languages) is extracted from
a programme at runtime in order to be stored in disk or
transferred through the wire — is critical for many
applications.  Most programming languages therefore include
in their standard libraries some means of performing it.

&lt;/p&gt;

&lt;p&gt;

Ocaml ships with the venerable Marshal module.  It is
extremely simple to use:  suppose we wished to convert
into a string &lt;i&gt;str&lt;/i&gt; a marshalled representation of a
value &lt;i&gt;manuscript&lt;/i&gt; of type Manuscript.t.  This would
suffice: &lt;i&gt;let str = Marshal.to_string manuscript
[]&lt;/i&gt;.  The inverse operation — taking a string
with a marshalled representation and converting back
into a programme value — is also dead easy: &lt;i&gt;let
manuscript : Manuscript.t = Marshal.from_string str 0&lt;/i&gt;.

&lt;/p&gt;

&lt;p&gt;

The attent observer will have noticed the type annotation
in the unmarshalling example above; in general,
unmarshalling does require an explicit type annotation
(which otherwise is rarely needed in Ocaml).  The reason
is that the type inference mechanism may not have enough
information to determine what is the type of the marshalled
representation (imagine, for example, that the routines
performing the marshalling and unmarshalling reside in
different programmes!).   And here lies the Achilles'
heel of marshalling in Ocaml: should the programmer make
a mistake in specifying the type to be unmarshalled, the
programme will most surely segfault.  This problem also
occurs if a version of the programme stores a marshalled
value, which is then read back by a subsequent of the
same programme where the value's type has been modified
(even if ever so slightly).

&lt;/p&gt;

&lt;p&gt;

Over the years, there appeared a number of extensions
to the Ocaml language offering type-safe marshalling
(&lt;a href="http://www.cl.cam.ac.uk/%7Epes20/hashcaml/"&gt;
HashCaml&lt;/a&gt; may be the most well-known, but it's not
the only one).  And judging from comments by Xavier Leroy
(the primary developer of the Ocaml language) at the &lt;a href="http://wiki.cocan.org/events/europe/ocamlmeetingparis2008"&gt;Ocaml
users meeting&lt;/a&gt; in Paris this last January, there's a
good chance that type-safe marshalling will make it into
the core language in the near future.

&lt;/p&gt;

&lt;p&gt;

In Lambdium-light, stories and comments are stored in
the database backend using the marshalled representation
offered by the Marshal module.  While this works and is
extremely fast, it does have the problem of not being
very resilient to future changes in the story and comment
format.  Therefore, I have been looking at alternatives to
Marshal that provide some degree of backwards compatibility
while not sacrificing too much speed.

&lt;/p&gt;

&lt;p&gt;

I suspect that the XML-fanboys in the audience
wouldn't even think twice, but personally I am far
from finding XML a good solution for many of the
problem domains where it is applied.  For this reason, &lt;a href="http://caml.inria.fr/pub/ml-archives/caml-list/2008/02/440da478b5c5d51d1ea4132bf5792b19.en.html"&gt;I
asked about this&lt;/a&gt; problem in the Caml-list.

&lt;/p&gt;

&lt;p&gt;

Anyway, I am currently leaning
towards choosing a solution based on &lt;a href="http://www.ocaml.info/home/ocaml_sources.html#sexplib310"&gt;Sexplib&lt;/a&gt;,
a library that converts Ocaml values to/from &lt;a href="http://en.wikipedia.org/wiki/S-expression"&gt;S-expressions&lt;/a&gt;.
It comes with a syntax extension that given a type
&lt;i&gt;t&lt;/i&gt; automatically writes the &lt;i&gt;sexp_of_t&lt;/i&gt; and
&lt;i&gt;t_of_sexp&lt;/i&gt; "marshalling" functions.  Making the
transition from Marshal to Sexplib is therefore very
straightforward.  Another advantage is that S-expressions
are essentially just text and are therefore human-readable.
Moreover, the format is very compact (a lot more than
XML!) and fairly easy to parse.  Speed-wise, while
obviously not being as fast as Marshal, it is still
reasonably fast, especially in native code.

&lt;/p&gt;

&lt;p&gt;

Suppose I have a fairly large story of value
&lt;i&gt;Manuscript.t&lt;/i&gt;.  On my machine, and using Ocaml byte
code, marshalling and unmarshalling this value 100,000
times takes approximately 19.68 seconds.  Using Sexplib,
these operations take 1175 seconds, which is about 60
times slower.  However, the times in native code are
respectively 17.98 and 105.3 seconds — Sexplib is
less than 6 times slower than Marshal.  Given the other
advantages of Sexplib, these are numbers I can live with.

&lt;/p&gt;

&lt;p&gt;

If you are curious about how I got these numbers (and you
should — never take anyone's word at face value when
benchmarks are involved!), here follows the run-down of
the small programme I used for testing.

&lt;/p&gt;

&lt;p&gt;

&lt;i&gt;run_marshal&lt;/i&gt; is a function that given a manuscript,
does a marshalling followed by an unmarshalling using
the Marshal module.  &lt;i&gt;run_sexplib&lt;/i&gt; does the same
thing but using Sexplib.  Note that the latter function
actually first converts the &lt;i&gt;Manuscript.t&lt;/i&gt; into its
&lt;i&gt;Sexp.t&lt;/i&gt; representation and then this latter value
into a string (and vice-versa for the reverse operation):

&lt;/p&gt;

&lt;pre&gt;let run_marshal manuscript () =&lt;br&gt;        let marshalled = Marshal.to_string manuscript [] in&lt;br&gt;        let unmarshalled : Manuscript.t = Marshal.from_string marshalled 0 in&lt;br&gt;        ignore (unmarshalled)&lt;br&gt;&lt;br&gt;&lt;br&gt;let run_sexplib manuscript () =&lt;br&gt;        let manuscript_sexp_old = Manuscript.sexp_of_t manuscript in&lt;br&gt;        let mach_str = Sexplib.Sexp.to_string_mach manuscript_sexp_old in&lt;br&gt;        let manuscript_sexp_new = Sexplib.Sexp.of_string mach_str in&lt;br&gt;        let manuscript_new = Manuscript.t_of_sexp manuscript_sexp_new in&lt;br&gt;        ignore (manuscript_new)&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;

I also define a generic benchmarking function that
loops a provided function 100,000 times.  It uses
&lt;i&gt;Unix.gettimeofday&lt;/i&gt; to retrieve timing information:

&lt;/p&gt;

&lt;pre&gt;let benchmark test =&lt;br&gt;        let start = Unix.gettimeofday () in&lt;br&gt;        for i = 1 to 100000 do&lt;br&gt;                test ()&lt;br&gt;        done;&lt;br&gt;        let finish = Unix.gettimeofday () in&lt;br&gt;        let duration = finish -. start in&lt;br&gt;        duration&lt;br&gt;&lt;/pre&gt;

&lt;p&gt;

Finally, the main programme simply creates a new manuscript
(assume that function &lt;i&gt; get_manuscript&lt;/i&gt; returns a
new parsed manuscript) and calls the benchmark function
with the marshal and sexplib routines:

&lt;/p&gt;

&lt;pre&gt;let () =&lt;br&gt;        let manuscript = get_manuscript () in&lt;br&gt;        let duration_marshal = benchmark (run_marshal manuscript) in&lt;br&gt;        let duration_sexplib = benchmark (run_sexplib manuscript) in&lt;br&gt;        Printf.printf "Marshal: %f\n" duration_marshal;&lt;br&gt;        Printf.printf "Sexplib: %f\n" duration_sexplib&lt;br&gt;&lt;/pre&gt;
</description><comments>http://nleyten.com/2008/03/10/sexpressions-for-longterm-storage-of-ocaml-values.aspx#Comments</comments><guid isPermaLink="false">34990299-01e9-4596-b9a5-81d18250de95</guid><pubDate>Mon, 10 Mar 2008 16:21:00 GMT</pubDate></item><item><title>Nleyten@1300: the joy of parsing</title><link>http://nleyten.com/2008/02/26/nleyten1300-the-joy-of-parsing.aspx?ref=rss</link><dc:creator>Dario Teixeira</dc:creator><description>&lt;br&gt;

&lt;p&gt;

I know this is bound to brand me as
an incurable language geek, but I find &lt;a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree"&gt;
Abstract Syntax Trees&lt;/a&gt; a thing of extraordinary beauty.
Yeap, I am still immersed in the creation of the languages
and associated parsers for the markup of Lambdium stories
and comments.  And I'm finding that I'm really enjoying
all the stuff in this trade.

&lt;/p&gt;

&lt;p&gt;

I have now completed the definition and most of parsing
tools for the full-fledged Lambtex parser.  As it turned
out, introducing support for labelling and references
forced me to rethink some of the prior assumptions I
had for the Lambtex language.  It was a difficult birth
of sorts, and the language definition did go through
several revisions until it arrived in its present state.
I am now however quite pleased with the result: Lambtex
manages to be both simple and powerful, gracefully handling
most complex cases without burdening beginners with an
arcane syntax.  I will write a small manual (to be part
of Nleyten's help system) soon enough — you will
then get a clearer idea of what I mean.

&lt;/p&gt;

&lt;p&gt;

I also realise that I'm lucky enough to be able to be
creating both the language and the tools to parse it at
the same time.  The two play an intricate dance together,
and even minor changes to the syntax of a language can
have a profound effect on the parsing tools.  I am
also thankful to be doing this in Ocaml: the language
is just perfect for compiler writing!

&lt;/p&gt;

&lt;p&gt;

As for the SVN changelog at revision 1300, it reads
"Adapted tokenizer to new Lambtex scanner".  The Lambtex
parsing chain is composed of four separate modules
(as typical with most compilers): at the lowest
level there is a scanner that splits the input into
recognisable language atoms; closely tied to it there is
a tokenizer that converts those atoms into proper parser
tokens; then we have the parser proper (I am using &lt;a href="http://cristal.inria.fr/%7Efpottier/menhir/"&gt;Menhir&lt;/a&gt;
to generate the parser; it's similar to ocamlyacc, but
better); and at last there is a postprocessor that verifies
that the document is semantically correct (all references
point to valid targets, for example) and produces its
final version.

&lt;/p&gt;
</description><comments>http://nleyten.com/2008/02/26/nleyten1300-the-joy-of-parsing.aspx#Comments</comments><guid isPermaLink="false">4110d200-92cc-45f4-a360-ca072871d55b</guid><pubDate>Tue, 26 Feb 2008 14:59:00 GMT</pubDate></item></channel></rss>