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

Alan Schmitt alan.schmitt at polytechnique.org
Tue Jan 24 00:25:21 PST 2006


Hello,

Here is the latest Caml Weekly News, for the week of 17 to 24  
January, 2006.

1) GODI news
2) Constraints in module types
3) C interface style question
4) C-Interface: CAMLreturn and failwith
5) toplevel with pre-installed printers
6) Again C-Interface: caml_alloc_custom
7) Camlmix 1.3: OCaml-stuffed templates
8) Announcing OMake 0.9.6.8

========================================================================
1) GODI news
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/31976>
------------------------------------------------------------------------
** Gerd Stolpmann announced:

Welcome to GODI news, the newsletter that informs you about updates of
GODI, the source-based O'Caml distribution.

------------------------------------------------------------
TABLE OF CONTENTS:

1. GODI releases O'Caml 3.09.1
2. Where to find more information about GODI
------------------------------------------------------------

1. GODI RELEASES O'CAML 3.09.1

The project has just released the package repository for O'Caml 3.09.1.
This is the first released version for the "3.09" branch of the
distribution.

The "3.08" branch of GODI is still supported. The "3.07" branch is
discontinued.

Existing installations of GODI can be easily upgraded. To do so, you
should edit the file godi.conf and set

GODI_SECTION = 3.09

(it was formerly 3.08). The next step is to upgrade the GODI packages
using the standard mechanism. This works in an almost fully automatic
way, GODI takes care not to only build the new O'Caml base but also
rebuilds all dependent libraries. Although well tested, it is
recommended to save a copy of the old installation before trying the
update.

To start the update, invoke godi_console in interactive mode, and do:

- Update the list of packages
- Go into the menu where one can select the packages. Press 'u'
   to upgrade the packages, and confirm with 'o'. Start the installation
   as usual.
- Enjoy the updated installation

It is also possible to do the same from the command-line:

$ godi_console update
$ godi_console wish -rebuild
$ godi_console perform -wishes -newer
$ godi_console wish -reset

Alternatively, you can also bootstrap a new GODI installation, e.g. in
parallel of the existing installation for 3.08. There is a new bootstrap
tarball at

<http://www.ocaml-programming.de/packages/godi- 
bootstrap-20060118.tar.gz>

defaulting to the 3.09 release.

2. WHERE TO FIND MORE INFORMATION ABOUT GODI

GODI is a source-based O'Caml distribution. It consists of a framework
that automatically builds the O'Caml core system, and additionally
installs a growing number of pre-packaged libraries. GODI is available
for O'Caml-3.08 and 3.09. It runs on Linux, Solaris, FreeBSD, NetBSD,
Cygwin, HP-UX, MacOS X.

Advantages of using GODI:

       * Automatic installation of new libraries: GODI knows where a
         library can be downloaded, which prerequisites are needed to
         build it, and which commands must be invoked to compile and
         install it
       * Complete package management of the installation: A library is
         installed as a package (a managed set of files), so it is
         possible to remove it later without any hassle.
       * GODI implements the necessary logic to upgrade installations:
         Because of the way O'Caml works, all dependent libraries  
must be
         recompiled if a library is upgraded to a newer version. GODI
         automates this process.
       * Integration with the operating system: If additional C  
libraries
         are needed to build an O'Caml library, and the operating system
         includes them, they will usually be automatically found and
         used. Non-standard locations can be configured (there is only
         one configuration file for the whole installation).
       * GODI has a menu-based user interface that makes it simple to  
use
         even for beginners.
       * GODI tries to standardize the directory layout of library
         installations, so it becomes simpler to find files of interest.

GODI currently supports 75 add-on libraries and 15 applications written
in O'Caml.

Read more on the GODI homepage: <http://godi.ocaml-programming.de>

========================================================================
2) Constraints in module types
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/31981>
------------------------------------------------------------------------
** Alessandro Baretta asked and Jacques Garrigue answered:

 > # type foo = [ `Foo of foo ];;
 > type foo = [ `Foo of foo ]
 > # module type BAR = sig type bar constraint bar = [ > foo ] end;;
 > The type constraints are not consistent.
 > Type bar is not compatible with type [> foo ]
 >
 > Is there a good reason for prohibiting the above declarations?  
Could I achieve a
 > similar effect with private row types?

Not a "similar" effect, as the meaning of the above code is: define an
abstract type bar, and check that this abstract type is unifiable with
[> foo] (by definition impossible, so this might just be a syntax
error...)

On the other hand

   module type BAR = sig type bar = private [> foo] end

means "require the type bar to be an instance of type [> foo]".
I suppose this is what you intended?

========================================================================
3) C interface style question
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/31971>
------------------------------------------------------------------------
** Thomas Fischbacher asked and Jacques Garrigue answered:

 > value-type parameters to C functions exported to OCaml should be
 > registered with CAMLparamX(...). Does this hold in general, or is it
 > considered acceptable/appropriate to just ignore this for "immediate"
 > values that do not hold pointers, but, say, int, bool etc. values?

Registration is required to have the GC properly update the values.
The GC may be called by any allocation.
So it is only safe not to register a parameter (or a variable) in any
of the following 4 cases.
1) you know that it can only hold a non-pointer value (int, bool, ...)
    (i.e. the GC has nothing to update)
2) there are no allocations in your function
3) the parameter is not accessed after the first allocation
4) for a new variable whose contents is returned, there is no
    allocation between the setting of the variable and return.

(1) and (2) are relatively easy to see, but (3) and (4) are a bit
trickier (particularly with side-effecting expressions), so
it is not a bad idea to register more parameters than strictly
necessary.

** John Skaller said and Damien Doligez answered:

 > Unless I'm mistaken, 'registration' with these macros
 > is never required: these macros are simply a high level
 > abstraction layer providing convenience and relative safety.
 >
 > The Ocaml manual explains all this fairly well IMHO,
 > the low level interface is well documented, Hendrik Tews
 > version is cool:
 >
 > <http://wwwtcs.inf.tu-dresden.de/~tews/htmlman-3.09/manual032.html>
 >
 > See 18.5.2 -- IMHO the low level interface, whilst requiring
 > more work to apply, is actually easier to understand.
 >
 > Just one 'BTW': I have seen some code using Field() macro
 > with incorrect C. You must NOT do this:
 >
 > 	MyType *p = ...
 > 	(MyType*)Field(v,n) = p;
 >
 > it isn't valid ISO C for *any* type MyType (not even 'value').

Indeed.  My K&R explicitely says: "a cast does not yield an l-value".

 > You would have to do it like this:
 >
 > 	*(MyType**)(void*)&Field(v,n) = p; // **

You should only do this if you want strange GC bugs and random
crashes, because you are walking around the write barrier and
that's a bad idea.

 > However I strongly recommend instead
 >
 > 	StoreField(v,n,(value)(void*)p);
 >

This is the only way.  Always use Store_field, Store_double_field,
and Store_double_val.

 > The incorrect usage was not detected by older versions of gcc.
 > Gcc 4.x does detect this error. The workaround (**) is
 > the ONLY correct way to cast an lvalue in ISO C. This problem
 > arises in some larger codes where a macro has been used
 > to do the type conversion .. and it appeared to work
 > but was in fact invalid C. For example:
 >
 > 	#define MyThing(v) (MyType*)Field(v,2)
 >
 > is not a good idea, since
 >
 > 	MyThing(v) = ...
 >
 > is invalid ISO C but may not even produce a warning. You would
 > have to instead say:
 >
 > 	#define MyThing(v) (*(MyType**)(void*)&Field(v,2))
 >
 > but it seems better to rewrite your code so values and
 > lvalues are distinguished by usage (eg 'get' and 'set' macros).
 > [The intention of the macros is usually to abstract away the
 > field number]

** Thomas Fischbacher said and Damien Doligez answered:

 > > Registration is required to have the GC properly update the values.
 > > The GC may be called by any allocation.
 >
 > Just by allocations in the local C code? Is this (and will this  
always
 > be) a guaranteed property? How about future extensions and
 > multithreading?

Any allocation performed during the execution of your code.  Including
context switches and signals, if you're doing begin_blocking_section.

 > > So it is only safe not to register a parameter (or a variable)  
in any
 > > of the following 4 cases.
 > > 1) you know that it can only hold a non-pointer value (int,
 > > bool, ...)
 > >    (i.e. the GC has nothing to update)
 > > 2) there are no allocations in your function
 > > 3) the parameter is not accessed after the first allocation
 > > 4) for a new variable whose contents is returned, there is no
 > >    allocation between the setting of the variable and return.
 > >
 > > [...]
 >
 > Can I take this as an official position of the OCaml team on the
 > behaviour
 > of the C interface?

The official position is: none of these is guaranteed to hold in future
releases.  You should play it safe and register all your local
variables.

If you really need all the speed you can get, you might use these tricks
in the two functions where your program spends all its time, but I'd
still advise against it.

** Thomas Fischbacher asked, Olivier Andrieu answered, and Damien  
Doligez said:

 > > One more question about this: can I interface a C function in such
 > > a way that it uses an OCaml float array to store its output data,
 > > i.e. pass &(Double_field(ml_output,0)) as a double* "output
 > > parameter"?
 >
 > You can only do this on platform that accept doubles aligned on word
 > boundaries (such as x86). On those platforms, OCaml's config.h
 > undefines ARCH_ALIGN_DOUBLE. So your code might look like this :
 >
 > ,----
 > |   double *c_array;
 > | #ifdef ARCH_ALIGN_DOUBLE
 > |   c_array = /* allocate temporary storage and copy the caml float
 > array */
 > | #else
 > |   c_array = (double *) ml_array;
 > | #endif
 > |
 > |   /* use c_array */
 > |
 > | #ifdef ARCH_ALIGN_DOUBLE
 > |   free (c_array);
 > | #endif
 > `----

This is correct, except for the way you get the pointer.  You should
do it
properly with &(Double_field(ml_array,0)).  There is no guarantee that
the value ml_array points to the first element of the array.

Thomas wanted an "out" parameter, and the above code is for an "in"
parameter, but it should work if you make the obvious changes.

Thomas Fischbacher wrote:

 > Is it (= will it always be) permissible to nest Field / Store_field
 > macros?

If you are not doing some strange things, the Store_field will always
be outermost, and some Fields will be nested inside it.  In that case,
it is safe.  Otherwise, you're using C macros with arguments that have
side-effects, and your program will never work anyway :)

========================================================================
4) C-Interface: CAMLreturn and failwith
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/32012>
------------------------------------------------------------------------
** Christoph Bauer asked and Damien Doligez answered:

 > a question related to CAMLreturn and failwith in C-Stubcode:
 >
 > Is this code correct:
 >
 > #include <fail.h>
 > ...
 >
 > CAMLprim value prim( value unit )
 > {
 >    CAMLparam0();
 >    CAMLlocal( result );
 >    int error;
 >    /* allocate result, error has an errorcode */
 >    if( error ) failwith( "error");
 >    else CAMLreturn( result );
 > }
 >
 > or should it be
 >
 > CAMLprim value prim( value unit )
 > {
 >    CAMLparam0();
 >    CAMLlocal( result );
 >    int error;
 >    /* allocate result, error has an errorcode */
 >    if( error ) {
 >       caml_local_roots = caml__frame;
 >       failwith( "error");
 >    }
 >    else CAMLreturn( result );
 > }

The first one is correct: failwith will take care of deregistering
the local roots (actually, the bytecode interpreter does it when
failwith longjumps to the exception handler).

The second one should work in the current implementation, but it
may break in the future.

========================================================================
5) toplevel with pre-installed printers
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/31993>
------------------------------------------------------------------------
** Andrej Bauer asked and Jean-Christophe Filliatre answered:

 > This seems like a trivial question, but I do not know the answer:
 > how do I create either a toplevel (or a shell script which appears  
to be
 > a toplevel) with pre-installed pretty-printers (and pre-opened  
modules,
 > for that matter)?

I learnt a trick to do that from David Monniaux's GMP interface.

First define  your pretty-printers using the Ocaml  module Format. For
instance, the GMP pretty-printers look like

== gmp_pp.ml =========================================================
open Gmp
open Format
let z z = print_string (Z.string_from z)
let q q = ...
======================================================================

then introduce another file installing the pretty-printers:

== install_gmp_pp.ml =================================================
(* This is a hack to install the pretty-printers in the customized  
toplevel. *)

(* Caml longidents. *)
type t =
   | Lident of string
   | Ldot of t * string
   | Lapply of t * t

let _ = Topdirs.dir_directory "+creal"

let _ = Topdirs.dir_install_printer Format.std_formatter
	  (Obj.magic (Ldot (Lident "Gmp_pp", "z")) : 'a)

let _ = Topdirs.dir_install_printer Format.std_formatter
	  (Obj.magic (Ldot (Lident "Gmp_pp", "q")) : 'a)
======================================================================

Finally,  build your  ocaml toplevel  the usual  way, linking  the two
files above:

======================================================================
ocamlgmp: gmp.cma gmp_pp.cmo install_gmp_pp.cmo
	ocamlmktop -custom -o $@ $^
======================================================================

I know  this is a  hack (the infamous  Obj.magic is used and  the Caml
longident  type could change  in a  next ocaml  version) but  it works
fine.

** Gerd Stolpmann added:

 > First define  your pretty-printers using the Ocaml  module Format.  
For
 > instance, the GMP pretty-printers look like

In Ocamlnet, we use a similar trick, but get around Obj.magic:

let exec s =
   let l = Lexing.from_string s in
   let ph = !Toploop.parse_toplevel_phrase l in
   assert(Toploop.execute_phrase false Format.err_formatter ph)
;;

exec "#install_printer Mimestring.print_s_param;;";;
exec "#install_printer Neturl.print_url;;";;
exec "#install_printer Netbuffer.print_buffer;;";;
exec "#install_printer Netstream.print_in_obj_stream;;";;

This module can be simply compiled to bytecode and can be loaded into
the toplevel. As we are using findlib, a second trick automates this. In
META we have

archive(byte,toploop) =
     "netstring.cma netstring_top.cmo"

where netstring.cma contains the generic code and netstring_top.cma the
toplevel-specific code. So when the user types #require "netstring" the
toplevel printers are automatically available.

** code17 also suggested:

       I recently worked on a problem about customized toplevel. I  
need a
generic toplevel with various kinds of preloaded modules and open them
beforehand. So I can't produce these toplevels statically using
ocamlmktop, I have to launch them with various configurations on the
fly. Maybe this is also your situation. Here are some results I've got
(especially from the beginner's list, hi Richard Jones :)

Case 1:
   Suppose your requirement is quite simple: pre-load variant modules,
   open them, execute some evaluations and primitives without showing  
the
   feedback ... and you don't have to do complex interpretation between
   the user input as well as feedback from the real ocaml toplevel.

   You would probably like to use the undocumented(why?) option "-init",
   then wrap your executable as a shell script or programs. Use it  
like the
   default .ocamlinit except now you can indicate who is the script for
   initialization. E.g.

   <code>
   tmp/init.ml:

   # load "bigarray.cma";;
   open Bigarray.Genarray;;
   (* You may even delete it after execution, maybe dangerous *)
   Sys.command "rm tmp/init.ml";;
   </code>

   <command>
   ocaml -init tmp/init.ml
   </command>

   <toplevel>
             Objective Caml version 3.09.0

   # create;;
   - : ('a, 'b) Bigarray.kind ->
       'c Bigarray.layout -> int array -> ('a, 'b, 'c)  
Bigarray.Genarray.t
   = <fun>
   #
   </toplevel>

   Obviously you can have different configuration for different  
toplevels
   you want, and even produce the configuration on the fly.

Case 2:
   If you want to do complex interpretation between your user and the
   real ocaml toplevel, e.g. you want "My own topleve" instead of
   "Objective Caml version 3.09" showing at the beginning, you want to
   interpret the user's input secretly before feeding them to the
   toplevel (maybe camlp4 help to do anything possible here?) and  
hide or
   modify feedback from ocaml (maybe personalized pretty printer can
   solve any problem here?).

   Either you are quite familiar with toplevel source and hack by
   yourself, or like me really provide a program acting as translator,
   i.e. another process active between user and the background running
   toplevel. Then you can do anything as you want. I've done so, and  
wish
   to provide some of the generic functionality as library when I've got
   time to clean my code.

========================================================================
6) Again C-Interface: caml_alloc_custom
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/32016>
------------------------------------------------------------------------
** Christoph Bauer asked and Olivier Andrieu answered:

  > Could be here a problem (CAMLparam+CAMLreturn in C-called function):
  >
  > static value copy_tcl_array(int objc,  Tcl_Obj * const * objv)
  > {
  >   CAMLparam0 ();
  >   CAMLlocal2 (result, t);
  >   int n;
  >
  >   result = Val_int(0);
  >   for (n = objc-1; n >= 0; --n) {
  >     t = caml_alloc_small(2,0);
  >     Field(t, 0) = alloc_tcl_obj( objv[n] );
                      ^^^^^^^^^^^^^

I guess alloc_tcl_obj creates the custom block. That's wrong because
the block t you've just allocated with caml_alloc_small is not
completely initialized yet.

Either do this (safe, higher-level way):
,----
|   t = caml_alloc (2, 0);
|   Store_field (t, 0, alloc_tcl_obj (objv[n]));
|   Store_field (t, 1, result);
`----

or that (lower-level) :
,----
|   CAMLlocal1(obj);
|   obj = alloc_tcl_obj (objv[n]);
|   t = caml_alloc_small (2, 0);
|   Field (t, 0) = obj;
|   Field (t, 1) = result;
`----

========================================================================
7) Camlmix 1.3: OCaml-stuffed templates
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/32036>
------------------------------------------------------------------------
** Martin Jambon announced:

I would like to announce the latest version of Camlmix, since it  
provides
a few features that make it useful in a broader range of applications
than before. It now includes applications that serve web pages with
dynamic contents.

Camlmix is a template processor, which converts text containing
embedded OCaml into an OCaml program with embedded text.

Example:
    This is ocaml version ## print Sys.ocaml_version ##
    This is ocaml version ##= Sys.ocaml_version ##
becomes after execution:
    This is ocaml version 3.09.1
    This is ocaml version 3.09.1

The main novelty is that a template can now be converted into a
regular OCaml source file which provides a "render" function instead of
simply executing toplevel expressions when the module is initialized.
The resulting module can be compiled and included into any OCaml  
program,
and can take advantage of the numerous libraries that are now available
for OCaml, including syntax extensions.

Camlmix 1.3.0 can be installed from GODI or downloaded from its home at

    <http://martin.jambon.free.fr/camlmix>

========================================================================
8) Announcing OMake 0.9.6.8
Archive: <http://thread.gmane.org/gmane.comp.lang.caml.general/32047>
------------------------------------------------------------------------
** Aleksey Nogin announced:

We are proud to announce the latest release of the OMake Build System -
OMake version 0.9.6.8.

OMake is a build system, similar to GNU make, but with many additional
features. The home site for OMake is <http://omake.metaprl.org/> . OMake
features include:

    o Support for 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, scriptable dependency analysis using
      MD5 digests.

    o Portability: omake provides a uniform interface on Win32, Cygwin,
      and Unix systems including Linux and 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 files at once.

    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.

OMake preserves the style of syntax and rule definitions used in
Makefiles, making it easy to port your project to omake.  There is no
need to code in perl (cons), or Python (scons).  However, there are a
few things to keep in mind:

    1. Indentation is significant, but tabs are not required.
    2. The omake language is functional: functions are first-class
       and there are no side-effects apart from I/O.
    3. Scoping is dynamic.

OMake is licensed under a mixture of the GNU GPL license (OMake engine
itself) and the MIT-like license (default configuration files).

OMake version 0.9.6.8 in minor bugfixes/feature enhancements release.
The changes in this version include:

   - Fixed a bug in PATH-expansion for pipelines.
   - Improved the handling of the ".PHONY" nodes.
   - Added a remove-project-directories function.
   - Documentation fixes.
   - A few other bugfixes and improvements.

For a more verbose change log, please visit
<http://omake.metaprl.org/changelog.html#0.9.6.8> .

Source and binary packages of OMake 0.9.6.8 may be downloaded from
<http://omake.metaprl.org/download.html> . In addition, OMake may be
obtained via the GODI packaging system (release lines "3.08", "3.09" and
"dev").

To try it out, run the command "omake --install" in a project directory,
and modify the generated OMakefile.

OMake 0.9.6.8 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:// 
bugzilla.metaprl.org/>

========================================================================
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, you may subscribe online at
<http://lists.idyll.org/listinfo/caml-news-weekly/> .

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

Alan Schmitt, <http://sardes.inrialpes.fr/~aschmitt/>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: PGP.sig
Type: application/pgp-signature
Size: 186 bytes
Desc: This is a digitally signed message part
Url : http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20060124/dc544981/PGP.bin


More information about the caml-news-weekly mailing list