Previous week Up Next week


Here is the latest Caml Weekly News, for the week of April 25 to May 9, 2006.

  1. Col: from records to CSV and vice-versa
  2. programmatic access to toplevel print facilities
  3. Type-safe marshalling for OCaml
  4. RSS-Software in OCaml?
  5. Ostap - yet another parser combinators library + BNF syntax extension
  6. Oddness with recursive polymorphic variants
  7. ocamlagrep anybody ?

Col: from records to CSV and vice-versa


Martin Jambon announced:
Col is a syntax library for the conversion between lists of records and 
CSV files with header. CSV (Comma-Separated Values) is a text format 
supported by spreadsheet programs. "records" are represented as OCaml 
records, tuples or objects, all being available and interconvertible.

   main URL:
   development/discussion wiki:

For a demonstration of what the syntax can do, see

Here is a short example which defines a list of 2 records and saves them:

(* File *)
type col t = { x : float;
                y : float;
                title "The Title" : string = "no title" }

let data =
   let x = 1. in
   [ T.create ~x ~y:2. ();
     T.create ~y:4. ~x ~title:"line2" () ]

let _ = T.save_csv "data.csv" data
(* end *)

$ ocamlfind ocamlopt -o testcol -syntax camlp4o -package col -linkpkg
$ ./testcol
$ cat data.csv
x,y,"The Title"
1.,2.,"no title"

This package is not well-documented but I have been using it intensively 
with and gnuplot, and it is stable. My largest record type 
has 49 fields and is still growing!

programmatic access to toplevel print facilities


Sam Steingold asked and Richard Jones answered:
> is there a way to access the top-level printing facilities from a program?
> e.g., ocaml toploop will print a complex structure nicely:
> # let x = make_my_huge_struct ();;
> val x : my_huge_struct =
> {a = 1; b = 2; c = 3; ...}
> how do I access this from a program?
> e.g., if I have an array of my_huge_struct, I want to be able to examine
> a part of it:
> let show_part arr p1 p2 =
>   for i = p1 to p2 do
>     ocaml_toploop_print (Array.get arr i)
>   done
> # show_part array_of_huge_structs 100 105;;
> (in lisp I would do
>  (loop :for i :from p1 :to p2 :do (print (aref array_of_huge_structs i))))

Have a look at this thread:

There's also a library around which allows you to access Toploop, but
I'm afraid my Google-fu is failing me today and I can't find it.
Lukasz Stafiniak also answered:
Recently announced (needs MetaOCaml):

Type-safe marshalling for OCaml


Peter Sewell announced:
We are pleased to announce a preliminary release of HashCaml, an
extension of the OCaml bytecode compiler with support for type-safe
marshalling and related naming features.

This makes the core type-safe and abstraction-safe marshalling
constructs from the Acute prototype language available within OCaml.
Some OCaml features are not supported (including marshalling of
polymorphic variants and objects), and this is very much an alpha
release - there may well be serious problems in the implementation.
Nonetheless, it should be usable for nontrivial experiments, and any
feedback and comment would be most welcome.

Further details, including a draft paper, the README, examples, and
the full distribution can be found at

for the HashCaml team: John Billings, Peter Sewell, Mark Shinwell, Rok Strnisa

RSS-Software in OCaml?


Oliver Bandel asked and Mikhail Gusarov answered:
> is there RSS-software writen in OCaml?
> Complete RSS-Reader or a Library for imlementing own clients?

There is jabber transport written in OCaml. You may ask
in conference for details.
Maxence Guesdon also answered:
You can have a look at ocaml-rss:
It reads and writes RSS 2.0. If you want to contribute, you're welcome.
Richard Jones also answered:
Pure OCaml software is always preferable, but just in case this
doesn't work out for you (want to support Atom?), then it is also
possible to use a Perl module such as Plagger (
via Perl4Caml (

Ostap - yet another parser combinators library + BNF syntax extension


Dmitri Boulytchev announced:
this is to announce yet another parser combinators library and camlp4 syntax
extension to embed parser expressions into plain OCaml code:

Oddness with recursive polymorphic variants


At the end of this thread, Jeremy Yallop said:
Thanks for all the replies.  My current understanding is as follows:

Given the types

    type f = [`A]
    type g = [f | `C]

then the following function is not acceptable

    let k (x:f) = (x:g)

because f and g are not unifiable: they are "closed rows" with different 
fields.  There are a number of ways to "open" the row, however:

    let k (#f as x:f) = (x:g)

This one is acceptable because the pattern "#f" means "an open row that 
includes all the tags in f".  (That's its type on the rhs, anyway.  The 
pattern (and the function) will accept exactly those tags in the type 
"f").  The type annotation on the parameter doesn't affect the type of 
"x", although the compiler does check that the type of the annotation 
and of the pattern can be unified.  The case where all the tags (only 
one in this case) are enumerated is treated identically:

    let k (`A as x:f) = (x:g)

Finally, the explicit coercion (:>).  Like the acceptable patterns, this 
"opens" the row, allowing it to be unified with "g" (or, indeed, with 
any other row type whose tag parameters don't clash with those of "f").

How does that sound?

ocamlagrep anybody ?


Ingo Bormuth asked and Xavier Leroy answered:
> ocamlagrep produces strange results in my hands:
>   let p =  Agrep.pattern "test" ;;
>   let s = "Hello test world." ;;
>   let l = String.length s ;;
>   Agrep.errors_substring_match p s ~numerrs:0 ~pos:0 ~len:l
>     ==> returns 0   ( as expected )
>   Agrep.errors_substring_match p s ~numerrs:3 ~pos:0 ~len:l
>     ==> returns 3   ( why ??? Should be 0 !!! )
> I tried many other combinations and do not get what's going on.

It's been a long time since I wrote this library, but AFAIK
Agrep stops at the first (approximate) match found.
So, in your example with numerrs=0 it scans s all the way to "test"
and reports success; and in your example with numerrs=3 it stops
at "Hell" (a 3-error match) and reports success.

In other terms, the integer returned by errors_substring_match
is not the minimal number of errors for a match over the whole text.
If that's what you want, you can obtain that number by repeated calls
to errors_substring_match using binary search on the value of numerrs.

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}$'?'<1':1

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