Version française
Home     About     Download     Resources     Contact us    
Browse thread
RE: first class modules (was: alternative module systems)
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Claudio Russo <crusso@m...>
Subject: RE: first class modules (was: alternative module systems)

(This was a response to Xavier and Mosml hackers, but I've been asked to
forward it to the list).

> Hi Claudio,
> 
> > BTW, in Moscow ML, the "open" construct is integrated more naturally
> > as a special form of declaration, plus a side condition that
> > disallows an open declaration from appearing within the body of a
> > functor (for soundness reasons). This lets you open first-class
> > modules at top-level and within substructures, which can be more
> > convenient.
> 
> That sounds interesting.  I was thinking exactly along these lines.
> Do you have this written down somewhere?
> 
> Xavier

In Moscow there is no separate open expression, just a new form of
structure binding that let's you deconstruct a
first-class module (there is a similar form for functors):

<strbind> := ... | <strid> as <sigexp> = <exp>

This lets you write declarations like


structure Bar as S = if .. then .. else ...;

wherever an ordinary declaration can occur.

This is actually more general (and convenient) than the open construct
because it lets you open first-class modules  at top-level and within
structure bodies, not just within Core expressions. If functors are
always generative, this is ok, but it interacts badly  with applicative
functors (programs can go "wrong"). 
To avoid this, in Moscow we simply place a syntatic restriction on
functor bodies: 
"the body of any functor (whether applicative or generative) cannot
contain a structure level declaration of the 
 above form,  *unless* that declaration occurs within a dec in a Core
"let <dec> in <exp> end" expression"

In the examples below, the structure Ok is legal, the functor Wrong is
illegal but the functor Ok is legal.

signature S = sig type t val f:t end;
structure A = struct type t = int -> int val f x = x+1 end;
structure B = struct type t = bool  val f = true end;
structure Ok as S = if ... then [structure A as S] else  [structure B as
S] (* legal *)
functor Wrong(val b:bool) = 
struct structure C  as S =if b then [structure A as S] else  [structure
B as S]                            
end (* ilegal, because of "open" within immediate structure binding *)

functor Ok(val b:bool) = 
struct val c = let structure C as S = if b then [structure A as S] else
[structure B as S]
	                                in  ...
                                      end
end (* legal again, because "open" is within Core let. *)

I've got a formal revision of the SML definition,  if anyone is
interested, just ask.

The Mosml doc also describes the syntax in more detail (if I recall
correctly).
Of course, it's probably possible to come up with a more permissive
restriction, but I like this one because its simple.

Cheers,
Claudio