Previous week Up Next week

Hello

Here is the latest Caml Weekly News, for the week of 18 to 25 November, 2003.

  1. Inferring exceptions
  2. AutoMLI
  3. Release announcements
  4. OCaml - No Batteries Included :(
  5. int -> byte array (and back)
  6. Compiling a native code OCaml library into an .so?
  7. Inner workings of Caml compiler
  8. Parallel programming
  9. Classes, objects, and class variables
  10. Any Java parser written in OCaml?
  11. Building large and portable projects
  12. ocaml-i18n list
  13. ooowrite generates OpenOffice of StarOffice Writer .sxw files from OCaml programs
  14. GD4O release 1.0a5

Inferring exceptions

Benjamin Geer asked and Xavier Leroy answered:
> If the type of a function included its exception specification,
> could Caml infer exception specifications?

Yes, with the proviso that you need a fairly sophisticated exception
analysis to get enough precision in practice.  See for instance the
PhD work of my former student, François Pessaux:

François Pessaux and Xavier Leroy. Type-based analysis of uncaught
exceptions. ACM Transactions on Programming Languages and Systems,
22(2):340-377, 2000.
http://pauillac.inria.fr/~xleroy/publi/exceptions-toplas.ps.gz
    

AutoMLI

Richard Jones asked and Jim announced:
> It's a bit of a flaw in the language that you have all this lovely
> type inference working for you, but then you have to go and declare
> your types anyway in the .mli files.

It occured to me that this should be fairly easy to fix using some kind of
preprocessor, so this afternoon I had a go at throwing one together.

http://draco.dyndns.org/~jim/files/automli-0.1.tar.gz

Using this program, you write foo.ml, then create a foo.mla file containing
something like:

export none ;
export val foo ;   
export type bar ;
export type qux ;
export typedef qux ;

Then running

automli foo >foo.mli

will generate an interface containing the definition for function foo, the
abstract type bar, and the concrete type qux, all taken automagically from
foo.ml.

If you prefer to say which things you DON'T want exported, instead of those you
do, you can write a foo.mla file like this:

export all ;
hide typedef bar ;

It should handle values, types, classes, class types, and exceptions.  It also
works for modules and module types, except there is no way to specify what from
a module declaration should be exported.  (i.e., the whole thing gets exported.)

It also works for the revised syntax.  Use automlir instead of automli.

Note, this program is in the "very dodgy hack" category, and I haven't tested
it in any real life situations.  I knew nothing about camlp4 before today, (nor
do I know much about it now ;) ) so I have no idea if what I have done is sane,
except that it seems to work for me on my simple test data, using O'Caml 3.07.

There are many bugs, I'm sure. For example, it doesn't do any kind of error or
sanity checking.

I'm going to play with this program in my own project, as I am often annoyed by
the need to keep my mli files in sync with my ml files, and if it turns out to
be useful I may develop it further.  (Unless anyone else feels inspired to do
it for me.  :) )

Feedback welcome.

What can be exported in a mli file that I have missed?  There are definitely
more declarations in MLast, but as it isn't documented, I don't know what they
are.

Can anyone tell me how I can get pr_r.cmo to send output to a file, instead of
stdout?
    

Release announcements

Shawn Wagner announced:
Ocaml-MySQL 1.0.2: Bindings for accessing MySQL databases from ocaml.
  Changes: Now licensed under the LGPL.
  New function, Mysql.insert_id

Mathlib 0.9.0: Assorted math functions.
  Changes: Rewrote the Mersenne Twister RNG to use literal int32s. Now
requires ocaml 3.07.

Extlib 0.10.2: Assorted non-math-related extensions of the standard libraries.
  Changes: New functions Time.parse_tm, Time.parse_time, UnixExtras.pread
and UnixExtras.pwrite

All available at http://raevnos.pennmush.org/code/ocaml.html
    
Stefano Zacchiroli asked and Shawn Wagner answered:
> Is this related in some way to the other "extlib"
> (http://ocaml-lib.sourceforge.net) project?
>

Nope.
    

OCaml - No Batteries Included :(

Christian Schaller asked and Gerd Stolpmann answered:
> Dear Camlers,
>
> Working on a small software project, I decided to use OCaml for reasons
> we all know ;-)
> 
> Everything works smooth, however, there's one thing that drives me nuts:
> libraries!  I'm not complaining about not enough libraries being
> available, but about libraries being available, but not bundled in any
> with with OCaml (like getopt).
>
> Did I miss anything?  Is there an OCaml Extended Library Distribution
> available that I can just download from *one* place, including *all*
> known libraries?  Most of the time I'm just investigating if someone has
> written a module for a general purpose and then trying to install it.

I began such a distribution: GODI. It contains core O'Caml plus a number
of libraries that can be individually added or removed. However, it does
not contain _all_ libraries, just a subjective selection. (Hint:
Everybody is invited to express his or her subjective feelings about
important packages by just creating them.)

Here is the link:

http://ocaml-programming.de/godi/
    

int -> byte array (and back)

Dustin Sallings asked and Issac Trotts answered:
>       I need to be able to get a byte array (specifically in little-endian
> format) from an int.  I'll need the reverse as well.  Is there anything
> that does that in the distribution, or do I need to calculate it
> myself?  Just trying to do things the right way.

Here's a way to do it:

# open Bigarray;;
# #load "bigarray.cma";;
# let i=Random.int 1024;;
val i : int = 735
# let a_of_i i =
   let a=Array1.create int8_unsigned c_layout 4 in
   a.{0} <- i land 0xff;
   a.{1} <- (i lsr 8) land 0xff;
   a.{2} <- (i lsr 16) land 0xff;
   a.{3} <- (i lsr 24) land 0xff;
   a;;
val a_of_i :
  int ->
  (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t =
  <fun>
# let i_of_a a =
   a.{0} lor (a.{1} lsl 8) lor (a.{2} lsl 16) lor (a.{3} lsl 24);;
val i_of_a : (int, 'a, 'b) Bigarray.Array1.t -> int = <fun>
# let a = a_of_i i;;
val a :
  (int, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t =
  <abstr>
# a.{0},a.{1},a.{2},a.{3};;
- : int * int * int * int = (223, 2, 0, 0)
# i_of_a a;;
- : int = 735
    

Compiling a native code OCaml library into an .so?

Aleksey Nogin asked and Kamil Shakirov answered:
> I am wondering - is it possible to compile a native code OCaml library
> into an dynamic library (.so) and then link an OCaml program against it,
> or dynamically load it from an OCaml program?
>
> My (very shallow) understanding of how this is supposed to work suggests
> that it should not be too hard to implement (at least if we do not
> insist on detecting version mismatches at runtime). We would need:
>
> 1) A flag to ocamlopt that would tell it to compile to ".cmxa + .so"
> instead of ".cmxa + .a". Given such a flag, ocamlopt would
>    a) Create an assembly file defining _init function that would call
> the initialization functions of all the modules and add that file to the
> list of things to be compiled in.
>    b) Add -shared flag to the ld call.
>
> 2) When compiling a program with ocamlopt, if one of the arguments is a
> .cmxa, then look for both .a and .so and pass the right one to ld.
>
> 3) Have a function somewhere (Dynlink module?) that's a wrapper for the
> C's dlopen function.
>
> 4) Ideally - have a function somewhere (Dynlink module?) that would try
> loading a .cma when running in bytecode and would try loading an .so
> when running in native code.
>
> Am I missing any serious difficulties here? Are there any plans to add
> something like this to OCaml?

Look at the http://www.boblycat.org/~malc/scaml/
    

Inner workings of Caml compiler

Oleg Trott said and Christian Lindig answered:
> Things like this make me wonder how people outside of INRIA understand the
> inner workings of Caml compiler (enough to modify it). Just  guessing by
> looking at the rather sparcely commented source? Or is there anything else?

I once looked at the data structures in the ocamlopt back end. I'm not
sure my slides are useful without the talk, but here they are:

    http://www.st.cs.uni-sb.de/~lindig/talks/ocaml-02/slides.ps.gz
    

Parallel programming

Selentek asked and Yaron Minsky answered:
> Is where any libs for ocaml, for parallel programming ?
> or library for pass messages between processes and remote procedures calls?

Take a look at Xavier Leroy's bindings for MPI.  I've been using it
quite happily as a wrapper for lam, which is one of the open source MPI
implementations.

http://pauillac.inria.fr/~xleroy/software.html
    

Classes, objects, and class variables

Jacques Garrigue announced:
I'm in the process of improving the ocaml class system.
Principally the following two points:
1) making class creation cheaper.
   If you believed you could create classes in a "let module", and
   get away with it, you weere: it was prohibitively expensive in both
   time and space. Now I'm seeing 10000% speeups.
2) using this to make objects (or final classes) first class.
   Be able to write "let o = object (self) method m = ... end"
   Side advantage, there are no restrictions on polymorphism.

But in this process, I came along with the rather strange behaviour of
class variables. Class variables are defined by a let before any
parameters, for instance
  class c = let a = init () in fun ... -> object ... end
Their current semantics is to be evaluated repeatedly, once for c,
but again for all classes inheriting from c. The problem is that this
is costly for the implementation, doesn't fit well with the
possibility to create dynamically an arbitrary number of classes
inheriting from, and that I don't see what it's intended for.

So I'm planning to revert to the more intuitive semantics: evaluation
when creating c, but never again.

Does that bother anybody?
    

Any Java parser written in OCaml?

Peng Li asked and Eric Cooper answered:
> I am trying to do something with standard Java programs.  All I need
> is to parse Java programs, do some transformation with the AST, and
> pretty print it.
>
> I am tempted to use OCaml, but there would be too much overhead if I
> write everything from scratch.  Is there any publicly available OCaml
> code that I can use for parsing/pretty printing Java programs?

Here is a Java parser and pretty printer that I wrote in OCaml a
couple of years ago:

       http://www.cs.cmu.edu/~ecc/joust.tar.gz
    

Building large and portable projects

Martin Jambon asked and Jason Hickey answered:
>Is there a convenient way to develop OCaml code, and be sure that
>this code will be configurable, compilable, installable and
>executable without changes, on any environment where OCaml is available?

We have been using omake to build several large projects, primarily on
Linux and Windows.  omake is written in OCaml, and provides a build
system with syntax similar to make, but project-wide dependency
analysis.  Here are some features:

    - omake runs on Unix, Windows, MacOS, and presumably
      other architectures where OCaml is available.
    - dependency analysis is project-wide (like cons),
      based on MD5 digests
    - automated dependency analysis
    - there is builtin support for OCaml and C code,
      and it is easy to add support for other kinds
      of files (just like make).
    - the OMakefile syntax is similar to GNU make, but
        - omake has user-defined functions
        - OMakefile programs are functional
        - the .SUBDIRS target is used to define
          the project hierarchy
        - different parts of the project can have
          different configuration.

omake is available by anonynous CVS from cvs.metaprl.org.
   % cvs -d :pserver:anoncvs@cvs.metaprl.org:/cvsroot login
   The password is anoncvs.
   % cvs -d :pserver:anoncvs@cvs.metaprl.org:/cvsroot checkout omake

Alternatively, RPMs are available at rpm.nogin.org.

Here is a short description.  Every project must have an OMakeroot file
in the project root.  It is usually boilerplate; this is typical:

   # Include the standard configuration
   include $(STDROOT)

   # Include the OMakefile
   .SUBDIRS: .

The project commands are then placed in an OMakefile.  To build a
standalone OCaml program from files a.ml b.ml and c.ml, you just need
one line.  The OCamlProgram function is defined in the system OMakeroot.

   OCamlProgram(foo, a b c)

You can choose the byte-compiler, native-code compiler, or both.

   BYTE_ENABLED = true
   NATIVE_ENABLED = true
   OCamlProgram(foo, a b c)

Maybe you have some C files you need to include in your compile as well.
 Perhaps f.c is a generated file.

   f.c: f1.c f2.c
        cat $+ > $@
   StaticCLibrary(bar, d e f)
   LIBS = bar
   OCamlProgram(foo, a b c)

Perhaps you use the C-preprocessor on some .mlp files:

   %.ml: %.mlp
        $(CPP) $*.mlp > $@

The system sources contain more examples, and the MetaPRL system, also
available at cvs.metaprl.org, provides a very large, complex, example.
    

ocaml-i18n list

Yamagata Yoriyuki announced:
I made ocaml-i18n (internationalization) list in Yahoo groups.  The
purpose of the list is to discuss, coordinate and promote i18n of
ocaml, and to share idea, experience, and tips about use of ocaml in
i18n settings.

The list address is ocaml-i18n@yahoogroups.com  To subscribe, send a
message to ocaml-i18n-subscribe@yahoogroups.com

To reach the widest audience, English messages are preferable.  Other
languages are acceptable, if you add a short English summary to your
message.

(Disclaimer: this list is unrelated to the official ocaml team in
INRIA.)
    

ooowrite generates OpenOffice of StarOffice Writer .sxw files from OCaml programs

Richard Jones announced:
Merjis has released another of the internal libraries we've been
developing. 'OOoWrite' or 'ooowrite' lets you write OpenOffice or
StarOffice .sxw files from OCaml programs.  It's a little primitive at
the moment, but improved versions are on their way.

http://www.merjis.com/developers/ooowrite/
    

GD4O release 1.0a5

Matt Gushee announced:
I am pleased to announce the 5th alpha release of GD4O, the OCaml
wrapper for the GD graphics library. Today's release adds support for
the copying and resizing portion of the GD API, consisting of the
following functions:

    OCaml method name           C API function name
    -----------------           -------------------
    #image#copy             <-> gdImageCopy
    #image#copy_resized     <-> gdImageCopyResized
    #image#copy_resampled   <-> gdImageCopyResampled
    #image#copy_rotated     <-> gdImageCopyRotated
    #image#copy_merge       <-> gdImageCopyMerge
    #image#copy_merge_gray  <-> gdImageCopyMergeGray
    #image#palette_copy     <-> gdImagePaletteCopy

The test script has been updated accordingly.

The project home page, with download links and documentation, is:

    http://gd4o.sourceforge.net/


P.S.: Volunteer developers needed, especially those with expertise
      in interfacing OCaml with C! Please get in touch if you're
      interested.
    

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