Previous week Up Next week

Hello

Here is the latest Caml Weekly News, for the week of March 18 to 25, 2008.

  1. NW Functional Programming Interest Group
  2. Lego Mindstorm Library v0.5
  3. camlp4 question: Mixing a printer and Ast.fold
  4. Long-term storage of values

NW Functional Programming Interest Group

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/e095762001b66bc6/8d3578a79e8fe439?lnk=gst

Greg Meredith announced:
A small cadre of us are organizing a Northwest Functional Programming
Interest Group (hey... NWFPIG, that's kinda funny). Our next
meeting is at the

The Seattle Public Library
1000 - 4th Ave.
Seattle, WA  98104 

from 18:30 - 20:00 on March 19th. 

On this meeting's agenda 
- i'll give a highly idiosyncratic talk about the Curry-Howard isomorphism
- followed an informal discussion section

Hope to see you there.
			

Lego Mindstorm Library v0.5

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/242200470cc3d566/c4162d0a59325e14#c4162d0a59325e14

Christophe TROESTLER announced:
It is my pleasure to announce the availability of the Lego Mindstorm library.

This library allows to communicate with the Lego Mindstorm NXT robotic
system via bluetooth.  All Lego commands are implemented.  It is
released under LGPL with the standard exception.  For more information
and the code, please go to the web site :

 http://ocaml-mindstorm.sourceforge.net/

There, you will also find two robots (maze escaper and Rubik's cube
solver) build by 3 students in mathematics of the University of
Mons-Hainaut.

Your reactions, comments, further developments,... are very welcome.
			

camlp4 question: Mixing a printer and Ast.fold

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/07064db65c25e246/a0090ccaf3429ff3#a0090ccaf3429ff3

After much debugging, Richard Jones announced:
This is the patch to make ocaml-gettext work against ocaml 3.10.X: 
http://www.annexia.org/tmp/ocaml-gettext-0.2.0-20080321.patch
			

Long-term storage of values

Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/2b4a8a9fbc70adf5/3724c25bed16dced

Continuing an old thread, Dario Teixeira said:
Some weeks ago I asked in the list about solutions for the long-term
storage of values in Ocaml.  I was looking for a solution that was
not quite as brittle as the Marshal module, while still maintaining
reasonable performance and being able to deal with Ocaml types in
all their glory (recursive structures, etc).

Thanks for all your replies -- I got plenty of ideas and found out
about new libraries I didn't know existed.  After some experimenting,
I settled for Sexplib; the main reason being the syntax extension that
automatically takes care of writing the (de)serialising functions.

However, if your requirements are different, you may find that another
solution might be more suitable.  Here's a brief summary of the main
options I looked into:  (let me know if there are others!)


- S-expressions using Sexplib.  It has the advantage of being
 quite fast, compact, and still human-readable-ish (if you like
 parentheses).  Moreover, the Camlp4 syntax extension makes the
 creation of (de)serialising functions as straightforward as
 appending "with sexp" to type definitions.

- Config_file.  A strong contender if proper human-readability
 is a requirement (it is far more readable than Sexplib, for
 example).  As far as I can tell, you still need to manually
 create the (de)serialising functions for complex types, though.
 Also, my guess is that the slightly more complex syntax will
 make it slower than Sexplib.

- JSON.  Possibly close to Config_file in terms of effort and
 speed.  Has the same advantage of being very human-friendly,
 and the additional advantage of having quickly become a popular
 interchange format (you'll find libraries for almost any language
 out there).

- XML.  Though Ocamlduce makes XML easier to deal with, the
 only advantage I see in XML is its ubiquity.  The format is
 verbose, not all that human-friendly, and you still need to
 manually create the (de)serialising functions.

- XDR.  Though I have fond memories of using XDR with C (in a
 different life), I have no experience with it in Ocaml.
 Though it should be very fast, you also need to manually
 create the (de)serialising functions.

- The I/O combinator library by Berke Durak.  Seems similar
 to XDR in terms of effort required.  Does it still not
 support recursive structures?  That is a common requirement.
			
Martin Jambon replied:
There's json-static for automatic marshalling:

 http://martin.jambon.free.fr/json-static.html
			
Dario Teixeira then asked and Martin Jambon replied:
> Thanks for your reply, Martin.  Looking at the examples, it seems that
> json-static is JSON-centric, in the sense that the type definitions for
> the automatic (de)serialisers are to be written in JSON.  Does it support
> the reverse, namely "here's an Ocaml type: please write Ocaml functions
> that (de)serialise into JSON"?

Dario,

No JSON needs to be written by hand.
Here's a simple example:

type json point = { x : int; y : int }  (* an OCaml record *)

It creates the functions with the following signature:

val json_of_point : point -> Json_type.t
val point_of_json : Json_type.t -> point

Json_type.t is the JSON syntax tree that you can serialize using Json_io.string_of_json.


# let j = json_of_point { x = 12; y = 34 };;
val j : Json_type.t =
 Json_type.Object [("x", Json_type.Int 12); ("y", Json_type.Int 34)]

# Json_io.string_of_json j;;
- : string = "{ \"x\": 12, \"y\": 34 }"
			
Later on, Martin Jambon added (erratum sent to the list already included):
I have to say that json-static does not support parametrized types other than
a few pervasive ones (lists, arrays, hash tables, options, ...).

Like the other syntax extensions that deal with types it uses the type names
to determine the JSON type to use, i.e. if 2 names are used to refer to the
same OCaml type, they can use 2 different JSON representations. A common,
predefined example is the "assoc" type, which is defined as follows:

type 'a assoc = (string * 'a) list

and would use a JSON object rather than a JSON array of arrays, which is
common usage.
			
Gerd Stolpmann also answered the original question:
>- XDR.  Though I have fond memories of using XDR with C (in a
> different life), I have no experience with it in Ocaml.
> Though it should be very fast, you also need to manually
> create the (de)serialising functions.

No, there is a generator for that in Ocamlnet. ocamlrpcgen can be used
to generate these functions.
			
Dario Teixeira then asked and Richard Jones answered:
> If I remember correctly, the model with XDR+rpcgen is that the data type
> is defined in a special XDR notation, which ocamlrpcgen will then use to
> generate the Ocaml type and the (de)serialisation functions.

That's right.  You write a '*.x' file and it gets converted to C by
rpcgen or to OCaml by ocamlrpcgen.  There's a very lengthy example I
wrote below.  XDR is regarded as a rather "old" protocol and support
is somewhat limited (basically, C, Java and OCaml).  On the other hand
it is well-understood and miles faster than anything else, since it's
a simple marshalling format just like OCaml's Marshal.

http://git.et.redhat.com/?p=libvirt.git;a=blob_plain;f=qemud/remote_protocol.x;hb=HEAD

> Though XDR
> offers a fairly rich type set, it's not quite as versatile as Ocaml's.
> I just wonder if this will lead to situations where one would rather
> write the (de)serialisation functions by hand instead of relying on
> the poorer expressiveness of the automatic generators.

The limited type set is an advantage if you're sharing data with other
languages (or if you're using C), but a disadvantage otherwise.

> Btw, do you have any numbers concerning XDR performance?  My guess
> is that this would be the fastest method after Marshalling.

There's a really tiny table at the end of this document, comparing it
to XML so not really any competition:

http://et.redhat.com/~rjones/secure_rpc/
			
David MENTRE then added:
> XDR is regarded as a rather "old" protocol and support
> is somewhat limited (basically, C, Java and OCaml).

And Python: http://thomas.enix.org/pub/pyrpc/ We used it to talk using
SUN's RPC (ONC RPC) to a server written in OCaml.

> On the other hand it is well-understood and miles faster than
> anything else, since it's a simple marshalling format just like
> OCaml's Marshal.

And the on-the-wire storage is much more efficient compared to say, XML,
with no issues like decimal-asci <-> binary conversions.
			
Gerd Stolpmann also answered Dario's question:
> If I remember correctly, the model with XDR+rpcgen is that the data type
> is defined in a special XDR notation, which ocamlrpcgen will then use to
> generate the Ocaml type and the (de)serialisation functions.  Though XDR
> offers a fairly rich type set, it's not quite as versatile as Ocaml's.

No, but it's ok. There are products, sums, sequences, and options. What
you cannot do is to marshal cyclic data - this is a limitation XDR
shares with most other external representations. There's also no notion
of objects.

> I just wonder if this will lead to situations where one would rather
> write the (de)serialisation functions by hand instead of relying on
> the poorer expressiveness of the automatic generators.

This may be an issue. Currently, ocamlrpcgen understands only a few
annotations that modify the O'Caml type the XDR type is mapped to. 

In the past months, I wrote Hydro, which is a library for another RPC
protocol called ICE. Hydro bases on my SunRPC efforts, and improves on a
number of its limitations. In Hydro, it is possible to annotate an ICE
type with an O'Caml function that converts it into a more pleasuring
representation. This allows to fix most shortcomings of the built-in
mapping to O'Caml types. Something similar could be done for XDR.

I wouldn't recommend Hydro for storing values, because its model is
OO-centric, and there is some impedance mismatch between the OO approach
and O'Caml's type system. Except you have cyclic values, because ICE can
represent that. (If you got curious: http://oss.wink.com)

> Btw, do you have any numbers concerning XDR performance?  My guess
> is that this would be the fastest method after Marshalling.

I don't have numbers. The O'Caml implementation is definitely slower
than the C code generated by rpcgen. However, the company I'm currently
working for uses this implementation for a high-performance cluster of
servers, and we never even thought about the XDR speed. It never
mattered.
			
Berke Durak also answered the original question:
I have been testing Sexplib for the last few weeks and I am very
satisfied with it.  The code is very high quality and the automatic
generation of converters (to and from S-expressions) is extremely
pleasant to work with.  It works very well with modules, functors
and polymorphic types.  Congratulations to Markus Mottl.
I certainly do not miss writing I/O combinators by hand for record
or sum types.

The use of uniform S-expressions has the considerable advantage of
simplicity.  You will never spend more than half an hour
writing a parser/printer for S-expressions in any language.

Simplicity and uniform representation are also very important for data
perennity.  The type is just

  type t = Atom of string | List of t list

Values of this type can very easily be processed in Ocaml.  This way,
you can migrate your old data quite easily by loading it, writing a few
recursive functions or using the Path module of Sexp, and then saving
it again.  For simple cases, you could even use sed, sgrep or even Scheme.

For instance, I have migrated twice a (small) user base for a personal
web site when I had to add some record fields or change one key from
ints to int lists to strings, and it works well.

We are also using it now for debugging output of complex types (ASTs,
class hierarchies, etc.) and the output is much more readable than what
you would usually crank by hand for debugging purposes.

Note however that Sexplib doesn't handle recursive data by default, but as
you can override printers/parsers for any type, you could easily use special
"references" thru which recursion could go and handle it manually.
As you all know, there is no good way in Ocaml for maintaining a physical
equality-based set.  (The IO combinator library doesn't either).

So I heavily recommend the use of Sexplib and its integration with
standardized Ocaml distributions.
			

Using folding to read the cwn in vim 6+

Here is a quick trick to help you read this CWN if you are viewing it using vim (version 6 or greater).

:set foldmethod=expr
:set foldexpr=getline(v:lnum)=~'^=\\{78}$'?'&lt;1':1
zM

If you know of a better way, please let me know.


Old cwn

If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.

If you also wish to receive it every week by mail, you may subscribe online.


Alan Schmitt