Hello
Here is the latest Caml Weekly News, for the week of 26 April to 03 May, 2005.
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/38663b36c2e7971eebe0dd989798f3cd.en.html
Michel Mauny announced:Please forward this announce to whom might be interested. INRIA-Rocquencourt (Cristal group) is seeking for an engineer whose task will be to develop a specific version of the Caml language in partnership with an an IT manufacturer. More information at http://quincy.inria.fr/ing-en.html .
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/33ea2e8128a2d90f6a1514d180dc6271.en.html
Julien Verlaguet asked and Jean-Christophe Filliatre answered:> I have the following function definition : > > let myfun param= > let res=Marshal.from_channel stdin [] in > if res=param then > res > else res > > I was expecting : myfun : 'a -> 'a > > I got instead : myfun : 'a -> 'b > > Is it normal ? Yes. "Marshal.from_channel stdin []" has type 'a and this type is generalized in the let/in construct, giving res the type "forall 'a. 'a". In the test "res = param", the type of res is instanciated on the type of param, but this does not affect the type of the result. It would be better if Marshal.from_channel would be given a type that cannot be generalized ('_a) but I don't think that the ocaml type system can do this. Anyway, it is always a good idea to use a type constraint when using marshalling functions, as in let (x : tau) = Marshal.from_channel ...Mark Shinwell then asked and Jacques Garrigue answered:
> > Yes. "Marshal.from_channel stdin []" has type 'a and this type is > > generalized in the let/in construct, giving res the type "forall > > 'a. 'a". In the test "res = param", the type of res is instanciated on > > the type of param, but this does not affect the type of the result. > > I can understand this behaviour in a case such as the following: > > let f v = > let r = fun x -> x in > if r = v then r else r > > where as you say the (non-trivial) type scheme assigned to r is > instantiated multiple times, yielding ('a -> 'a) -> 'b -> 'b for f. > > However, in the Marshal example above, we have > > Marshal.from_channel stdin [] > > in the first part of the "let". In the SML terminology, this is not a > "nonexpansive expression"[*] (unlike "fun x -> x"). Therefore, I would > have thought that the appearance of such an expression here would > prohibit generalisation (in order to prevent possible unsoundness in the > presence of mutable state). This is presumably not the case in OCaml: > can someone explain why? > > Mark > > [*] http://www.smlnj.org//doc/Conversion/types.html Because ocaml now uses an improvement of the so-called "value restriction". Rather than refusing to generalize any variable in expansive expressions, it generalizes covariant ones, as they cannot be used in an unsound way. (See "Relaxing the value restriction" at http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/papers/) What we see here is a consequence of that for functions which are known as typing holes: any function that returns a totally unconstrained result (as input_value or Obj.magic) allows this result to be generalized. Actually, for Obj.magic this is a good thing: you sometimes want the result to be polymorphic (this is not a real function anyway). For input_value this is subject for discussion, but anyway this function is a glaring hole in the type system... maybe we should have a way to explicitly require its result to be annotated with a ground type!
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/620595164517ee253e0c180d5eaaa0b7.en.html
David Baelde announced:The Savonet project aims at building a complex web-radio system, completely written in OCaml. We are proud to finally release the first stable version of liquidsoap, the heart of the Savonet system! Not only is it stable, it is also very rich, as demonstrated by examples on our website. Unfortunately, we can't make a public demonstration web-radio. Gentoo ebuilds are available, and Debian packages should be released soon. Check on our website: http://savonet.sourceforge.net Here's a list of the released packages, featuring newly released sub-projects and many major bug fixes: * liquidsoap-0.2.0 Programmable and extensible audio stream generator, allows any kind of audio manipulation. * ocaml-dtools-0.1.1 Utilies for logging, configuration, and startup/shutdown services of your OCaml applications. * ocaml-ftp-0.1.0 FTP file access. * ocaml-smbclient-0.1.0 Bindings for libsmbclient, for Samba file access. * ocaml-fetch-0.1.0 Transparent remote/local file access. * ocaml-mad-0.1.3 Bindings for libmad, for encoding/decoding MP3. * ocaml-mp3id3-0.2.0 For reading Mp3Id3 tags. * ocaml-vorbis-0.2.0 Bindings for libvorbis+libogg, for encoding/decoding Ogg/Vorbis. * ocaml-shout-0.2.0 Bindings for shout2 library for streaming ogg/mp3 audio data. * ocaml-ssl-0.2.0 Bindings for libssl, provinding secure sockets. Thanks to all that work, liquidsoap is a very powerful and flexible audio streaming language, abstracting over format, protocol, stream generation, manipulation and output. Allowing arbitrarily deep-nested composition of streams and easy extensibility, it gives you more power than you need for creating an original web-radio. But liquidsoap is still very light and easy to use, in the Unix tradition of many simple strong components working together. The web-radio we're running accepts user requests, and then search in a database for matching songs. The database feeder is not yet released, but is available on CVS. Other unmaintained parts of the project are a website and an OCaml IRC bot, making easy the user requests and playlist querying. Instead we're currently using an unpublished Perl hack. All of these components were expected to communicate using libsavonet, using authentification, and directly exchanging caml values over network. Hope our project interests a few of you, and demonstrate that OCaml is a great real-life programming language.
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/0cb1293570b0f1fd9d36e904eeee929e.en.html
Martin Jambon announced:I am pleased to announce the availability of this new online resource: "How to customize the syntax of OCaml, using Camlp4" URL: http://martin.jambon.free.fr/extend-ocaml-syntax.html
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/d22b1761efb27d7b182cb9eabf245e1c.en.html
Jon Harrop announced:I just knocked up a little ray tracer in OCaml to test its viability for the shootout: http://www.ffconsultancy.com/free/ray_tracer/ Here, it traces a 768^2 image of 66,430 spheres in 22.51s on a 1.2GHz Athlon-Thunderbird and in 7.24s on a 1.8GHz Athlon 64. I've boiled it down to 94 LOC and posted it to the shootout mailing list.
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/677f99f4fc250f84c4b36c7594f137a9.en.html
Olivier Michel asked and Damien Doligez answered:> I just noticed the following change in Ocaml between release 3.06 and > 3.08.3, as far > as equality on records is concerned : > > # type toto = { b : int -> int; };; > type toto = { b : int -> int; } > # let a = { b = (fun x -> x) } ;; > val a : toto = {b = <fun>} > # a = a;; > Exception: Invalid_argument "equal: functional value". > > > Is this supposed to be a bug, or a feature ? Will future releases of > Ocaml follow > the new way of handling equality between records or the old one ? New feature. Carefully thought out. Well documented. Ultimately caused by a strange wart of the IEEE floating-point standards. You should use the "compare" function if you want the old behaviour.Alex Baretta said:
Keep in mind that in 3.06 physical equality (==) implied structural equality (=). Now, (=) now longer checks for (==), so no functional value can be found to be structurally equal to any other functional value. The following line illustrates this point. # (=) (=) (=);; Exception: Invalid_argument "equal: functional value". Actually, an interesting question related to this one is why the following line behaves as it does. # (==) (==) (==);; - : bool = falseOlivier Andrieu answered and Marcin Kowalczyk added:
> Probably because == is defined by an "external" in pervasives.ml, > not a regular function definition. So here, when you use (==), > you're building three closures. Two. OCaml materializes function objects corresponding to external functions each time they are used instead of once at the point of their definition (presumably because it assumes that usually they are not passed as first-class objects at all), but application of such function doesn't need the function object but jumps straight to its machine code.Jon Harrop then said:
# let f = (==) in (==) f f;; - : bool = true Interesting. I don't like it, but it's interesting. :-)
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/29ca2e908ec620baea6f17300835ae5b.en.html
Oliver Bandel announced:I have to announce a tool which is useful in sorting/listing/moving files. It's name "pftdbns" is a short hand for "put files to directories (sorted) by name structure". It takes filenames, maps each char of the filename into a char, representing the charclass of it (a..z and A..Z -> "l" (letter), 0...9 -> "d" (digit" and so on). Thsi yields to an easy way of sorting files by names, based upon file-naming with certain filenaming-conventions. So, for example "hello.txt" and "ballo.txt" are part of the same name structure, as well as "1001.txt" and "8251.txt" but also "8251.jpg" are of the same name structure. The default behaviour is to move files into directories. The names of the directories are choosen from the string, which represents the name structure. But since version 0.2.2 this defaulkt behaviour can be overriden, so that the files will not be moved, but only the names (or names and the namestructure strings) will be printed. So, I hope you enjoy this program, and I think if you have to handle a lot of files, this will be very helpful. You can find the tool here: ftp://www.belug.org/new/user/ob/Programs/Tools/pftdbns/ There also is a README in this directory, so that you can read more details. A description can also be found here: http://www.belug.org/~ob/ftp-area.html pftdbns uses the GPL-license.
Archive: http://caml.inria.fr/pub/ml-archives/caml-list/2005/05/cca768b52b2c21cf6ba35ad3558bf17e.en.html
Matt Gushee announced:[ ... written in OCaml, of course! ] To make a long story short: I couldn't find a file manager that had just the right combination of features, so I created Bantam. It attempts to be a fast, light, unobtrusive productivity aid for power users of POSIX/X11 systems. Important features include: * An arbitrary number of directory views * Single-keystroke commands * Internal text file viewer * Configurable interface to external viewers and editors * A minimum of visual clutter (i.e. no icons, etc.) Bantam 0.1 is now available in source and Linux binary packages. The binary should work on any system with Tcl/Tk 8.4 installed. If you have any trouble installing or running it, *please* let me know. The Bantam home page is http://matt.gushee.net/software/bantam/ .
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.