[cwn] Attn: Development Editor, Latest Caml Weekly News

Alan Schmitt alan.schmitt at polytechnique.org
Tue Jan 11 14:16:56 PST 2005


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

======================================================================== 
======
1) 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

======================================================================== 
======
2) 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.

======================================================================== 
======
3) 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/

======================================================================== 
======
4) 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.

======================================================================== 
======
5) 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/

======================================================================== 
======
6) 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/

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

======================================================================== 
======
8) 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.)

======================================================================== 
======
9) 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/

======================================================================== 
======
10) 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
(alan.schmitt at polytechnique.org) and I'll mail it to you, or go take a  
look at
the archive (http://sardes.inrialpes.fr/~aschmitt/cwn/) or the RSS feed  
of the
archives (http://sardes.inrialpes.fr/~aschmitt/cwn/cwn.rss). If you  
also wish to
receive it every week by mail, just tell me so.

======================================================================== 
======

Alan Schmitt
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: =?ISO-8859-1?Q?Ceci_est_une_signature_=E9lectronique_PGP?=
Url : http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20050111/9a2deebd/PGP.bin


More information about the caml-news-weekly mailing list