Previous week Up Next week

Hello

Here is the latest Caml Weekly News, for the week of July 14 to August 25, 2009.

  1. Manipulation objet files
  2. Burrows Wheeler Transform
  3. book "Le langage Caml"
  4. mlpost 0.7
  5. An OCaml Plugin for the NetBeans IDE
  6. naclgrid 0.1 (desktop grid engine) released
  7. Physical counterpart to Pervasives.compare?
  8. HOL Light on ocamlnat
  9. SynDEx v7 released
  10. Jane Street is hiring (as if you didn't already know)
  11. Storing UTF-8 in plain strings
  12. fancy tex for ocaml code
  13. Connecting to Mysql using Ocaml
  14. Conditional compilation
  15. ocaml for the Semantic Web
  16. Transition to OCaml 3.11.1 in Ubuntu Karmic Koala completed!
  17. lazy vs fun
  18. Other Caml News

Manipulation objet files

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/8e15b8257a5cb6181466270453c33884.en.html

Ed Keith asked and Alain Frisch answered:
> Before I reinvent the wheel I thought I'd ask is anyone knows of any
> libraries, that can be accessed from ocaml, to read and write object
> files. In particular I need to read and write ELF files, Windows PE
> files, the .obj files generated by Visual C++ (I think there are PE
> files, but am not sure yet) and the .o files generated by mingw (I think
> there are a.out files, but am not sure yet).

Visual C++ and gcc under Windows (Cygwin / MinGW) both produce COFF 
object files and static libraries (.obj/.lib, .o/.a), which can be 
linked to PE image files (.dll, .exe). Note that despite their suffix, 
objects and static libraries produced by gcc under Windows are regular 
COFF files.

flexdll contains a module to parse COFF objects and libraries and write
COFF objects (not libraries). The module has not been designed as a 
standalone library, just as a support module for flexdll (the same 
module is also used internally by LexiFi for our direct x86 COFF code 
generator for ocamlopt, which avoids the use of an external compiler), 
but it handles most of the COFF spec. There is also a minimal DLL writer 
in flexdll, but it is far from complete (e.g. it does not support 
embedding of Win32 resource files into the DLL).

http://alain.frisch.fr/flexdll.html
      

Burrows Wheeler Transform

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/87c383ad14e1b6ea145bb55e1607bdea.en.html

Jon Harrop announced:
I recently wrote an interesting blog post comparing the Burrows-Wheeler 
Transform written in OCaml and F#:

http://flyingfrogblog.blogspot.com/2009/07/ocaml-vs-f-burrows-wheeler.html

F# has a really handy "inline" feature that allows the programmer to have 
higher-order functions and their function arguments inlined and specialized 
to completely remove the performance overheads (i.e. polymorphism and closure 
invocation). Would be really nice if this were possible in OCaml too. Perhaps 
a batteries included macro is in order? :-)

Mauricio Fernandez was kind enough to optimize my simple fork-based 
parallelism into genuine shared memory parallelism, turning it into a real 
quicksort and producing much better performance (only 75% slower than F#):

http://www.reddit.com/r/programming/comments/920y4/ocaml_vs_f_burrows_wheeler_transform/c0b5u80

Matias Giovannini's minimal sorting networks can probably make it 
substantially faster still:

http://alaska-kamtchatka.blogspot.com/2008/08/family-portrait.html

I also wrote an article about QR decomposition that uses the same technique 
but the performance difference is much bigger because the functions being 
inlined are basic arithmetic ops:

http://flyingfrogblog.blogspot.com/2009/07/ocaml-vs-f-qr-decomposition.html
      

book "Le langage Caml"

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/fdbddd910ef0fbfcb1faa6afbb4c0382.en.html

Xavier Leroy announced:
A few months ago, there was a discussion on this list about
"Le langage Caml", an early book on Caml (Light) programming written
by Pierre Weis and I.  The book was out of print, but the publisher,
Dunod Éditions, graciously agreed to relinquish its rights and give
them back to the authors.

Pierre and I are therefore happy to announce that the full text of the
book (2nd edition) is now available freely:

    http://caml.inria.fr/pub/distrib/books/llc.pdf

There was a companion book, "Manuel de référence du langage Caml",
which is the French translation of the Caml Light 0.7 reference
manual.  For completeness, we also made it available:

   http://caml.inria.fr/pub/distrib/books/manuel-cl.pdf

Both texts are distributed under the Creative Commons BY-NC-SA
license.
      

mlpost 0.7

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/b2dfbb0409ca57a14a518a559c28a50c.en.html

Johannes Kanig announced:
We are pleased to announce version 0.7 of the mlpost tool. It can be
downloaded from the ocamlforge:

https://forge.ocamlcore.org/projects/mlpost/

or from its website:

http://mlpost.lri.fr/

See the Changelog:

http://mlpost.lri.fr/download/CHANGES

for new features and small changes; be aware, there are some
incompatible changes.
      

An OCaml Plugin for the NetBeans IDE

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/25f05f0cfb22d60a072d8d45b4b301a9.en.html

Pawel Boguszewski announced:
I am pleased to announce an OCaml extension for the NetBeans IDE.

This is first release of plugin so any comments and bug reports are welcome.

More information you can find on plugin home page: http://ocamlplugin.loki-a.com
      

naclgrid 0.1 (desktop grid engine) released

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/d565060d4cc6ea7ec97237c6a7e2a23b.en.html

William Le Ferrand announced:
I'm am very happy to announce the first release of naclgrid, a light desktop
grid engine written in jocaml and relying ocsigen.

Basically, it's a server where

++ you can upload tasks, tasks being shared libraries that follow some basic
rules. In particular tasks have two functions, one returning a list of
subtasks and another one that would gather the results. They also refer to a
worker for this specific task.

++ you can participate to queued tasks simply by browsing a webpage. When
you do so, you download an atomic task and a worker, which is a 'google
native client' binary. It's a standard C program compiled for the google
native client. Google native client is a plugin for your browser that
performs static analysis on your (native) library before running it in a
sandbox: thus you get both safety and close-to-native speed in a browser.
When the subtask is done another task is downloaded and so on ..

The package embeds two examples, one based on a knn and the other one being
some md5 distributed computation.

Compared to existing solution (Boinc ..), naclgrid does not require to
install a specialized rich client and provides strong safety features : the
worker can't compromise your system (according to google ..). Thus you get a
multi task and very flexible desktop grid.

I've build a website for this software : http://www.themipsfactory.com. There is a
demo video and of course the source code of naclgrid (its GPL v3). It's a
bit tricky to install as one has to build ocsigen with jocaml but it should
run fine. I'm writing documentation too. There is also a google group,
naclgrid-dev (http://groups.google.fr/group/naclgrid-dev), for all the
questions regarding the installation and for suggestions.

If you have any remarks, both on functionality and style, do not hesitate!
And if you know how I can package it in a better way, please tell me!
      

Physical counterpart to Pervasives.compare?

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/aeb1b438a176e0cb4a17973f06aff411.en.html

Elnatan Reisner asked and Alain Frisch replied:
> Is there something that can complete this analogy:
> (=) is to (==) as Pervasives.compare is to ___?
>
> That is, is there a polymorphic total ordering with respect to *physical*
> entities, rather than to their structure?

Not really. The physical location of heap values is not stable (because 
of the GC), so you cannot use it as a total ordering.

It may be useful to know that the generic structural comparison has a 
physical behavior for OCaml objects (it compares their unique ids). So 
wrapping your values inside objects can be a good trick to get physical 
comparison (and hashing), as in:

class ['a] physical_reference init = object
   val mutable current : 'a = init
   method get = current
   method set x = current <- x
end
      
Edgar Friendly also replied and Pascal Cuoq said:
> No, but it'd be pretty trivial to implement through the C interface.

No, it would not be trivial to implement, because you would not want the
order of two values to change each time one is moved from the minor heap
to the major heap or when the major heap is compacted.
The article linked below is about this kind of topic (among other
things), in the context of Haskell.

http://research.microsoft.com/en-us/um/people/simonpj/papers/weak.htm

The simple solution is to number at creation the objects that you want  
to
physically compare, using an additional field.

> If you had to stay in the OCaml realm, you might be able to do [let
> phys_comp (x:'a) (y:'a) = (Obj.magic x) - (Obj.magic y)], but it  
> depends
> on the exact implementation of (-) on your architecture, as it may
> produce a value that's not an OCaml int when given non-ints as input.

As an additional general remark, it is a bad idea to use "x - y"
as an implementation of "compare x y" because of overflows.
      
Jean-Christophe Filliâtre then suggested:
> The simple solution is to number at creation the objects that you want to
> physically compare, using an additional field.

You can do that while hash-consing your values, which has many other
benefits than allowing physical comparison, as explained in this paper:

  http://www.lri.fr/~filliatr/ftp/publis/hash-consing2.pdf

Ocaml code for hash-consing can be found on that page:

  http://www.lri.fr/~filliatr/software.en.html
      

HOL Light on ocamlnat

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/07/befdf134aca7b5a6f6766d23d2570e17.en.html

Kevin Cheung announced:
I am pleased to announce that experiments
on loading HOL Light in ocamlnat have
been successful.  A 4x to 10x speedup on
various computations has been observed.

A preliminary how-to guide is available at:
http://www.math.carleton.ca/~kcheung/holnat.html
      

SynDEx v7 released

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/c685a90891edb6e1a9553f5cc8a0dc30.en.html

Cécile Stentzel announced:
We are happy to announce the release of the v7 version of SynDEx.

SynDEx is a system level CAD software written in OCaml for rapid prototyping and 
optimizing the implementation of distributed real-time embedded applications 
onto multicomponent architectures.

This release includes new features:
- multi-periodic applications,
- adequation based on multi-periodic distributed real-time scheduling analyses,
- verification of dependence cycle in the algorithm graph,
- a new Graphical User Interface for algorithm specifications,
   - a single window grouping all the definition operations,
   - abstract reference,
   - superblock,
   - undo.

SynDEx v7 can be downloaded from the SynDEx web site http://www.syndex.org
      

Jane Street is hiring (as if you didn't already know)

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/5e710e9b2057adbe4ede5c92c3cdc243.en.html

Yaron Minsky announced:
This is my periodic reminder to the FP world that Jane Street is
looking to hire functional programmers.  I've started getting the
occasional inquiry coming in from people who are clearly unsure if our
previous hiring announcements still apply, and I wanted to make it
clear that they do.  So, at the risk of boring longtime residents of
the list to tears:

Despite the problems besetting much of the financial industry, we have
grown strongly in the last few years in our people, our technology,
the scope of our business and its profitability.  We now have over 30
OCaml developers, and we are actively looking to hire more in Tokyo,
London and New York.

For someone who cares about functional programming, Jane Street is an
interesting place to consider.  Jane Street has invested deeply in
OCaml, to the point where we now have the largest team of OCaml
programmers in any industrial setting, and probably the world's
largest OCaml codebase--over a million lines.  We really believe in
functional programming, and use OCaml for everything from research to
systems adminstration to trading systems.

The atmosphere is informal and intellectual, with a focus on learning.
The work itself is deeply challenging, and you get to see the
practical impact of your efforts in quick and dramatic terms.  Jane
Street is also a small enough place that people have the freedom to
get involved in many different areas of the business.

Unlike many financial firms, software and technology are considered a
core part of what we do, not some segmented-off cost center that the
people who run the business don't think about.  Jane Street is a place
where people really care about the quality of the software, to the
point that several of the most senior members of the firm, who do not
have technology backgrounds, nonetheless review critical portions of
the codebase before they can go into production.

If you'd like to learn more, here are some links.  First, there are a
couple of papers we've written about our experiences here.

   http://www.janestreet.com/technology/articles.php

We also have a technically-oriented blog:

  http://ocaml.janestreet.com

For a (recruiting-oriented) overview of Jane Street, here's the firm
website:

  http://janestreet.com

If you're interested, send me a resume and cover letter.
      
Yaron Minsky later added:
And by-the-by, I will be at parts of ICFP, CUFP and DEFUN this year, so
if you're interested in hearing more about Jane Street, you should come
by and chat.
      
Romain Beauxis asked and Yaron Minsky replied:
> Since you wrote a long mail presenting your activity, it would also be nice
> to
> present what you actually *do* with ocaml in this presentation. I guess
> when
> one seeks for a job, he might also care about this aspect, in particular in
> the financial world.

I think the text above does hint at the range of things we work on in OCaml,
but if you want to get a better feel, there are a couple of good sources:
first, there's an article that Stephen Weeks and I wrote for JFP, which you
can find here:

   http://janestreet.com/technology/articles.php

Also, there's video of a talk I gave at CMU:

  http://ocaml.janestreet.com/?q=node/61

It's hard to be too precise in a short missive about the kind of things we
do in OCaml, because our use is so diverse.  One of the things that I think
speaks well for OCaml is that we have found it to be highly effective for so
many different kinds of things --- whether we're writing admin tools or
research codes or automated trading systems, it is our tool of choice.
      

Storing UTF-8 in plain strings

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/285aa2b18d99695127c68b033b22d334.en.html

Dario Teixeira asked:
I'm using Ulex + Menhir to parse UTF-8 encoded source code, and I'm relying
on plain strings for processing and storing data.  I *think* I can get away
with using only the String module to handle this variable-length encoding
as long as I am careful with the way I treat these strings.  Here are the
assumptions I am making:

- If the source is invalid UTF-8 in any way, Ulex will raise Utf8.MalFormed.
  I can therefore assume in subsequent steps that the source is compliant.

- It is forbidden to use String.get, String.sub, String.length, or other
  functions where awareness of variable-length encoding is required.

- String concatenation is allowed.

- Using Extlib's String.nsplit is okay if the separator is a newline (0x0a),
  because in a multi-byte sequence all bytes have a value > 127.  There is
  therefore no chance of splitting a multi-byte sequence down the middle.


So, can someone find any problems with this reasoning?  (Thanks in advance!)

Best regards,
Dario Teixeira

P.S. And yes, I am aware that there are excellent libraries for handling
     UTF-8 (like the Rope module in Batteries).
      
Michael Ekstrand replied:
It looks good to me.  Further, much of the functionality you're
forbidding yourself in String is provided by Extlib's UTF8 module
without additional dependencies if you do need it at some place in your
program.

You can also go ahead and use buffers, sprintf, etc., so long as
everything is valid UTF-8.  They won't care; they'll only see a sequence
of bytes.
      
Jake Donham suggested:
The original poster might be interested in the Netconversion module
from Ocamlnet, which is designed to work with UTF-8 stored in OCaml
strings. In particular it has a function

  Netconversion.verify `Enc_utf8 s

which checks that s is a valid UTF-8 string. It also has equivalents
for String.{get,sub,length}.
      
Florian Hars also replied:
> So, can someone find any problems with this reasoning?

No, the kind of compatibility with legacy code you described is
one of the original design goals of UTF-8, see
http://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt
      

fancy tex for ocaml code

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/564c6ead549c35ee724a1552f20b7656.en.html

Tumenjargal Tsagaan asked, Pierre-Evariste Dagand replied, and Michaël Grünewald added:
> > I was wondering if someone is aware of a tool for ocaml like this at
> > http://people.cs.uu.nl/andres/lhs2tex/ which generates a fancy tex code 
> > from haskell-code.
> 
> Ocamlweb is what you are looking for:
> [http://www.lri.fr/~filliatr/ocamlweb/]. It's an excellent tool.

I really second your voice saying that ocamlweb gives very enjoyable 
results.

> Also, for any language, noweb [http://www.cs.tufts.edu/~nr/noweb/] 
> always works.

NOWEB will not produce a `fancy output' for a given language without 
special support for this language. BTW it is an excellent tool for 
literate programming.
      

Connecting to Mysql using Ocaml

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/15e537bb578bf969d6aecc54150919b1.en.html

Tumenjargal Tsagaan asked and Christophe Troestler replied:
> has someone with experience tell me how to access mysql database
> using ocaml?  Any help would be appreciated.

Google is your friend: for "mysql ocaml" it reports as its first page
http://raevnos.pennmush.org/code/ocaml-mysql/

> It would be great when posting a small snippet for connecting a
> mysql database and inserting something.

You will hopefully be fully satisfied that there is a demo in the
tarball then!
      
Dave Benjamin also replied:
See the second half of this example (dbusers):
http://pleac.sourceforge.net/pleac_ocaml/dbaccess.html#AEN784

You can get the MySQL bindings here:
http://raevnos.pennmush.org/code/ocaml-mysql/

Or, if you're using Debian or Fedora, there should be a package available.
      

Conditional compilation

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/e5f7062556e893f01b316d368fb96c71.en.html

Edgar Friendly asked:
I'm working on a project that has significant build infrastructure using
autoconf, make and ocamlbuild.  I want to have a reasonably simple
trigger, such as a command-line argument to autoconf.  The result of
activating this trigger would be to drastically reduce what gets
compiled -- many files wouldn't need to be compiled, and many sections
of files should be commented out.

The project already uses optcomp for some conditional compilation based
on ocaml version.  I've learned that optcomp creates a new camlp4
command-line flag, [-let], which accepts a "var=value" pair and sets
that for use in [#if var = value] triggers.  I've also dug into
ocamlbuild and found a way to set this flag within the [-pp] argument to
ocamlc.  I've hit some hurdles, and wonder how to overcome them:

1) optcomp is sometimes used as a standalone camlp4 executable (-pp
'build/optcomp/optcomp_o.byte') - in this mode, it seems to accept only
the name of a file as input, and doesn't take the [-let] argument.  What
is the difference between this and "-pp 'camlp4oof
build/optcomp/pa_optcomp.cmo'"?

2) I'm using the identifier "AAA" for my trigger, and I can use
ocamlbuild's tags system to set "-let AAA=true" when the tag "AAA" is
set - is there any way to do "-let AAA=false" when tag "AAA" is unset?
Optcomp gives a compilation error on bound identifiers, so I have to set
it in both cases.

Is there a better way to do this?  The path I'm following is looking
very byzantine compared to C's [-DFOO] + [#ifdef FOO].
      
Andre Nathan suggested:
In ospec I use

  -pp "camlp4o Camlp4MacroParser.cmo -D FOO"

which can then be tested in the code with

IFDEF FOO THEN
  ...
END
      
Richard Jones also suggested:
You can just use autoconf's ordinary features:

eg:

  AC_ARG_ENABLE([foo],
          [AS_HELP_STRING([--enable-foo],
            [enable foo @<:@default=no@:>@])],
          [],
          [enable_foo=no])
  
  # Define an automake conditional:
  AM_CONDITIONAL([FOO],[test "x$enable_foo" = "xyes"])
  
  # Define an autoconf substitution:
  if test "x$enable_foo" = "xyes"; then
    FOO=1
  else
    FOO=0
  fi
  AC_SUBST(FOO)

And then in Makefile.am you can use:

  ifdef FOO
  FLAGS = -DFOO=1
  else
  FLAGS =
  endif

and in any autoconf-substituted files you can use:

  @FOO@

We use autoconf/automake with OCaml code all the time, and it works
fine.  There are also OCaml macros available:

  http://forge.ocamlcore.org/projects/ocaml-autoconf/
  http://git.ocamlcore.org/cgi-bin/gitweb.cgi?p=ocaml-autoconf/ocaml-autoconf.git;a=summary
      

ocaml for the Semantic Web

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/b1e21e262d4f2d29d44abd11a3a8e164.en.html

Tumenjargal Tsagaan asked:
(1) is there any specialized APIs for processing RDF as well as OWL file?
(2) is there any similar API in Ocaml like XML-parsers from Java world?
      
Sebastien Ferre replied:
I am also interested in processing semantic web languages in OCaml,
and I haven't found anything yet.
Some months ago, I wrote a parser for RDF files (using Xml-light).
This cannot be considered as an "API" for RDF, but the hard work of
analysing the RDF-XML is done (source file below).

Sébastien

(*
  Extracting RDF statements from the XML structure
  generated by the library 'xml-light'.

  Author: Sébastien Ferré <ferre@irisa.fr>
  Creation: 11/02/2009

*)

type uri = string
type id = string
type lang = string
type datatype = Plain of lang | Typed of uri
type thing = URI of uri | XMLLiteral of Xml.xml | Literal of string * datatype | Blank of id
type property = uri

type tree = Node of thing * (property * (uri option * tree)) list
type rdf = {
   xmlns : (string * string) list;
   trees : tree list
 }

(* accessors *)

let subject (Node (s, _)) = s

let properties (Node (_, ps)) = ps

let all_objects (Node (_, ps)) p = List.fold_right (fun (p', (_,o')) res -> if p' = p then o'::res else res) ps []

let statement (Node (_, ps)) p o =
 let (_, (uri, _)) = List.find (fun (p', (uri', Node (o', _))) -> p' = p && o' = o) ps in
 uri

(* RDF vocabulary *)

(* namespace *)
let namespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
(* classes *)
let _XMLLiteral = "rdf:XMLLiteral"
let _Property = "rdf:Property"
let _Statement = "rdf:Statement"
let _Bag = "rdf:Bag"
let _Set = "rdf:Set"
let _Alt = "rdf:Alt"
let _List = "rdf:List"
(* properties *)
let _type = "rdf:type"
let _first = "rdf:first"
let _rest = "rdf:rest"
let _value = "rdf:value"
let _subject = "rdf:subject"
let _object = "rdf:object"
let _predicate = "rdf:predicate"
let _n n = "rdf:_" ^ string_of_int n
(* ressources *)
let _nil = "rdf:nil"

(* parsing *)

type parse_ctx = { base : string; lang : string}

exception Failure
exception Error

let parse_list p l =
 List.rev
   (List.fold_left
      (fun res x -> try p x :: res with _ -> res)
      [] l)

let default_ctx = { base = ""; lang = ""}

let get_ctx previous_ctx e =
 { base = (try Xml.attrib e "xml:base" with _ -> previous_ctx.base);
   lang = (try Xml.attrib e "xml:lang" with _ -> previous_ctx.lang)}

let resolve ctx rel =
 if String.contains rel ':'
 then rel
 else ctx.base ^ rel

let resolve_tag ctx tag =
 if String.contains tag ':'
 then tag
 else ctx.base ^ "#" ^ tag

let isCoreSyntaxTerm x =
 List.mem x ["rdf:RDF"; "rdf:ID"; "rdf:about"; "rdf:parseType"; "rdf:resource"; "rdf:nodeID"; "rdf:datatype"]

let isSyntaxTerm x =
 isCoreSyntaxTerm x || List.mem x ["rdf:Description"; "rdf:li"]

let isOldTerm x = List.mem x ["rdf:aboutEach"; "rdf:aboutEachPrefix"; "rdf:bagID"]

let isNodeElementURI x = not (isCoreSyntaxTerm x || x = "rdf:li" || isOldTerm x)
let isPropertyElementURI x = not (isCoreSyntaxTerm x || x = "rdf:Description" || isOldTerm x)
let isPropertyAttributeURI x = not (isCoreSyntaxTerm x || x = "rdf:Description" || x = "rdf:li" || isOldTerm x)

let rec parse_RDF e =
 if Xml.tag e = "rdf:RDF"
 then {
   xmlns =
     List.fold_right
     (fun (a,v) res ->
       let i = try String.index a ':' with _ -> String.length a in
       if String.sub a 0 i = "xmlns"
       then
         let ns =
           if i = String.length a
           then ""
           else String.sub a (i+1) (String.length a - (i+1)) in
         (ns,v)::res
       else res)
     (Xml.attribs e) [];
   trees =
     let ctx = get_ctx default_ctx e in
     parse_list (parse_nodeElement ctx) (Xml.children e)
 }
 else raise Failure

and parse_nodeElement previous_ctx e =
 let tag = Xml.tag e in
 let ctx = get_ctx previous_ctx e in
 if isNodeElementURI tag
 then
   let subject =
     try URI (resolve ctx ("#" ^ Xml.attrib e "rdf:ID")) with _ ->
     try Blank (Xml.attrib e "rdf:nodeID") with _ ->
     try URI (resolve ctx (Xml.attrib e "rdf:about")) with _ ->
         Blank "" in
   let properties =
     (if tag = "rdf:Description" then [] else [(_type, (None, Node (URI (resolve_tag ctx tag), [])))]) @
     parse_list (parse_propertyAttr ctx) (Xml.attribs e) @
     parse_list (parse_propertyElt ctx (ref 0)) (Xml.children e) in
   Node (subject, properties)
 else raise Failure

and parse_propertyAttr ctx (a,v) =
 if isPropertyAttributeURI a
 then
   if a = _type
   then (a, (None, Node (URI (resolve ctx v), [])))
   else (a, (None, Node (Literal (v, Plain ctx.lang), [])))
 else raise Failure

and parse_propertyElt previous_ctx cpt e =
 incr cpt;
 let tag = match Xml.tag e with "rdf:li" -> "_" ^ string_of_int !cpt | s -> s in
 let ctx = get_ctx previous_ctx e in
 if isPropertyElementURI tag
 then
   let reified = try Some (resolve ctx ("#" ^ Xml.attrib e "rdf:ID")) with _ -> None in
   let children = Xml.children e in
   try
     match Xml.attrib e "rdf:parseType" with
     | "Resource" -> (* parseTypeResourcePropertyElt *)
         let properties = parse_list (parse_propertyElt ctx (ref 0)) children in
         (tag, (reified, Node (Blank "", properties)))
     | "Collection" -> (* parseTypeCollectionPropertyElt *)
         let t =
           List.fold_right
             (fun n res ->
               Node (Blank "",
                     [ (_first, (None, n));
                       (_rest, (None, res))]))
             (parse_list (parse_nodeElement ctx) children)
             (Node (URI _nil, [])) in
         (tag, (reified, t))
     | "Literal" (* parseTypeLiteralPropertyElt *)
     | _ -> (* parseTypeOtherPropertyElt *)
         let xml = match children with [n] -> n | _ -> raise Error in
         (tag, (reified, Node (XMLLiteral xml, [])))
   with _ ->
     match children with
     | [Xml.Element _ as n] -> (* resourcePropertyElt *)
         let t = parse_nodeElement ctx n in
         (tag, (reified, t))
     | [Xml.PCData s] -> (* literalPropertyElt *)
         let d =
           try Typed (Xml.attrib e "rdf:datatype") with _ ->
               Plain ctx.lang in
         (tag, (reified, Node (Literal (s,d), [])))
     | [] -> (* emptyPropertyElt *)
         let attribs = Xml.attribs e in
         ( match attribs with
         | []
         | ["rdf:ID",_] ->
             (tag, (reified, Node (Literal ("",Plain ctx.lang), [])))
         | _ ->
             let obj =
               try URI (resolve ctx (Xml.attrib e "rdf:resource")) with _ ->
               try Blank (Xml.attrib e "rdf:nodeID") with _ ->
                   Blank "" in
             let properties = parse_list (parse_propertyAttr ctx) attribs in
             (tag, (reified, Node (obj, properties)))
          )
     | _ -> raise Error
 else raise Failure

let from_xml xml =
 try parse_RDF xml with _ ->
     { xmlns = []; trees = [parse_nodeElement default_ctx xml]}
      

Transition to OCaml 3.11.1 in Ubuntu Karmic Koala completed!

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/82cf6e9a4c8194b8f7367b024d474034.en.html

David Mentre announced:
I am very pleased to announce that transition to OCaml 3.11.1 in
Ubuntu Karmic is now completed!
  http://bentobako.org/ubuntu-ocaml-status/transition_monitor/ocaml_transition_monitor.html

Many thanks to (in order of appearance):

 * Ubuntu side:
   James Wetsby
   Andrea Gasparini
   Michael Bienia
   Steve Kowalik
   Jonathan Riddell
   Stefan Lesicnik

 * Debian side:
    Stefano Zacchiroli
    Stéphane Glondu
    Mehdi Dogguy
    Sylvain Le Gall

And of course all the Debian and Ubuntu developers that work so hard
on OCaml support and have helped me doing this transition!

Currently, most of OCaml packages is Debian unstable are available in Karmic:
  http://bentobako.org/ubuntu-ocaml-status/raw/compare-unstable-karmic.html

[ I have requested a synchronization for "react" and "pgocaml". ]
      

lazy vs fun

Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2009/08/a6195dc96bf1f716608d7131a3ee5b3d.en.html

Warren Harris asked and Jake Donham replied:
> Is there any advantage to using lazy evaluation in ocaml rather than just
> using thunks to defer evaluation? E.g.
>
> let x = lazy (3+4)
> let y = Lazy.force x
>
> vs:
>
> let x = fun () -> 3+4
> let y = x ()

Lazy cells don't just defer, they also memoize the returned value once
the cell is forced.

  # let x = lazy (print_endline "forced"; 1);;
  val x : int lazy_t = <lazy>
  # Lazy.force x;;
  forced
  - : int = 1
  # Lazy.force x;;
  - : int = 1

They even memoize exceptions:

  # let x = lazy (print_endline "forced"; failwith "failed");;
  val x : 'a lazy_t = <lazy>
  # Lazy.force x;;
  forced
  Exception: Failure "failed".
  # Lazy.force x;;
  Exception: Failure "failed".
      

Other Caml News

From the ocamlcore planet blog:
Thanks to Alp Mestan, we now include in the Caml Weekly News the links to the
recent posts from the ocamlcore planet blog at http://planet.ocamlcore.org/.

Macaque:
  http://forge.ocamlcore.org/projects/macaque/

FP-Syd #17.:
  http://www.mega-nerd.com/erikd/Blog/FP-Syd/fp-syd-17.html

OCaml-Idaho:
  http://forge.ocamlcore.org/projects/ocaml-idaho/

Designing a code-review tool, Part 2: Patches or Diffs:
  http://ocaml.janestcapital.com/?q=node/67

Designing a code-review tool, Part 1:
  http://ocaml.janestcapital.com/?q=node/66

ocaml 3.11.1 in testing:
  http://upsilon.cc/~zack/blog/posts/2009/08/ocaml_3.11.1_in_testing/

Result of Debcamp at Debconf9 for OCaml task force:
  http://le-gall.net/sylvain+violaine/blog/index.php?2009/08/04/52-result-of-debcamp-at-debconf9-for-ocaml-task-force

RegStab 1.0:
  http://caml.inria.fr/cgi-bin/hump.cgi?contrib=706

OCaml plugin for the Netbeans IDE:
  http://caml.inria.fr/cgi-bin/hump.cgi?contrib=705

Transition to OCaml 3.11.1 has started in Karmic:
  http://bentobako.org/david/blog/index.php?post/2009/07/21/Transition-to-OCaml-3.11.1-has-started-in-Karmic
      

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