From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from weis@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id NAA29639 for caml-redistribution; Wed, 27 Mar 1996 13:29:17 +0100 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.6.10/8.6.6) with ESMTP id RAA14394 for ; Tue, 26 Mar 1996 17:04:04 +0100 Received: from margaux.inria.fr (margaux.inria.fr [128.93.8.2]) by concorde.inria.fr (8.7.1/8.7.1) with ESMTP id RAA10165 for ; Tue, 26 Mar 1996 17:03:34 +0100 (MET) Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by margaux.inria.fr (8.6.10/8.6.6) with ESMTP id RAA06515 for ; Tue, 26 Mar 1996 17:04:03 +0100 Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by concorde.inria.fr (8.7.1/8.7.1) with ESMTP id RAA10161; Tue, 26 Mar 1996 17:03:33 +0100 (MET) Received: (from xleroy@localhost) by pauillac.inria.fr (8.6.10/8.6.6) id RAA14390; Tue, 26 Mar 1996 17:04:02 +0100 From: Xavier Leroy Message-Id: <199603261604.RAA14390@pauillac.inria.fr> Subject: Re: Q: Q: Module system and separate compilatioQ: To: Jocelyn.Serot@lasmea.univ-bpclermont.fr (Jocelyn Serot) Date: Tue, 26 Mar 1996 17:04:02 +0100 (MET) Cc: caml-list@margaux.inria.fr In-Reply-To: <199603211208.NAA07231@concorde.inria.fr> from "Jocelyn Serot" at Mar 21, 96 01:10:16 pm MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: weis > First of all, thanks to W. Lux and C. Boos for their clever answers > to my last questions about the interaction between the module system > and the file system. What i had not realized - it seems - is that > the module language is _implicitely_ spoken within the file system > and that functor application takes place automatically during the > linking phase. This is essentially correct: compilation units (files) are special cases of structures (module-class objects). However, you can still do explicit parameterization and explicit functor applications in a context of separate compilation. That's because all module-class objects, including functors, structures, and module types, can be components of structures, hence components of compilation units. > With the "all in same file, with explicit module declaration" approach , you > can write: > > module type Bar = sig ... end > > module type Foo = sig ... end > > module Foo1 : Foo = struct ... (* 1st impl *) ... end > > module Foo2 : Foo = struct ... (* Another impl *) ... end > > module MakeBar(M: Foo) = (struct ... let double = ... Foo.add ... end : Bar) > > and then _choose_ to build a Bar implementation using either Foo1 > > module Bar = MakeBar(Foo1) > > or Foo2 > > module Bar = MakeBar(Foo2) > > How can you translate the same approach with the signatures and > implementations for Foo and Bar being in distinct files (that is: > foo.mli, foo1.ml, foo2.ml, bar.mli and bar.ml) ? I would have the following compilation units: * "foosig" contains the module type Foo e.g. foosig.ml: module type Foo = sig ... end and if you wish, foosig.mli with the same contents. * "foo1" and "foo2" containing the two implementations foo1.ml: module Foo = struct ... end foo1.mli: module Foo : Foosig.Foo foo2.ml: module Foo = struct ... end foo2.mli: module Foo : Foosig.Foo * "bar" containing the MakeBar functor and the Bar modtype bar.ml: module type Bar = ... module Make(M: Foosig.Foo) = ... bar.mli: module type Bar = ... module Make(M: Foosig.Foo): Bar * "main1" and "main2" that choose between the two implementations and starts up the whole program main1.ml: module Bar = Bar.Make(Foo1.Foo) let _ = Bar.doit(); exit 0 main2.ml: module Bar = Bar.Make(Foo2.Foo) let _ = Bar.doit(); exit 0 Then, link-time configuration is achieved by linking either main1 or main2 with the remainder of the compilation units. So, it can be done. I'm not saying this is completely satisfactory, and more support for link-time configuration could be desirable. On the other hand, I'd hate to add a third language just for controlling the linker... - Xavier Leroy