caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Include question
@ 2011-11-08 15:03 Hans Ole Rafaelsen
  2011-11-08 15:10 ` Gabriel Scherer
  0 siblings, 1 reply; 12+ messages in thread
From: Hans Ole Rafaelsen @ 2011-11-08 15:03 UTC (permalink / raw)
  To: caml-list


[-- Attachment #1.1: Type: text/plain, Size: 1986 bytes --]

Hi,

I'm trying to create a mockup module to replace a network module when doing
testing.

The application consists of basically 3 parts. Some user interaction. This
calls some logic of the application, and the logic module might need to
call some other functions over the network. For testing I want to make a
mockup of the network module, in addition to synthesize the user
interaction. I want to test the logic module. The application has the
following files:

net_lib.ml:
let util_fun a = a
let foo a b = a + b
let bar a b = a - b

logic.ml:
let state = ref 0
let get_state () = !state
let do_op a b =
  incr state;
  (Net_lib.foo a b) * (Net_lib.bar (Net_lib.util_fun a) b )

main_appl.ml:
let () =
  let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
  Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)

let () =
  let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
  Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)


For testing I have the following modules:
net_lib_mockup.ml
include Net_lib
let foo a b = 1
let bar a b = 1

logic_mockup.ml:
module Net_lib = Net_lib_mockup
include Logic

main_test.ml:
module Logic = Logic_mockup

let () =
  let a, b = (1, 1) in
  Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)

let () =
  let a, b = (10, 1) in
  Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)

The problem is that the "include Logic" has already 'bound' the functions
in Logic to the Net_lib module and will not use the Net_lib_mockup that I
try to use through a moudle alias. If i replace the 'include Logic' with
the actual content of the logic.ml file, then the functions get bound to
the Logic_mockup functions, and the test works as they should.

Are there some trick to get the 'include Logic', in logic_mockup.ml, to use
to the Net_lib_mockup module and not the Net_lib module, so that I don't
have to do copy and paste between the two files?


Regards,

Hans Ole Rafaelsen

[-- Attachment #1.2: Type: text/html, Size: 2708 bytes --]

[-- Attachment #2: mockup.tgz --]
[-- Type: application/x-gzip, Size: 2842 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-08 15:03 [Caml-list] Include question Hans Ole Rafaelsen
@ 2011-11-08 15:10 ` Gabriel Scherer
  2011-11-08 15:45   ` Hans Ole Rafaelsen
  2011-11-08 15:49   ` Alexandre Pilkiewicz
  0 siblings, 2 replies; 12+ messages in thread
From: Gabriel Scherer @ 2011-11-08 15:10 UTC (permalink / raw)
  To: Hans Ole Rafaelsen; +Cc: caml-list

If you want some module of your system to be parametrized by another
module (to be able to pass either a concrete module or a mockup
module), you should use a functor.

  http://caml.inria.fr/pub/docs/manual-ocaml/manual004.html#toc15

in logic.ml
  module Make (Net_lib : Net_interface) = struct
    ...
  end

in main.ml:
  module Logic = Logic.Make(Net_lib)
  ..

in main_mockup.ml:
  module Logic = Logic.Make(Net_mockup)
  ...

On Tue, Nov 8, 2011 at 4:03 PM, Hans Ole Rafaelsen <hrafaelsen@gmail.com> wrote:
> Hi,
>
> I'm trying to create a mockup module to replace a network module when doing
> testing.
>
> The application consists of basically 3 parts. Some user interaction. This
> calls some logic of the application, and the logic module might need to call
> some other functions over the network. For testing I want to make a mockup
> of the network module, in addition to synthesize the user interaction. I
> want to test the logic module. The application has the following files:
>
> net_lib.ml:
> let util_fun a = a
> let foo a b = a + b
> let bar a b = a - b
>
> logic.ml:
> let state = ref 0
> let get_state () = !state
> let do_op a b =
>   incr state;
>   (Net_lib.foo a b) * (Net_lib.bar (Net_lib.util_fun a) b )
>
> main_appl.ml:
> let () =
>   let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
>   Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
>
> let () =
>   let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
>   Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
>
>
> For testing I have the following modules:
> net_lib_mockup.ml
> include Net_lib
> let foo a b = 1
> let bar a b = 1
>
> logic_mockup.ml:
> module Net_lib = Net_lib_mockup
> include Logic
>
> main_test.ml:
> module Logic = Logic_mockup
>
> let () =
>   let a, b = (1, 1) in
>   Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
>
> let () =
>   let a, b = (10, 1) in
>   Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
>
> The problem is that the "include Logic" has already 'bound' the functions in
> Logic to the Net_lib module and will not use the Net_lib_mockup that I try
> to use through a moudle alias. If i replace the 'include Logic' with the
> actual content of the logic.ml file, then the functions get bound to the
> Logic_mockup functions, and the test works as they should.
>
> Are there some trick to get the 'include Logic', in logic_mockup.ml, to use
> to the Net_lib_mockup module and not the Net_lib module, so that I don't
> have to do copy and paste between the two files?
>
>
> Regards,
>
> Hans Ole Rafaelsen
>
>


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-08 15:10 ` Gabriel Scherer
@ 2011-11-08 15:45   ` Hans Ole Rafaelsen
  2011-11-08 15:50     ` Thomas Gazagnaire
  2011-11-08 15:49   ` Alexandre Pilkiewicz
  1 sibling, 1 reply; 12+ messages in thread
From: Hans Ole Rafaelsen @ 2011-11-08 15:45 UTC (permalink / raw)
  To: Gabriel Scherer; +Cc: caml-list

[-- Attachment #1: Type: text/plain, Size: 3136 bytes --]

I was hoping not to have to change the interfaces of the application.  Most
of the application is already written and the testing was just an
afterthought :-(

But it might not be that much that need to be changed. I'll give it a shot.

Thanks

On Tue, Nov 8, 2011 at 4:10 PM, Gabriel Scherer
<gabriel.scherer@gmail.com>wrote:

> If you want some module of your system to be parametrized by another
> module (to be able to pass either a concrete module or a mockup
> module), you should use a functor.
>
>  http://caml.inria.fr/pub/docs/manual-ocaml/manual004.html#toc15
>
> in logic.ml
>  module Make (Net_lib : Net_interface) = struct
>    ...
>  end
>
> in main.ml:
>  module Logic = Logic.Make(Net_lib)
>  ..
>
> in main_mockup.ml:
>  module Logic = Logic.Make(Net_mockup)
>  ...
>
> On Tue, Nov 8, 2011 at 4:03 PM, Hans Ole Rafaelsen <hrafaelsen@gmail.com>
> wrote:
> > Hi,
> >
> > I'm trying to create a mockup module to replace a network module when
> doing
> > testing.
> >
> > The application consists of basically 3 parts. Some user interaction.
> This
> > calls some logic of the application, and the logic module might need to
> call
> > some other functions over the network. For testing I want to make a
> mockup
> > of the network module, in addition to synthesize the user interaction. I
> > want to test the logic module. The application has the following files:
> >
> > net_lib.ml:
> > let util_fun a = a
> > let foo a b = a + b
> > let bar a b = a - b
> >
> > logic.ml:
> > let state = ref 0
> > let get_state () = !state
> > let do_op a b =
> >   incr state;
> >   (Net_lib.foo a b) * (Net_lib.bar (Net_lib.util_fun a) b )
> >
> > main_appl.ml:
> > let () =
> >   let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
> >   Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> > let () =
> >   let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
> >   Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> >
> > For testing I have the following modules:
> > net_lib_mockup.ml
> > include Net_lib
> > let foo a b = 1
> > let bar a b = 1
> >
> > logic_mockup.ml:
> > module Net_lib = Net_lib_mockup
> > include Logic
> >
> > main_test.ml:
> > module Logic = Logic_mockup
> >
> > let () =
> >   let a, b = (1, 1) in
> >   Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> > let () =
> >   let a, b = (10, 1) in
> >   Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> > The problem is that the "include Logic" has already 'bound' the
> functions in
> > Logic to the Net_lib module and will not use the Net_lib_mockup that I
> try
> > to use through a moudle alias. If i replace the 'include Logic' with the
> > actual content of the logic.ml file, then the functions get bound to the
> > Logic_mockup functions, and the test works as they should.
> >
> > Are there some trick to get the 'include Logic', in logic_mockup.ml, to
> use
> > to the Net_lib_mockup module and not the Net_lib module, so that I don't
> > have to do copy and paste between the two files?
> >
> >
> > Regards,
> >
> > Hans Ole Rafaelsen
> >
> >
>

[-- Attachment #2: Type: text/html, Size: 4711 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-08 15:10 ` Gabriel Scherer
  2011-11-08 15:45   ` Hans Ole Rafaelsen
@ 2011-11-08 15:49   ` Alexandre Pilkiewicz
  2011-11-09  7:29     ` Cedric Cellier
  1 sibling, 1 reply; 12+ messages in thread
From: Alexandre Pilkiewicz @ 2011-11-08 15:49 UTC (permalink / raw)
  To: Hans Ole Rafaelsen, caml-list

On Tue, Nov 8, 2011 at 10:10 AM, Gabriel Scherer
<gabriel.scherer@gmail.com> wrote:
> If you want some module of your system to be parametrized by another
> module (to be able to pass either a concrete module or a mockup
> module), you should use a functor.

And if you don't want to pollute your entire code with functor when
it's in fact for testing and not part of the logic of the application,
you can use the "functor of the poor": you put your net_lib.ml in a
"real_src" sub directory, and the mockup net_lib.ml (same name) in
"mockup_src", and then you change wich subdir is in the path. Less
pretty, but less invasive too!

Other dirty option (yerk): you put your net_lib module in a reference
over a first class module, and you dynamically change it to point to
the mockup version when you want to test it (but this will probably
not work in many situations, like with abstract types)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-08 15:45   ` Hans Ole Rafaelsen
@ 2011-11-08 15:50     ` Thomas Gazagnaire
  0 siblings, 0 replies; 12+ messages in thread
From: Thomas Gazagnaire @ 2011-11-08 15:50 UTC (permalink / raw)
  To: Hans Ole Rafaelsen; +Cc: Gabriel Scherer, caml-list

[-- Attachment #1: Type: text/plain, Size: 3546 bytes --]

You can have a look at http://www.ocamlpro.com/code/2011-08-10-ocaml-pack-functors.html

It describes how to use either a patched version of OCaml or some external tools to automatically functorize modules to solve your problems.

--
Thomas

On Nov 8, 2011, at 4:45 PM, Hans Ole Rafaelsen wrote:

> I was hoping not to have to change the interfaces of the application.  Most of the application is already written and the testing was just an afterthought :-(
> 
> But it might not be that much that need to be changed. I'll give it a shot.
> 
> Thanks
> 
> On Tue, Nov 8, 2011 at 4:10 PM, Gabriel Scherer <gabriel.scherer@gmail.com> wrote:
> If you want some module of your system to be parametrized by another
> module (to be able to pass either a concrete module or a mockup
> module), you should use a functor.
> 
>  http://caml.inria.fr/pub/docs/manual-ocaml/manual004.html#toc15
> 
> in logic.ml
>  module Make (Net_lib : Net_interface) = struct
>    ...
>  end
> 
> in main.ml:
>  module Logic = Logic.Make(Net_lib)
>  ..
> 
> in main_mockup.ml:
>  module Logic = Logic.Make(Net_mockup)
>  ...
> 
> On Tue, Nov 8, 2011 at 4:03 PM, Hans Ole Rafaelsen <hrafaelsen@gmail.com> wrote:
> > Hi,
> >
> > I'm trying to create a mockup module to replace a network module when doing
> > testing.
> >
> > The application consists of basically 3 parts. Some user interaction. This
> > calls some logic of the application, and the logic module might need to call
> > some other functions over the network. For testing I want to make a mockup
> > of the network module, in addition to synthesize the user interaction. I
> > want to test the logic module. The application has the following files:
> >
> > net_lib.ml:
> > let util_fun a = a
> > let foo a b = a + b
> > let bar a b = a - b
> >
> > logic.ml:
> > let state = ref 0
> > let get_state () = !state
> > let do_op a b =
> >   incr state;
> >   (Net_lib.foo a b) * (Net_lib.bar (Net_lib.util_fun a) b )
> >
> > main_appl.ml:
> > let () =
> >   let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
> >   Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> > let () =
> >   let a, b  = Scanf.scanf  "%d %d\n" (fun a b -> a,b) in
> >   Printf.printf "Foo %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> >
> > For testing I have the following modules:
> > net_lib_mockup.ml
> > include Net_lib
> > let foo a b = 1
> > let bar a b = 1
> >
> > logic_mockup.ml:
> > module Net_lib = Net_lib_mockup
> > include Logic
> >
> > main_test.ml:
> > module Logic = Logic_mockup
> >
> > let () =
> >   let a, b = (1, 1) in
> >   Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> > let () =
> >   let a, b = (10, 1) in
> >   Printf.printf "Test %d %d\n%!" (Logic.get_state ()) (Logic.do_op a b)
> >
> > The problem is that the "include Logic" has already 'bound' the functions in
> > Logic to the Net_lib module and will not use the Net_lib_mockup that I try
> > to use through a moudle alias. If i replace the 'include Logic' with the
> > actual content of the logic.ml file, then the functions get bound to the
> > Logic_mockup functions, and the test works as they should.
> >
> > Are there some trick to get the 'include Logic', in logic_mockup.ml, to use
> > to the Net_lib_mockup module and not the Net_lib module, so that I don't
> > have to do copy and paste between the two files?
> >
> >
> > Regards,
> >
> > Hans Ole Rafaelsen
> >
> >
> 


[-- Attachment #2: Type: text/html, Size: 5330 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-08 15:49   ` Alexandre Pilkiewicz
@ 2011-11-09  7:29     ` Cedric Cellier
  2011-11-09 15:41       ` Vincent Aravantinos
  0 siblings, 1 reply; 12+ messages in thread
From: Cedric Cellier @ 2011-11-09  7:29 UTC (permalink / raw)
  To: caml-list

> And if you don't want to pollute your entire code with functor when
> it's in fact for testing and not part of the logic of the application,

Functor seams the way to go here.
The use of this technique as envisaged here is hardly invading, and comes with many advantages :

Functors help document/clarify the code by stating the relasionships between modules.

Functors help build testable programs by encouraging small and well isolated modules.

Functors help build testable programs by allowing to replace a module with the test version of the modules (the same with many more pre/post conditions added).

And they come free from runtime cost most of the time, which is amazing.

For some reasons though, despite functors being one of the greatest strength of the language, we do seam shy to use, recommand or brag about them. I wonder if this is due to the lack of proper documentation ?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-09  7:29     ` Cedric Cellier
@ 2011-11-09 15:41       ` Vincent Aravantinos
  2011-11-09 15:50         ` Vincent Aravantinos
  0 siblings, 1 reply; 12+ messages in thread
From: Vincent Aravantinos @ 2011-11-09 15:41 UTC (permalink / raw)
  To: caml-list

[-- Attachment #1: Type: text/plain, Size: 1912 bytes --]



On 11/09/2011 02:29 AM, Cedric Cellier wrote:
> For some reasons though, despite functors being one of the greatest 
> strength of the language, we do seam shy to use, recommand or brag 
> about them. I wonder if this is due to the lack of proper documentation ?
I don't think there is a lack of proper documentation: it is introduced 
right away in the "tutorial" part of the Ocaml manual (Part I), it is 
described in the language description (Part II) and there are a couple 
of examples in the std lib (Part IV). What do you think it lacks to be 
properly documented (at least w.r.t other features of Ocaml)?

I actually wonder if they just *look* too complicated? Maybe because 
they are verbose?
Each time you define a functor you also have to give the signature of 
its argument, which, compared to a simple "include" can look overkilling.
Concretely:

module A = struct
   ...
end

module B = struct
   include A
   ...
end

VS

module A = struct
   ...
end

module type B_INPUT = sig
   ... (can be big)
end

module Make_B (X:B_INPUT) = struct
   ...
end

For one module that's fine, but when you start having lots of modules 
and intricate interactions between them, that can start to be a pain in 
the ass.
In addition, this include->functor switch happens quite often when you 
have sources that were not written in the first place with functors in 
mind, so this is not an uncommon situation.

I think personally that this verbosity is actually a good thing because 
it forces to give some documentation which is particularly needed when 
many modules are interacting.
But then this documentation argument is a bit contradictory with what we 
sell to beginners when they learn Ocaml: "Ocaml is great because it has 
type inference, this removes verbosity!"...

-- 
Vincent Aravantinos
Postdoctoral Fellow, Concordia University, Hardware Verification Group
http://users.encs.concordia.ca/~vincent


[-- Attachment #2: Type: text/html, Size: 3371 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-09 15:41       ` Vincent Aravantinos
@ 2011-11-09 15:50         ` Vincent Aravantinos
  2011-11-09 16:29           ` rossberg
  0 siblings, 1 reply; 12+ messages in thread
From: Vincent Aravantinos @ 2011-11-09 15:50 UTC (permalink / raw)
  To: caml-list, Cedric Cellier

[-- Attachment #1: Type: text/plain, Size: 788 bytes --]



On 11/09/2011 10:41 AM, Vincent Aravantinos wrote:
> I actually wonder if they just *look* too complicated? Maybe because 
> they are verbose?
> Each time you define a functor you also have to give the signature of 
> its argument, which, compared to a simple "include" can look overkilling.
> Concretely:
>
> module A = struct
>   ...
> end
>
> module B = struct
>   include A
>   ...
> end
>
> VS
>
> module A = struct
>   ...
> end
>
> module type B_INPUT = sig
>   ... (can be big)
> end
>
> module Make_B (X:B_INPUT) = struct
>   ...
> end

This verbosity problem is actually less true since 3.12 with the 
introduction of "module type of":

module A = struct
   ...
end

module Make_B (X: module type of A) = struct
   ...
end

Which is then quite close to the "include" version.

[-- Attachment #2: Type: text/html, Size: 1834 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-09 15:50         ` Vincent Aravantinos
@ 2011-11-09 16:29           ` rossberg
  2011-11-09 17:08             ` Vincent Aravantinos
  2011-11-09 23:36             ` Jacques Garrigue
  0 siblings, 2 replies; 12+ messages in thread
From: rossberg @ 2011-11-09 16:29 UTC (permalink / raw)
  To: Vincent Aravantinos; +Cc: caml-list, Cedric Cellier

Vincent Aravantinos wrote:
> This verbosity problem is actually less true since 3.12 with the
> introduction of "module type of":
>
> module A = struct
>    ...
> end
>
> module Make_B (X: module type of A) = struct
>    ...
> end
>
> Which is then quite close to the "include" version.

Except that it defeats the whole point of functorizing, because you won't be
able to plug in another module than A anymore (unless A defines no abstract
types, in which case you can get away with it).

/Andreas


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-09 16:29           ` rossberg
@ 2011-11-09 17:08             ` Vincent Aravantinos
  2011-11-09 23:36             ` Jacques Garrigue
  1 sibling, 0 replies; 12+ messages in thread
From: Vincent Aravantinos @ 2011-11-09 17:08 UTC (permalink / raw)
  To: rossberg; +Cc: caml-list, Cedric Cellier



On 11/09/2011 11:29 AM, rossberg@mpi-sws.org wrote:
> Vincent Aravantinos wrote:
>> This verbosity problem is actually less true since 3.12 with the
>> introduction of "module type of":
>>
>> module A = struct
>>     ...
>> end
>>
>> module Make_B (X: module type of A) = struct
>>     ...
>> end
>>
>> Which is then quite close to the "include" version.
> Except that it defeats the whole point of functorizing, because you won't be
> able to plug in another module than A anymore (unless A defines no abstract
> types, in which case you can get away with it).

Indeed. Stupid idea...

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-09 16:29           ` rossberg
  2011-11-09 17:08             ` Vincent Aravantinos
@ 2011-11-09 23:36             ` Jacques Garrigue
  2011-11-10 12:08               ` rossberg
  1 sibling, 1 reply; 12+ messages in thread
From: Jacques Garrigue @ 2011-11-09 23:36 UTC (permalink / raw)
  To: rossberg; +Cc: Vincent Aravantinos, caml-list, Cedric Cellier

On 2011/11/10, at 1:29, rossberg@mpi-sws.org wrote:

> Vincent Aravantinos wrote:
>> This verbosity problem is actually less true since 3.12 with the
>> introduction of "module type of":
>> 
>> module A = struct
>>   ...
>> end
>> 
>> module Make_B (X: module type of A) = struct
>>   ...
>> end
>> 
>> Which is then quite close to the "include" version.
> 
> Except that it defeats the whole point of functorizing, because you won't be
> able to plug in another module than A anymore (unless A defines no abstract
> types, in which case you can get away with it).

This is actually the opposite: "module type of A" gives no equation for the
abstract types, so if module A contained an abstract type, you will be able to
change it by another abstract one. On the other hand, all concrete types
will stay there, and you will have no way to change them even if Make_B doesn't
care.

Jacques Garrigue

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [Caml-list] Include question
  2011-11-09 23:36             ` Jacques Garrigue
@ 2011-11-10 12:08               ` rossberg
  0 siblings, 0 replies; 12+ messages in thread
From: rossberg @ 2011-11-10 12:08 UTC (permalink / raw)
  To: Jacques Garrigue; +Cc: rossberg, Vincent Aravantinos, caml-list, Cedric Cellier

> On 2011/11/10, at 1:29, rossberg@mpi-sws.org wrote:
>> Vincent Aravantinos wrote:
>>> This verbosity problem is actually less true since 3.12 with the
>>> introduction of "module type of":
>>>
>>> module A = struct
>>>   ...
>>> end
>>>
>>> module Make_B (X: module type of A) = struct
>>>   ...
>>> end
>>>
>>> Which is then quite close to the "include" version.
>>
>> Except that it defeats the whole point of functorizing, because you won't
>> be
>> able to plug in another module than A anymore (unless A defines no
>> abstract
>> types, in which case you can get away with it).
>
> This is actually the opposite: "module type of A" gives no equation for the
> abstract types, so if module A contained an abstract type, you will be able
> to change it by another abstract one. On the other hand, all concrete types
> will stay there, and you will have no way to change them even if Make_B
> doesn't care.

Oh, interesting. I was under the impression that A's signature gets
selfified as usual, so that

  sig module X : module type of A end

is equivalent to

  sig module X : SA end with module X = A

(Have no Ocaml 3.12 around here, unfortunately.)

Thanks for the correction!
/Andreas


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2011-11-10 12:08 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-08 15:03 [Caml-list] Include question Hans Ole Rafaelsen
2011-11-08 15:10 ` Gabriel Scherer
2011-11-08 15:45   ` Hans Ole Rafaelsen
2011-11-08 15:50     ` Thomas Gazagnaire
2011-11-08 15:49   ` Alexandre Pilkiewicz
2011-11-09  7:29     ` Cedric Cellier
2011-11-09 15:41       ` Vincent Aravantinos
2011-11-09 15:50         ` Vincent Aravantinos
2011-11-09 16:29           ` rossberg
2011-11-09 17:08             ` Vincent Aravantinos
2011-11-09 23:36             ` Jacques Garrigue
2011-11-10 12:08               ` rossberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).