Hello
Here is the latest Caml Weekly News, for the week of 04 to 11 January, 2005.
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
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.
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/
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.
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/
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/
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
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.)
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/
> 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.
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.
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.