Previous week Up Next week

Hello

Here is the latest Caml Weekly News, for the week of 04 to 11 January, 2005.

  1. OUnit website moved
  2. Ocaml-Event-0.5.0
  3. Ocaml-Expat-0.9.0
  4. Parser for configuration file
  5. 3D vector libs for OCaml?
  6. OMake 0.9.4
  7. generic functions
  8. Thread safe Str
  9. parser data structures (ast)
  10. using Graphics with more than one window

OUnit website moved

Archive: http://caml.inria.fr/archives/200501/msg00028.html

Maas-Maarten Zeeman announced:
I'd like to announce the move of the OUnit website. Please update your
bookmarks. The new web-site is at: http://www.xs4all.nl/~mmzeeman/ocaml
    

Ocaml-Event-0.5.0

Archive: http://caml.inria.fr/archives/200501/msg00029.html

Maas-Maarten Zeeman announced:
I'd like to announce the release of Ocaml-Event-0.5.0, Ocaml bindings
for the libevent API.

http://www.xs4all.nl/~mmzeeman/ocaml/

The libevent API provides a mechanism to execute a callback function
when a specific event occurs on a file descriptor or after a timeout has
been reached. Furthermore, libevent also support callbacks due to
signals or regular timeouts.

Currently, libevent supports /dev/poll, kqueue(2), select(2), poll(2)
and epoll(4). The internal event mechanism is completely independent of
the exposed event API, and a simple update of libevent can provide new
functionality without having to redesign the applications. As a result,
Libevent allows for portable application development and provides the
most scalable event notification mechanism available on an operating
system.
    

Ocaml-Expat-0.9.0

Archive: http://caml.inria.fr/archives/200501/msg00030.html

Maas-Maarten Zeeman announced:
I'd like to announce Ocaml-Expat-0.9.0, Ocaml bindings for the Expat XML
Parser.

http://www.xs4all.nl/~mmzeeman/ocaml/
    

Parser for configuration file

Archive: http://caml.inria.fr/archives/200412/msg00327.html

Jean-Baptiste Rouquier said:
> Is there a library that implements a parser
> for configuration files similar to the *.ini
> files from windows? For instance:
>
>   [section 1]
>   key1 = value1
>   key2 = value2
>
>   [section 2]
>   key3 = value3
>   key4 = value4
>   key5 = value5

Inifiles (http://www.csun.edu/~eric/inifiles-1.0.tar.gz) is explicitely designed
to parse this file format.

I also suggest my own lib, Config_file, available at
http://savannah.nongnu.org/download/cameleon/ . It allows comments, command lines
options identical to file options (based on Arg), arbitrary nesting of
subsections, error logging and a few more features.
    

3D vector libs for OCaml?

Archive: http://caml.inria.fr/archives/200501/msg00033.html

Richard Jones asked:
I'm looking for a 3D vector library for OCaml.  In particular I'm
interested in:

* points, rays, vectors, surfaces
* intersection of sphere and ray, surface and ray, etc.

Simple enough to write myself, but I was hoping that one would already
exist.  I checked the Humps, and the nearest I could find are GeOCaml,
which seems to be 2D only, and SOCaml which is the OCaml interface to
Open Inventor, which is not quite what I'm looking for.
    
Sachin Shah answered:
I am not sure if this exactly fits your needs, but PsiLAB
(http://psilab.sourceforge.net/) is available for the types of
mathematical operations you are talking about.  At the very least, it
provides extensive matrix/linear algebra operations, which you could
use to write your own (assuming another is unavailable).
    
Jon Harrop suggested and Richard Jones replied:
> Sounds like ray-tracing territory. IIRC there was an ocaml
> ray-tracer entry to one of the old ICFP contests. I suspect the
> source is available and should fill many of those holes.

Thanks - I found the source to the ray tracer
(http://caml.inria.fr/icfp00-contest/) which is very useful.

> Will this be performance critical?

I'm just messing around with some 3D scene stuff ...
    
Lars Nilsson added:
There's also a raytracer written in O'Caml available at

  http://user.it.uu.se/~jenso/programming/
    

OMake 0.9.4

Archive: http://caml.inria.fr/archives/200501/msg00038.html

Aleksey Nogin announced:
The OMake Team is proud to announce a new release of the OMake Build
System - OMake 0.9.4.

OMake is a build system, similar to GNU make, but with many additional
features:

    o Support for large projects spanning several directories or
      directory hierarchies.

    o Comes with a default configuration file providing support for
      OCaml, C and LaTeX projects, or a mixture thereof.
      Often, a configuration file is as simple as a single line

         OCamlProgram(prog, foo bar baz)

      which states that the program "prog" is built from the files
      foo.ml, bar.ml, and baz.ml.

    o Fast, reliable, automated dependency analysis using MD5 digests.

    o Portability: omake provides a uniform interface on Win32 and
      on Unix systems including Linux and Mac OS X.

    o Builtin functions that provide the most common features of
      programs like grep, sed, and awk.  These are especially useful on
      Win32.

    o Full native support for rules that build several things at once
      (such as ocamlopt building .cmx and .o).

    o Active filesystem monitoring, where the build automatically
      restarts whenever you modify a source file.  This can be very
      useful during the edit/compile cycle.

    o A companion command interpreter, osh, that can be used
      interactively.

The home site for OMake is http://omake.metaprl.org/

OMake version 0.9.4 contains a large number of enhancements and bug
fixes, including:

  - Portability improvements. OMake should now compile and work under
    Windows 2000, Windows NT and FreeBSD. A number of Windows-specific
    bugs are fixed. A Windows installer is added.

  - OMake now uses the built-in versions of the following commands:
       cp, mv, mkdir, rm, rmdir, chmod

  - Improvements to the filesystem watch functionality. In particular,
    the build will now restart if a change to one of the OMakefiles is
    detected.

  - Added a USE_OCAMLFIND variable that can be used to force or prohibit
    the usage of ocamlfind in a project (by default USE_OCAMLFIND is set
    to true iff the ocamlfind executable is found in path).

  - Added a "--force-dotomake" option to create all .omc and .omo files
    under $HOME/.omake/cache and a "--dotomake" option to specify an
    alternative to $HOME/.omake

  - Added :squash: dependencies (that specify that a dependency must
    be built, but when the dependency changes, it does not cause the
    target to be rebuilt).

  - OMake will now read ~/.omakeinit and ~/.omakerc files on startup.

  - Improved the latex-related rules.

  - Documentation improvements.

  - Bugs fixed: 142, 153, 311, 313, 314, 316, 332, 333, 339, 350, 360,
    361, 366, 367, 368, 374, 375. See
http://bugzilla.metaprl.org/buglist.cgi?bug_id=142,153,311,313,314,316,332,333,339,350,360,361,366
,367,368,374,375
    for details.

OMake 0.9.4 is still an alpha release.  While we have made an effort to
ensure that it is bug-free, it is possible some functions may not behave
as you would expect.  Please report any comments and/or bugs to the
mailing list omake at metaprl.org and/or at http://metaprl.org/bugzilla

OMake is distributed under the terms of the GNU General Public License.
OMake configuration files are distributed under the terms of an MIT-like
license. OMake sources, as well as a number of Linux and Windows
binaries are available from the OMake home page at http://omake.metaprl.org/
    

generic functions

Archive: http://caml.inria.fr/archives/200501/msg00046.html

Someone asked:
I just got from LISP to OCaml, and wondered if there is an equivalent of
generic functions from LISP (CLOS) in OCaml. In the Common Lisp Object
System methods don't belong to certain objects/classes. They are just
function specializing on the argument types. So basically I want to
write something like:

let foo (x : int) = x*x;;
let foo (x : float) = x*.x;;

This, obviously, will not work since foo is just redefined by the second
statement. One would think, that having methods not being belonging to
objects/classes, is rather pointless. Well 95% of the time, there is no
necessity for that. But in the other 5%, it is really helpful.
    
Richard Jones answered:
The general solution is GCaml
(http://pauillac.inria.fr/~furuse/generics/README.gcaml) which is not
part of OCaml core.
    
Brian Hurt also answered:
The short answer is no.  For two reasons- first, Ocaml doesn't keep type
information (in most cases) of data at run time, the type information is
used during compilation and then tossed.  Which means that Ocaml doesn't
have a way at run time to tell which version of the function to call.  And
second, and more importantly, overloading (like you're doing above) would
make type inference extremely difficult if not impossible.

There are several ways to "work around" this limitation in Ocaml,
depending upon what exactly you are doing.

1) Just use different functions.  Do:
        let ifoo x = x * x;;
        let ffoo x = x *. x;;
and just call the correct one.  This is generally not as bad a solution as
you might think.

2) Use variant types:
        type number = Int of int | Float of float;;
        let foo = function
                | Int(x) -> Int(x*x)
                | Float(x) -> Float(x*.x)
        ;;
The tags in this case are the type information Ocaml would normally "throw
away".

3) Use modules:
        module type Mult = sig
                type t
                val mul : t -> t -> t
        end
        module type Foo = sig
                type t
                val foo : t -> t
        end
        module Make(M: Mult) : Foo with type t = M.t = struct
                type t = M.t
                let foo x = M.mul x x
        end;;
        module IMult = struct
                type t = int
                let mul x y = x * y
        end;;
        module IFoo = Make(IMult);;
        module FMult = struct
                type t = float
                let mul x y = x *. y
        end
        module FFoo = Make(FMult);

For this simple example, modules and functors are clunky- but they allow
the user of your code to create new foo functions, which is usefull.

With the exception of certain artificial contests (Paul Graham) I've never
met a real world problem that needed overloading, or even benefitted
signifigantly from overloading that didn't benefit just as much or more
from one of the solutions above.
    
Someone added:
> 3) Use modules:
....

I would add 4)  use objects.
see http://caml.inria.fr/ocaml/htmlman/manual005.html
and define a class ofloat, and oint (for object float and objects int)
and define
  let foo x = x#mul x
Note that foo does not have to belong to the classes. It can be defined
outside of the class defintion.
Of course if your definition of foo would have been
 let foo (x : int) = x+x;; (* * have been replaced by + *)
 let foo (x : float) = x*.x;;
then, it does not work anymore.

>
> With the exception of certain artificial contests (Paul Graham) I've never
> met a real world problem that needed overloading, or even benefitted
> signifigantly from overloading that didn't benefit just as much or more
> from one of the solutions above.

I guess that's because you never been involved in real world problems.
Overloading, which is adhoc polymorphism is as useful as
parametric polymorphism. Ask the haskell folks if they would accept
to forget about type classes.
Of course functors can emulate some of the advantages of overloading,
but not totally. Objects are better for this.
    
John Skaller also answered:
Felix is an ML like language which does provide overloading.
It does overload resolution at compile time. As Brian mentions
this makes full type inference hard, however this isn't nearly so
much of a problem as you might think

You have to annotate function argument types, however function
return types and variable types are still deduced. For this extra
effort you get three positive benefits:

(a) better documented code
(b) better diagnostic messages on type errors
(c) overloading

In addition, some of the newer Ocaml features like polymorphic
variants require type annotations or coercions to be used
at times anyhow, and such annotation is common for functions
in separately compiled files, which often have interface
specifications (which require type annotations).

The two principal advantages of inference would appear to be:

(a) for quick and dirty code and small functions where
the extra clutter would reduce clarity and increase coding time.

(b) for complex functions with nasty types

The brevity argument is context dependent. I have just written in
Felix a function which converts a complex parse tree into
a string. This function has to decode around 100 variants
from 40 or so types to produce the result.

In Felix all these functions are called 'str', and I can just
write code like

fun str : product_list_t -> string =
  | product_list_1 (?s,?sl) => str s + " * " + str sl
  | product_list_2 ?s => str s
;


fun str : term_t -> string =
  | term_1 (?t,?p) => str t + " / " + str p
  | term_2 (?t,?p) => str t + " % " + str p
  | term_3 ?pr => str pr
;

...

Without overloading I would have to invent a discrete name for
each function, which would certainly reflect the argument type,
so this is balances out in favour of overloading. In the actual
use of the function there is no doubt that overloading is
briefer than inference without it, since I can use
the 'str' name without knowing which function is applied.

In Ocaml, this program would be almost untenable.
I would try to avoid this problem by using polymorphic variants
instead of ordinary ones (and then write one big 'str' function
for all the variants).

Bottom line: I have used two similar languages, one with
type inference and one with overloading, and in general
I could pick between them like this:

Overloading (in the Felix and C++ style) only works on direct
calls where the function is named. It doesn't work with
closures, for example variables containing function values,
including parameters. So I would say inference is better
when you're doing lots of higher order work, and overloading
is better for more mundane industrial applications.

BTW: it would be interesting to provide a better integration
of both features. G'Caml is one idea. Polymorphic variants
are another. In Felix you can write:

        fun swap(x,y) => y,x;

without type annotations: type variables are assumed but
they're independent. This precludes code like

        fun apply(f,x)=> f x;

but it is clear some localised inference in this case would
allow this.

It is also known that overloading CAN work with
inference with some contraints -- there is a paper somewhere
on Citeseer on this topic (sorry don't have the URL at the
moment, if someone finds it please let me know..)
    
Alex Baretta said:
> With the exception of certain artificial contests (Paul Graham) I've never 
> met a real world problem that needed overloading, or even benefitted 
> signifigantly from overloading that didn't benefit just as much or more 
> from one of the solutions above.

As a member of the International Caml's Jihad, I'd like to spend two 
cents of dynamite on this topic: type inference is as good as honey in 
large scale industrial projects, where sometimes the typing of complex 
recursive polymorphic algorithms is not evident until you get the 
printout from the compiler or the toplevel. Thank you, O great 
Unification Algorithm.

But, then again, extensional polymorphism is also a much needed feature. 
In my company we depend heavily on on extensional polymorphism to create 
exstensibile functions. We have implemented this on top of explicitly 
polymorphic types: i.e. polymorphic variant types.

Let us all faithfully await the Coming of the the Gcaml... And meanwhile 
let us use polymorphic variants to get the same effect.

type poly_int = [ `Int of int ]
type poly_float = [ `Float of float ]

let foo_int foo = function
   | `Int x -> `Int(x * x)
   | other -> foo other

let foo_float foo = function
   | `Float x -> `Float(x *. x)
   | other -> foo other

let rec foo x = match x with
   | #poly_int -> foo_int foo x
   | #poly_float -> foo_float foo x


All hail Ocaml!

Alex, after too many nights spent writing typechecking code...
    
Olivier Andrieu said and Alex Baretta answered:
> Hum, I would have written this in that way :
> ,----
> | let foo_int   (`Int x)   = `Int   (x * x)
> | let foo_float (`Float x) = `Float (x *. x)
> | 
> | let foo = function
> |   | #poly_int   as x -> foo_int x
> |   | #poly_float as x -> foo_float x
> `----
> 
> What's the use for the `other -> foo other' clauses ?

In my previous post I mentioned *extensible functions*. The first 
parameter of single instances of the polymorphic foo (i.e. foo_int and 
foo_float) allow the generalization of each of these to arbitrarily 
complex polymorphic type schema. We have exactly 7888 lines of code 
which contain such late-bound-recursive functions à la foo_int. 
Obviously it takes a relatively complex example to show why 
late-bound-recursion is essential to the implementation of a fairly 
extensional polymorphism with Ocaml's polymorphic variants.
    
And the thread continued ...:
I invite the interested readers to read the rest in the archive, the thread
starts at http://caml.inria.fr/archives/200501/msg00046.html
    

Thread safe Str

Archive: http://caml.inria.fr/archives/200501/msg00053.html

Christophe Troestler asked and Gerd Stolpmann answered:
> The new Str module not only made it LGPL but also very fast (100% more
> than Pcre in some cases).  However it is still not thread safe -- and
> it is not possible given its interface.  However, from a quick look,
> it seems to me that what is under the hood is almost thread safe.  So
> why not to write a new module (say Regexp) which would be thread safe
> and on top of which Str would be build?  This would not be too much
> work, would it?

The Netstring_str module (part of ocamlnet) does it the other way round:
The thread-safe interface is built on top of a potentially unsafe
implementation. Although the current version of Netstring_str uses Pcre
as its implementation, there is a historic version on top of Str. This
other way of layering can be made working because there is the global
master lock protecting the C parts of the regexp engine.

The interface of Netstring_str:
http://ocamlnet.sourceforge.net/manual/refman/Netstring_str.html

Of course, this is not the optimal solution, I would prefer it the way
you suggest.
    
Xavier Leroy answered, causing many replies in the thread:
> The new Str module not only made it LGPL but also very fast (100% more
> than Pcre in some cases).  However it is still not thread safe -- and
> it is not possible given its interface.  However, from a quick look,
> it seems to me that what is under the hood is almost thread safe.

You are correct: the regexp compiler (written in Caml) and the
execution engine (written in C) are thread-safe, it's only the API (in
Caml) that uses global state.

> So why not to write a new module (say Regexp) which would be thread
> safe and on top of which Str would be build?

That's a very good idea.  My initial plan was to have two APIs, the
old Str for compatibility and a newer, better designed one for new
programs.  Besides being thread-safe, the new API could also expose
the abstract syntax tree for regexps, allowing easier construction of
complex regexps by programs than can be done by working at the level
of the string representation of regexps.  It's just that I never got
to design that new API :-(

> This would not be too much work, would it?

The implementation work should be quite small indeed, but don't
underestimate the work needed to design the API.  API design is harder
than it seems...  But if a few persons on this list want to team up to
design an API, that would be wonderful indeed.  (A small group is
better than individual designers in that several pairs of eyes spot
inconsistencies better.)
    

parser data structures (ast)

Archive: http://caml.inria.fr/archives/200501/msg00045.html

Radu Grigore asked and Christian Lindig answered:
> Is there any document describing some decisions involved in choosing
> the right data structures for representing the OCaml parse tree? Is
> there any document describing some idioms that are common in the fp
> world?
> 
> I work on translators using C++ and I'd like to learn from other approaches.

I suggest to look at CIL, an infrastructure in OCaml for ANSI C.

http://manju.cs.berkeley.edu/cil/
    

using Graphics with more than one window

Martin Willensdorfer asked and Richard Jones answered:
> Can anyone tell me if it is possible to open two graphic windows in ocaml? I 
> would like to have something like a popup window that shows additional 
> information when clicking on specific regions in the initial graphics 
> windows.

You might want to migrate to a "proper" solution sooner rather than
later.  After all, you might also soon want to add buttons and menus.
Have a look at lablgtk2, here:
http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgtk.html
It supports a very capable canvas widget.
    

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
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