Previous week Up Next week


Here is the latest Caml Weekly News, for the week of 13 to 20 December, 2005.

Joyeux Noël !

  1. Weblogs and HostIP modules
  2. Concurrent and Distributed Programming in Ocaml
  3. Generic access to float arrays

Weblogs and HostIP modules


Richard Jones announced:
I'm pleased to announce that we have "liberated" another two modules
which we use internally.


A module for importing web logfiles from Apache or IIS web servers and
doing simple analysis on them.

License: LGPL + OCaml linking exception


HostIP is an OCaml module for looking up geolocation data from IP
addresses. It uses the community project API.

License: LGPL + OCaml linking exception

Concurrent and Distributed Programming in Ocaml


Alexsandro Soares asked:
   My team is working with evolutionary computing and
we develop a distributed model of gene expression
programming (GEP) in OCaml. Our first try used the
primitives provided in modules Mutex and Condition to
do syncronization between process and threads. The
system is done. However, we will make a refactoring of
the code and, at this time,  we would like to use
higher level constructs to work with concurrent and
distributed programming. What are the options to do
this in OCaml? We started to see Jocaml, but our
system uses native code generation both in Linux and
Windows, and I don't know if Jocaml can be compiled in
native code. Any help?
Vincenzo Ciancia suggested:
I would recommend trying the Event module which features channels and
events, which in turn are an abstraction which allows to build more complex
events from simpler ones before "synchronizing" on the resulting event.

For example, "receive a" is the event that, when you synchronize to it,
waits for a value to be sent on channel "a", and returns the value, and
"choose [receive a,receive b]" is the event that, when you synchronize to
it, waits for a value to be sent on either "a" or "b" and returns the value
- in this case a and b must have the same value type.
David Teller then said:
While this module is absolutely great, it suffers from OCaml's
limitation that multi-threaded code runs only one one processor, even if
several are available.

For concurrency, I would suggest taking a look at Acute, but that's
quite low-level, when compared to JoCaml. Basically, the communication
primitives are similar to a somewhat lower-level version of the Event
module. I don't know whether there is a native code compiler, though.

Generic access to float arrays


Andries Hekstra asked and Gerd Stolpmann answered:
> Attached please find the first program I wrote. It has about the same
> speed as its C++ counterpart (slightly faster). I welcome comments w.r.t.
> programming style, esp. when it affects the speed of the program.

As you are doing a lot of array manipulation, this tip may increase
performance significantly: because "float array" is stored with a
different layout than all other arrays, the compiler generates a dynamic
check for every access when the type of the array elements cannot be
statically determined. For example, your function

let swapElement i j a = let x = a.(i) in a.(i) <- a.(j); a.(j) <- x

is polymorphic in the element type. If you define instead

let swapFloatElement i j (a : float array) =
  let x = a.(i) in a.(i) <- a.(j); a.(j) <- x

better code is generated because the mentioned check can be omitted by the
compiler. This applies only if the function is not inlined; swapElement
could be small enough (but qsort, for instance, is definitely not).

Unfortunately, one cannot define swapNonFloatElement because there is no
way to constrain a type that it is not float. So the type system cannot
represent this duality float/non-float, and one must fall back to as many
definitions as element types are actually used.
Gerd Stolpmann added and Xavier Leroy said:
> I forgot one thing: This comment is only correct for 32 bit code. 64 bit
> code has a uniform array layout for all element types.

Yes, but a generic access to a float array still involves an extra
boxing operation.  So, your advice is sound for 64-bit plaforms as well.

I had a very quick look at the original poster's code: it seems
reasonable performance-wise.  There are a few extra hacks that could
be done to increase performance at some expense in code clarity, for
instance turning

            a.(i).(j) <- f i j a.(i).(j);
            (let b = a.(i) in b.(j) <- f i j b.(j));

but I wouldn't recommend doing this unless profiling exhibits a big
"hot spot" in this function.

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

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