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
========================================================================
1) 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>
========================================================================
2) 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
>
========================================================================
3) 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.
========================================================================
4) 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.
========================================================================
5) 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>
========================================================================
6) 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!
========================================================================
7) 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 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>
========================================================================
8) 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>
========================================================================
9) 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>
========================================================================
10) 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.
========================================================================
11) 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>
========================================================================
12) 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.
========================================================================
13) 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.
========================================================================
14) 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 @[email protected]:>@])],
[],
[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:
@[email protected]
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
>
========================================================================
15) 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é
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]}
========================================================================
16) 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". ]
========================================================================
17) 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.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.force x;;
forced
Exception: Failure "failed".
# Lazy.force x;;
Exception: Failure "failed".
========================================================================
18) 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
(alan.schmitt-o/5/jSaJEHk+NdeTPqioyti2O/[email protected]) and I'll
mail it to you, or go take a look
at
the archive (<http://alan.petitepomme.net/cwn/>)
or the RSS feed of the
archives (<http://alan.petitepomme.net/cwn/cwn.rss>).
If you also wish
to receive it every week by mail, you may subscribe online at
<http://lists.idyll.org/listinfo/caml-news-weekly/>
.
========================================================================