Previous week Up Next week

Hello

Here is the latest Caml Weekly News, for the week of 14 to 21 December, 2004.

  1. Apache 2 and mod_ocaml
  2. Possibility of Nested Classes and Nested Inheritance?
  3. Dummy polymorphic constructors
  4. GC, Anonymous Functions, and C
  5. OCaml 3.08.2 with TclTkAqua on OS X
  6. ocaml-ssl 0.2.0: bindings to the SSL library

Apache 2 and mod_ocaml

Archive: http://caml.inria.fr/archives/200412/msg00185.html

Joe Polanik asked and Richard Jones answered:
> Is there a version of mod_ocaml for Apache 2? If so, where might this be 
> found?

mod_caml or mod_ocaml?  The two are different things.  My summary of
the situation is here:

http://caml.inria.fr/archives/200410/msg00026.html

You need to patch Apache 2 to run mod_caml.  See these instructions:

http://merjis.com/developers/mod_caml/apache_2.0
http://issues.apache.org/bugzilla/show_bug.cgi?id=27550

The process of getting the required patch into Apache 2.x is glacial,
but at least the developers are now showing some small amount of
interest.
    
Peter Busser asked and Gerd Stolpmann answered:
> Has anyone looked at getting mod_lisp to work with OCaml? It's
> different from  mod_caml in that it doesn't execute OCaml code in
> Apache itself, but connects  to a separate process, which handles the
> request. Much like the way in which  Java servlet support for Apache
> works. It doesn't transfer any LISP specific  stuff according to the
> docs.

There is support for AJP (the Java connector you mention) and FastCGI in
Ocamlnet (http://ocamlnet.sourceforge.net). The O'Caml code runs in a
separate process, with all advantages, e.g. native code support, increased
stability etc.
    
Alex Baretta said, Richard Jones answered, and Alex Baretta replied:
> > The trouble is that FastCGI seems to be no longer actively developed, 
> > and it hardly supports Apache2.
> 
> 
> Oacmlnet supports JServ too, IIRC.

Gerd has managed to write in Ocaml every possible computable function, 
so, yes, he does support Jserv. Again, the problem is elsewhere. The 
Jakarta project no longer supports the Jserv protocol version 
implemented by Gerd. Gerd is not updating the Jserv support, if I recall 
correctly, because the new protocol version lacks support for some of 
the CGI features Ocamlnet needs.
    
Gerd Stolpmann answered:
> Gerd is not updating the Jserv support, if I
> recall  correctly, because the new protocol version lacks support for
> some of  the CGI features Ocamlnet needs.

No, there is not such a problem.

Currently, ocamlnet implements version 1.2 of the protocol, which is
widely available, even in the newest releases of Jakarta. Although this is
not the recommended protocol version.
I would really like to upgrade to version 1.3, because it fixes some
problems of 1.2 for SSL connections. Newer versions of the protocol (than
1.3) are experimental and not yet stable, and it is the question what one
really gains from them.
    
Peter Busser said, Richard Jones answered, and Alex Baretta said:
> > According to the documentation, mod_lisp uses a simpler protocol than JServ. 
> > It consists of attributename/value pairs.
> > http://www.fractalconcept.com/asp/1pY2/sdataQIjjZGSY-q5ODM==/2pY2sdataQoBh-N3qe0jUC1B=
> 
> I never really understood why people don't just use HTTP.  It is,
> after all, a perfectly suitable protocol for transfering web requests
> and web pages between entities :-)

This is what we are doing with the xcamld. Xcamld is a light-weigh http 
server working behind the scenes of a full-fledged server like Apache, 
which has support for proxying a request to another server. The client 
connects to Apache via HTTP; Apache is configured to act as a 
transparent proxy for this request and relays it to the xcamld. We 
already have a complete implementation of the HTTP 1.1 protocol and are 
currently working on the Ocamlnet bindings.
    
Christoph Bauer said:
BTW, there is another binding of FastCGI for OCaml. It uses the
C-Library, works under windows and could be used with threads.
In fact, it is only tested on windows. A binary version is included
in OCaml-Mingw-Maxi. If somebody really need it, I could release the
source.
    

Possibility of Nested Classes and Nested Inheritance?

Archive: http://caml.inria.fr/archives/200412/msg00195.html

Jørgen Hermanrud Fjeld:
I just read about the work by Nystrom, Chong and Myers on nested
inheritance, specifically the article "Scalable Extensibility via Nested
Inheritance".

The article does demonstrate fascinating, to me, use of inheritance, and
I wonder if it is possible to do something similar and object-oriented in OCaml.

To do something similar would, according to my understanding, require
both inner classes and super-class polymorphism.
In understand inner classes as implicitly polymorphic with respect to the enclosing class,
and polymorphism on the super class as the practical ability to extend
the type hierarchy upwards.

Do you know of any work that relate nested inheritance to OCaml, or that
address the similar issuesof inner classes and super-class polymorphism?

I have tried to search the mailing list history, but I have not
found relevant threads for these issues.

It seems to me that inner classes can always be written as parametric
classes, which means that OCaml could easily support inner classes. 
Is this correct? Are there other intrinsic reasons why OCaml does not
have inner classes, except of course that it would take an effort to
implement, which I understand.

Super-class polymorphism seems like a different beast, and I would very
much appreciate any ideas, especially theoretical ideas, on how that 
would interact with the OCaml type system.

I imagine the following OCaml'ish example:
class a =
    class b = object ... end
    class c = object inherit b ... end
    object
    ...
end

class d =
    class b' = object inherit b ... end
    (* The following is implicit
    class c' = object inherit b inherit b'  inherit c ... end *)
    object
      inherit a
      ...
end

The inner classes are parametrised by the outer class, thus for the
class a this could be written instead:

class a =
    object
    ...
end
class ['a] b = object ... end
class ['a] c = object inherit ['a] b ... end

Here i use 'a because the examples is from a nominal type system, 
as the name 'a suggests, although this is just coincidental for O'Caml.

The class d is not such a clear case to write out, here is a try:

class d =
    object
      inherit a
      ...
end

class ['d] b' = object inherit ['d] b ... end
(* The following is implicit
class ['d] c' = 
    object 
	inherit ['d] b' 
	inherit ['d] c 
	... 
    end 
*)

It is this implicit part that I suspect could use super-class
polymorphism, because then the class c could be rewritten as:

class ['a,'b] c = 
    object 
	inherit ['a] 'b 
	... 
    end

and then the class c' would be the same as c, except that c' 
is parametrised by [d,b'], while c is parametrised by [a,b].

With name shadowing of classes and explicit polymorphism 
code could be written as:

class a =
    class ['a] b = object ... end
    class ['a,'b] c = object inherit 'b ... end
    object
    ...
end

class d =
    class ['a] b = object inherit b ... end
    (* The following is implicit because b is connected to 'b by magic ;-)
    class ['a,'b] = object inherit b' ... end 
    *)
    object
      inherit a
      ...
end

I hope this demonstrates the idea.

The following code is from the paper by Nystrom, Chong and Myers, 
to give a sample of their intuition:
class A {
  class B { int x; }
  class C extends B {...}
  int m(B b) { return b.x }
  C n() { return new C(); }
  }

class A2 extends A {
  class B {int y; } 
  int m(B b) {return b.x + b.y }
  }
    
John Prevost answered:
One typical feature of inner classes that you will never see in O'Caml
is access to the private state of the surrounding class.  On the other
hand:

class a (xa : int) =
    object
      val mutable xb = xa
      method get_x = xb
      method set_x x = xb <- x
      method new_b () = object
        method get_x = xb
        method set_x x = xb <- x
      end
    end;;


Here you see that you can create an object in which the fields of the
containing object are in scope.  But this inner object is not a class,
so it cannot be inherited from.

Anyway, I will look at the rest of your email and look up the papers
your mention some time later.
    
Jacques Garrigue also answered:
Answer 1: there are no inner classes in ocaml.
Answer 2: there are plenty of other ways to obtain similar effects.

I don't know exactly what fascinated you in the paper, so it is hard
to answer precisely, but there are already a few techniques in ocaml to
solve the problems they describe.
(Of course they wouldn't cite them, as ocaml doesn't look like a
relevant language to them.)

Their compiler example seems to be a variant of the expression
problem.
There are several solutions to the expression problem in ocaml, using
either polymorphic variants
  http://wwwfun.kurims.kyoto-u.ac.jp/~garrigue/papers/fose2000.html
or objects
  http://pauillac.inria.fr/~remy/work/expr/

On the more general question of virtual types, Didier Rémy and Jérôme
Vouillon gave a detailed "refutation".
  http://pauillac.inria.fr/~remy/work/virtual/

So you can see if you can do all what you need with the above methods.
If you find some unexpected limitation, please let us now.
    

Dummy polymorphic constructors

Archive: http://caml.inria.fr/archives/200412/msg00198.html

Alex Baretta asked and Jacques Garrigue answered:
> Currently ocaml does not support empty polymorphic variant sum types. 
> Say, I cannot write the following.
> 
> type empty = [ ]
> 
> This fails due to a syntax error rather than a typing error, which is a 
> sensible, given that the type expression I have written is actually 
> perfectly meaningful.
> 
> Is there a design decision behind this, or have the Caml breeders simply 
> overlooked the potential need for empty types?

This is completely intentional.
Maybe this should be a typing error rather than a syntactic one, to
make the intention clearer.
Empty sum types are not allowed, because, while they are not really
dangerous, they may delay type errors.
For instance, consider the following code:

let f = function `A -> 1 | `B -> 2
let g = function `C -> 3 | `D -> 4
let h x = f x + g x
                  ^
This expression has type [< `A | `B ] but is here used with type [< `C | `D ]
These two variant types have no intersection

If we allowed empty sums, h would be accepted with the type
  [] -> int
But it's clear that this function can never be called.

Note that you can still write unusable functions, as checking for
non-emptyness of types is not always worth the pain, but this is a bit
less trivial than the above code, and the type contains more
information on what happened.

let f = function `A x -> x | `B x -> x+1
let g = function `A f -> truncate f | `B x -> truncate (x +. 0.5)
let h x = f x + g x
val h : [< `A of float & int | `B of float & int ] -> int = <fun>

Another result of excluding the empty sum is that sums with only one
case can be made monomorphic.

let f (`A x) = x
val f : [ `A of 'a ] -> 'a = <fun>
    
John Prevost asked and Alex Baretta answered:
> I'm somewhat confused as to why this is different from simply
> declaring a new opaque type:
> 
> type empty

Ah, this is interesting!

> Since there is no way to construct a value of the type, nor any way to
> deconstruct such a value, how is it different?

Not much, actually. I thought opaque types could only be *declared*.

module M : sig type t end = struct type t = *** end

I never realized that a type could be *defined* as opaque.

module M = struct type t end
    

GC, Anonymous Functions, and C

Archive: http://caml.inria.fr/archives/200412/msg00231.html

Jonathan Roewen asked:
When passing an anonymous ocaml function to a C function, is it safe
to store that value in an array, and then call it later at an abitrary
time, or will the GC reclaim it? And if so, what should be done to
stop the GC from doing so?

Basically, we're trying to do interrupt handling from OCaml, and need
to store the anonymous functions somewhere for the IDT to jump into,
to provide a little context for the problem.
    
Richard Jones answered:
The GC might reclaim the value (function, or whatever) unless you
register it as a global root.  To do this you need to call
caml_register_global_root on each value which you put in the array.
Furthermore you ought to call caml_remove_global_root when you remove
the value from the array and no longer need it.
    
David Brown also answered:
You'll need to register the value as a global root, using
register_global_root.  Please see the Interfacing C with Objective Caml,
where there is brief mention of this function.  It is also important to
dereference the value each time you use it.

static value hook = Val_int (0);

  ...
  hook = passed_argument;
  register_global_root (&hook);

  ...
  callback (hook, arg);

You can also use remove_global_root() later to remove the reference.
    
Damien Doligez also answered:
> Basically, we're trying to do interrupt handling from OCaml, and need
> to store the anonymous functions somewhere for the IDT to jump into,
> to provide a little context for the problem.

This is going to be extremely tricky, if it ever works, because
OCaml code can allocate memory by calling malloc.  And malloc
is not reentrant, so calling it from a signal handler cannot be
correct unless your main program never calls malloc, which rules
out a large number of functions of the C stdlib.  And you don't
even know which ones exactly...
    

OCaml 3.08.2 with TclTkAqua on OS X

Archive: http://caml.inria.fr/archives/200412/msg00238.html

Nathaniel Gray announced (please find the patch at the above url):
I've attached a patch that allows OCaml 3.08.2 to build using the
TclTkAqua frameworks from http://tcltkaqua.sourceforge.net instead of
an X11 version of Tcl/Tk.  To use it, apply the patch and configure
ocaml with "-tklibs '-framework Tcl -framework Tk'".

The changes are very simple:
#include <tcl.h>  --> #include <Tcl/tcl.h>
#include <tk.h>   --> #include <Tk/tk.h>

This is enought to allow ocaml to build, but the labltk examples won't
work as expected.  The OS X window manager requires graphical apps to
be launched from within an application bundle, so you'll need to use
something like Platypus http://sveinbjorn.vefsyn.is/platypus to
package your program.
    
William D. Neumann answered:
I'm not too familiar with platypus, I'll have to take a look at it.  
But for basic operation, it's very easy to create a bundle structure 
manually (or add a resource fork to the app) to enable labltk apps.  
See the bottom of 
http://wiki.cocan.org/getting_started_with_ocaml_on_mac_os_x for more 
details.
    

ocaml-ssl 0.2.0: bindings to the SSL library

Archive: http://caml.inria.fr/archives/200412/msg00253.html

Samuel Mimram announced:
I'm pleased to annonce the 0.2.0 release of ocaml-ssl library which 
consists in bindings to the SSL library (to encrypt communications over 
sockets).

This release corrects a few bugs, parametrizes the context creation 
functions by the protocol to use, and adds a few functions (to handle 
certificates verification, ciphers, etc).

It is licenced under the GPL and can be found here :

http://savonet.sourceforge.net/

As usual comments, suggestions, bug reports and of course patches are 
welcome.
    

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