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

Alan Schmitt alan.schmitt at polytechnique.org
Tue Sep 15 01:51:46 PDT 2009


Hello,

Here is the latest Caml Weekly News, for the week of September 08 to 15,
2009.

1) ocaml-fileutils v0.4.0
2) ocamlfind and GODI packaging sprint summary
3) Partially hiding modules in packages
4) polymorphic method.
5) A kind of syslog functionality
6) Ocamldoc and multiple packages
7) Other Caml News

========================================================================
1) ocaml-fileutils v0.4.0
Archive: <
http://groups.google.com/group/fa.caml/browse_thread/thread/e0e342415b599e51#
>
------------------------------------------------------------------------
** Sylvain Le Gall announced:

Ocaml fileutils is aimed to be a platform independent library to perform
operation on file like:
- mv
- cp
- rm
- mkdir
- touch
- which...

Comes also with a module to manipulate abstract filename:
- classification
- make_relative: made a filename relative to another
- make_absolute

This new release simplify module structure (nested modules are not
required anymore) and comes with a more clear documentation. It also
removes parser/lexer for path which was little bit overkilling. Some
operations have been optimized for speed (like find) -- coming close in
term of performance to standard POSIX commands.

Link:
<http://le-gall.net/sylvain+violaine/ocaml-fileutils.html>

========================================================================
2) ocamlfind and GODI packaging sprint summary
Archive: <
http://groups.google.com/group/fa.caml/browse_thread/thread/eddb07cf52acb357#
>
------------------------------------------------------------------------
** Hezekiah M. Carty announced:

The OCaml packaging sprint is now complete.  It was quite a success!

In total, seven packages were worked on today as part of this effort:

- cairo-ocaml
- bitstring
- mlpost
- ocamlgsl
- Deriving
- coThreads
- Uuidm

Out of these seven packages, the packaging efforts are in several states.

New package available in GODI:
- ocamlgsl

Ready for GODI, pending upload:
- bitstring
- Uuidm

Almost ready, requiring a bit more testing/tweaking:
- Cairo-OCaml
- mlpost

In progress:
- Deriving
- coThreads

So ocamlgsl is out there now and installable in GODI, with the other
packages hopefully following in the next few days.

You can read more, and find some ideas for libraries to package if you
are interested, at the wiki page:

<http://ocamlsprint.couch.it/ocamlfind_and_GODI_packaging>

Thanks to everyone who was involved in the packaging effort today!

========================================================================
3) Partially hiding modules in packages
Archive: <
http://groups.google.com/group/fa.caml/browse_thread/thread/3984117e6bb6129f#
>
------------------------------------------------------------------------
** Alexey Rodriguez asked:

My question is about how to hide modules (or parts thereof) in
an ocaml package from the outside world (users of the package).

I am trying to build an ocaml package with internal functionality
(types and functions)
that I do not want to expose. I have two modules in the package implemented
by
foo.ml and bar.ml. The structure of each .mli looks like this:

> module Foo = sig
>   type t
>   val make : t
>   val change : t -> t
>
>   (* Internal, not to be exposed. *)
>   val unsafe_change : t -> t
> end

> module Bar = sig
>   type t
>   val combine : t -> Foo.t -> t (* uses unsafe_change *)
> end

As you see Foo exports unsafe_change because Bar needs it.
I compile both modules using "-for-pack Foobar" and build them using
the "-pack" option.
However, now I want to hide "Foo.unsafe_change" from the package
"export list" (if there
is such a thing) so that main.ml cannot call it. I see the following
options:

* Merge foo.ml and bar.ml so that unsafe_change does not need to be exposed.
 I don't like this, the modules could be very large.
* Split Foo into Foo_internal and Foo, and somehow keep Foo_internal
 invisible. I don't know how to do this. I would use "exposed-modules" in
 Cabal which is a package manager for Haskell.
* Add the file foobar.mli which contains the signatures of Foo and Bar
but hiding
 Foo.unsafe_change. I think it could work, but I would have to repeat
much of the Foo
 and Bar interfaces. I tried this but it didn't work, ocaml complains
as follows:

> Error: The implementation (obtained by packing)
>        does not match the interface foobar.mli:
>        The field `Foo' is required but not provided

 I am attaching a tarball of this attempt in case someone knows what
went wrong.
 The example is a bit different from the example in the email.

So the question is:

 What solution do you follow when you want to hide (part of) a module
in a package?
 Keep in mind that the hidden parts should still be exposed to the
modules inside
 the package.

A related question is how to expose the representation Foo.t so that
Bar can manipulate it
directly, but at the same time keep it hidden from users of the
package. The following easy
hack works. Create foo_type.mli with the definition of the type t:

> type t = int

and redefine Foo as follows:

> module Foo = sig
>   type t = Foo_type.t
>   val make : t
>   val change : t -> t
>
>   (* Internal, not to be exposed. *)
>   val unsafe_change : t -> t
> end

Now "t" is visible for Bar to use but we still have to hide it from
the outside world. How do
we do it? Well, just use "-pack" on foo.cmx and bar.cmx. We can omit
Foo_types because it has
no .cmx. As a consequence Foo.t becomes abstract. This probably works
by accident and maybe it
is not a good idea to rely on this trick.

I would appreciate if you can share your experiences and perhaps point
to some ocaml library
that does module or partial module hiding so I can use it as an example.

** blue storm suggested:

The problem with your packages.tgz example is that you use "module
type Foo = .." in the .mli. This gives the signature of a module type,
that is, it refers to a _module type_ defined in the implementation
file.

What you want to do here is to give the signature of a _module_, not a
module types, so here is the correct syntax :

 module Foo : sig
   type foo_t

   val initial : foo_t
   val show : foo_t -> string
 end


Regarding your original problem, I've had the same needs and came up
with a slightly different solution : in order to avoid the additional
indirection level related to -pack (Foobar.Foo), is used a flattened
representation by adding a "foobar.ml" file containing only :

 include Foo

(and possibly include of other modules in the package). Then the
foobarl.mli is :

 type foo_t

 val initial : foo_t
 val show : foo_t -> string

And values can be referred with Foobar.foo, instead of Foobar.Foo.foo.
Of course this is only useful if you don't want the user to see the
internal module hierarchy, wich may not be what you had in mind.

** Alain Frisch also suggested:

It is not a well-known fact, but it is possible to provide an explicit
interface for the packaged module (just create an ad hoc foobar.mli and
compile it before doing the -pack'ing).

** Jean-Christophe Filliâtre also replied:

> My question is about how to hide modules (or parts thereof) in
> an ocaml package from the outside world (users of the package).
>
> * Add the file foobar.mli which contains the signatures of Foo and Bar
> but hiding
>   Foo.unsafe_change. I think it could work, but I would have to repeat
> much of the Foo
>   and Bar interfaces. I tried this but it didn't work, ocaml complains
> as follows:

That's the solution we followed in Mlpost (<http://mlpost.lri.fr/>) and it
works fine (you may have a look at the Makefile.in in mlpost sources).

Indeed, you have to repeat (parts of) the modules interfaces, but since
it is where we put all the ocamldoc documentation, in a single file, it
appears to be a satisfying solution.

========================================================================
4) polymorphic method.
Archive: <
http://groups.google.com/group/fa.caml/browse_thread/thread/1920b32e5a6091dd?pli=1
>
------------------------------------------------------------------------
** Guillaume Yziquel asked:

When developing with objects in OCaml, I'm quite often faced with
polymorphic
methods.

Such as:

class myobject = object
 method id x = x
end

Sometimes you have many methods that you're tinkling with, and the compiler
keeps saying to you that 'a is inbound in this class declaration.

I'm therefore wondering if it would be a good idea to have a keyword
'polymorphic', and one would write

class myobject = object
 polymorphic method id x = x
end

The polymorphic keyword would be a hint that the method is polymorphic and
that there is no need to look at the class' type parameters.

** Jacques Garrigue replied:

There are already polymorphic methods in ocaml.
The syntax for your example would be:

class myobject = object
 method id : 'a. 'a -> 'a = fun x -> x
end

A "polymorphic" keyword might seem simpler, but it would be complex to
handle the case where a polymorphic method type contains also class
parameters:

class ['a] cell (x : 'a) = object
 method pair : 'b. 'b -> 'a * 'b = fun y -> (x,y)
end

More generally, you might end up with types more polymorphic than you
expected, and since differently instantiated polymorphic method types
are incompatible, this would be a problem.

** Guillaume Yziquel then asked and Jacques Garrigue replied:

> By the way, I do not exactly understand the "you might end up with
> types more polymorphic than you expected" part.

This is actually the main problem.
At some point, I actually considered generating automatically
polymorphic method types where possible.
The idea would be simply to first give all the methods in a class
monomorphic types (to avoid the undecidability of polymorphic recursion),
and then generalize all type variables that do not "escape": i.e. do
not appear in class parameters, value fields, or global references.
Technically this is perfectly doable.
Theoretically, there are problems with principality, as there is no
most generic type for a polymorphic method (all types are incompatible
with each other).
It is easier to see that on a practical example.
Say that I defined lists:

class ['a] cons x l = object (_ : 'self)
 method hd : 'a = x
 method tl : 'self = l
end

class nil = object
 method hd = raise Empty
 method tl = raise Empty
end

Now, both cons and nil would be typable (cons is already typable), and
the inferred types would be:
class ['a] cons : 'a -> 'b ->
 object ('b) method hd : 'a method tl : 'b end

class nil : object
 method hd : 'a
 method tl : 'b
end

At first glance, it seems that the type of nil being completely
polymorphic, we could pass it as second argument to cons.
However, it is not the case. cons has two monomorphic methods, while
nil has two polymorhic methods, and their types are incomparable.
If we look at object types,

type 'a cons = < hd : 'a; tl : 'b > as 'b
type nil = < hd : 'a.'a ; tl : 'b.'b >

Of course, you could argue that what is wrong is the definition of
nil. But basically there is no way to decide what is the right type
for nil as soon as we allow inferring polymorphic methods.

Interestingly, currently you can define nil as an immediate object
and have immediately the right type without any annotation:

exception Empty
let nil = object
 method hd = raise Empty
 method tl = raise Empty
end ;;
val nil : < hd : 'a; tl : 'b > = <obj>

let l = new cons 3 nil ;;
val l : int cons = <obj>

So, the current approach is to privilege the monomorphic case,
requiring type annotations for the polymorphic case. Your suggestion
of allowing to give a hint that you want a polymorphic type makes
sense, but it does not say which polymorphic type: there might be
several, with different levels of polymorphism, with no way to choose
between them. Probably it would be ok to choose the most polymorphic
one, but one can always find counter-examples. So the meaning of your
"polymorphic" keyword would be: "give me the most polymorphic type for
this method, I hope I understand what it will be, but if I'm wrong and
it breaks my program I won't complain". This may be practically ok,
but this is a hard sell as a language feature. Particularly when you
think that future versions of the compiler may be able to infer more
polymorphic types, thanks to improvements in type inference, and
suddenly break your program.

** The editor says:

There were many replies to this thread with more technical discussion.
Please
follow the archive link above if you want to read them.

========================================================================
5) A kind of syslog functionality
Archive: <
http://groups.google.com/group/fa.caml/browse_thread/thread/4d1a0128632e53bf#
>
------------------------------------------------------------------------
** Michaël Grünewald asked and Stéphane Glondu replied:

> I am looking for a way to gather the messages coming from various modules
of a
> program and selectively dispatch them to STDERR, a log file, or whatever.
>
> A module processing the messages in a manner similar to the `syslog' found
on
> UNIX systems would be nice.

There is an implementation of the syslog protocol itself in OCaml:

 <http://homepage.mac.com/letaris/>

It is also available as package in Debian (and Ubuntu).

========================================================================
6) Ocamldoc and multiple packages
Archive: <
http://groups.google.com/group/fa.caml/browse_thread/thread/abfe4d4da5da3c9d#
>
------------------------------------------------------------------------
** Alexey Rodriguez asked:

I am trying to build ocamldoc documentation for an ocaml project that
contains multiple packages (collections of modules built using
-for-pack and -pack). My current setup generates documentation for
each package but it won't generate hyperlinks to modules in other
packages (module not found errors). I tried using the -load and -dump
commands to allow ocamldoc see the ocamldoc-results of the referred to
package, but I still get problems. I suspect that the problem arises
because ocamldoc does not have a -pack option, so it always sees
modules in a flat way. So if you have package Pack1 with module A, and
module B in Pack2 which refers to Pack1.A.t, ocamldoc cannot solve
this reference because it does not know that module A is inside
another module called Pack1.

The solutions I see right now seem to involve more effort than I am
willing to spend. So, before I embark on a task that might take too
long I would like to ask for tips on this. How do you perform ocamldoc
generation for projects with multiple packages? Thanks!

** Bertrand Jeannet suggested:

I wrote very recently a small script that packs source modules into a big
module, and takes care of ocamldoc convention, which is to interpret in each
file the first (** *) comment as the title associated to the module.

I am very bad at sh and gawk script, so the result (given below) is not very
elegant...

It would of course be better (and much more robust) to have a direct support
in ocamldoc.

Bertrand

-----------

#/bin/sh

# command line (very primitive...)
if test $1 != "-o"; then
   echo "ocamlpack: usage: ocamlpack -o outputmodule -title <str> module1
module2 ..."
   exit -1
fi
shift
out=$1
shift
if test $1 != "-title"; then
   echo "ocamlpack: usage: ocamlpack -o outputmodule -title <str> module1
module2 ..."
   exit -1
fi
shift
outtitle=$1
shift

# prepare output
/bin/rm -f $out.ml $out.mli
echo "(** $outtitle *)">$out.ml
echo "(** $outtitle *)">$out.mli

# iterate on input module,
for i in $*; do
   name=$i
# 1.A Look for the first (** *) comment, and output it to out.ml
# (see ocamldoc convention)
   gawk -v name=$name '
BEGIN {
 start=1
 # isolate module name from path/modulename
 nb = split(name, dirname, "/")
 name = dirname[nb]
 if (RLENGTH>0)
   name = substr(name,RINDEX,length(name)-RINDEX)
 # Capitalize the module name
 hd = toupper(substr(name,1,1))
 tl = substr(name,2,length(name)-1)
}
# Look for the first (** *) comment, and output it
{
 if (start==1) {
   match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
   if (RLENGTH>0){
     start=0
     title=substr($0,RSTART+4,RLENGTH-7)
     print "\n(** {1 Module [",hd tl "]:",title "} *)\n"
     print "module",hd tl,"= struct"
   }
 }
}
END {
 if (start==1) {
   print "\n(** {1 Module [",hd tl "]} *)\n"
   print "module",hd tl,"= struct"
 }
}
'       $i.ml >>$out.ml
# 1.B Output the rest of name.ml to out.ml
       gawk -v name=$name '
{
 if (start==1) {
   match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
   if (RLENGTH>0)
     start=0
   else
     print $0
 }
 else
   print " ",$0
}
END { print "end\n" }
'       $i.ml >>$out.ml

# 2.A Look for the first (** *) comment, and output it to out.mli
   gawk -v name=$name '
BEGIN {
 start=1
 nb = split(name, dirname, "/")
 name = dirname[nb]
 if (RLENGTH>0)
   name = substr(name,RINDEX,length(name)-RINDEX)
 hd = toupper(substr(name,1,1))
 tl = substr(name,2,length(name)-1)
}
{
 if (start==1) {
   match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
   if (RLENGTH>0){
     start=0
     title=substr($0,RSTART+4,RLENGTH-7)
     print "\n(** {1 Module [",hd tl "]:",title "} *)\n"
     print "module",hd tl,": sig"
   }
 }
}
END {
 if (start==1) {
   print "\n(** {1 Module [",hd tl "]} *)\n"
   print "module",hd tl,": sig"
 }
}
'       $i.mli >>$out.mli
# 2.B Output the rest of name.mli to out.mli
       gawk -v name=$name '
{
 if (start==1) {
   match($0, /\(\*\*([ ]+)([^*]*)([ ]+)\*\)/ )
   if (RLENGTH>0)
     start=0
   else
     print $0
 }
 else
   print " ",$0
}
END { print "end\n" }
'       $i.mli >>$out.mli
done

========================================================================
7) Other Caml News
------------------------------------------------------------------------
** From the ocamlcore planet blog:

Thanks to Alp Mestan, we now include in the Caml Weekly News the links to
the
recent posts from the ocamlcore planet blog at <http://planet.ocamlcore.org/
>.

FileUtils 0.4.0:
  <http://caml.inria.fr/cgi-bin/hump.cgi?contrib=249>

ocaml-dbf:
  <http://forge.ocamlcore.org/projects/ocaml-dbf/>

Melt 1.2.0:
  <http://forge.ocamlcore.org/forum/forum.php?forum_id=413>

Constructive gem: juggling exponentials:
  <http://math.andrej.com/2009/09/09/constructive-gem-juggling-exponentials/
>

Constructive stone: minima of sets of natural numbers:
  <
http://math.andrej.com/2009/09/08/constructive-stone-minima-of-sets-of-natural-numbers/
>

========================================================================
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://alan.petitepomme.net/cwn/>) or the RSS feed of the
archives (<http://alan.petitepomme.net/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/> .

========================================================================
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20090915/ec9028e5/attachment-0001.html 


More information about the caml-news-weekly mailing list