caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Extending modules and signatures
@ 2009-04-17 20:51 Peter Hawkins
  2009-04-17 21:36 ` [Caml-list] " Goswin von Brederlow
  2009-04-18  5:47 ` Ashish Agarwal
  0 siblings, 2 replies; 12+ messages in thread
From: Peter Hawkins @ 2009-04-17 20:51 UTC (permalink / raw)
  To: caml-list

Hi...

I have a quick question. I want to extend the List module with various
functions that I want that aren't present in the standard library,
much as the Batteries ExtList library does.

I might write the following code in "mylibrary.ml":
module MyList = struct
  include List
  let foo x = ... code here
  let bar y = ... code here
end

That's ok so far, but now suppose I want to write a "mylibrary.mli"
interface file corresponding to "mylibrary.ml". Ideally I'd write
something like this in "mylibrary.mli":
module MyList : sig
  include List  (* unknown module type List *)
  val foo : ...
  val bar : ...
end

Unfortunately I can't include "List" here since it is a structure, not
a signature. I don't think there is a way to say "include the
signature associated with List".

I can think of three solutions:
a) Copy the complete signature of List into MyList. This is a bad idea
since the List module might change in the future. This is what the
Batteries ExtList module does.
b) Alter the List module to define a signature, say List.S, in
addition to its other contents. I can't easily do this since I didn't
write the List module.
c) Don't write a .mli file at all.

Are there any other alternatives?

Cheers,
Peter


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-17 20:51 Extending modules and signatures Peter Hawkins
@ 2009-04-17 21:36 ` Goswin von Brederlow
  2009-04-18  5:47 ` Ashish Agarwal
  1 sibling, 0 replies; 12+ messages in thread
From: Goswin von Brederlow @ 2009-04-17 21:36 UTC (permalink / raw)
  To: Peter Hawkins; +Cc: caml-list

Peter Hawkins <hawkinsp@cs.stanford.edu> writes:

> Hi...
>
> I have a quick question. I want to extend the List module with various
> functions that I want that aren't present in the standard library,
> much as the Batteries ExtList library does.
>
> I might write the following code in "mylibrary.ml":
> module MyList = struct
>   include List
>   let foo x = ... code here
>   let bar y = ... code here
> end
>
> That's ok so far, but now suppose I want to write a "mylibrary.mli"
> interface file corresponding to "mylibrary.ml". Ideally I'd write
> something like this in "mylibrary.mli":
> module MyList : sig
>   include List  (* unknown module type List *)
>   val foo : ...
>   val bar : ...
> end
>
> Unfortunately I can't include "List" here since it is a structure, not
> a signature. I don't think there is a way to say "include the
> signature associated with List".
>
> I can think of three solutions:
> a) Copy the complete signature of List into MyList. This is a bad idea
> since the List module might change in the future. This is what the
> Batteries ExtList module does.
> b) Alter the List module to define a signature, say List.S, in
> addition to its other contents. I can't easily do this since I didn't
> write the List module.
> c) Don't write a .mli file at all.
>
> Are there any other alternatives?

Something like :

module MyList = struct
  include List
  module M : sig val foo : int -> unit end = struct
    let foo x = ()
    let bar y = y
  end
  include M
end

and no .mli file. The module M is there to alow you to give (or hide)
the signature of just your extra functions.

> Cheers,
> Peter

MfG
        Goswin


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-17 20:51 Extending modules and signatures Peter Hawkins
  2009-04-17 21:36 ` [Caml-list] " Goswin von Brederlow
@ 2009-04-18  5:47 ` Ashish Agarwal
  2009-04-18 14:20   ` Martin Jambon
  1 sibling, 1 reply; 12+ messages in thread
From: Ashish Agarwal @ 2009-04-18  5:47 UTC (permalink / raw)
  To: Peter Hawkins; +Cc: caml-list

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

This is a commonly requested feature. One issue is that a file a.ml creates
a module A. However, a file a.mli does not create a module type A. I'm not
sure why this is the case. Does anyone know if there is a specific reason?

On Fri, Apr 17, 2009 at 4:51 PM, Peter Hawkins <hawkinsp@cs.stanford.edu>wrote:

> Hi...
>
> I have a quick question. I want to extend the List module with various
> functions that I want that aren't present in the standard library,
> much as the Batteries ExtList library does.
>
> I might write the following code in "mylibrary.ml":
> module MyList = struct
>  include List
>  let foo x = ... code here
>  let bar y = ... code here
> end
>
> That's ok so far, but now suppose I want to write a "mylibrary.mli"
> interface file corresponding to "mylibrary.ml". Ideally I'd write
> something like this in "mylibrary.mli":
> module MyList : sig
>  include List  (* unknown module type List *)
>  val foo : ...
>  val bar : ...
> end
>
> Unfortunately I can't include "List" here since it is a structure, not
> a signature. I don't think there is a way to say "include the
> signature associated with List".
>
> I can think of three solutions:
> a) Copy the complete signature of List into MyList. This is a bad idea
> since the List module might change in the future. This is what the
> Batteries ExtList module does.
> b) Alter the List module to define a signature, say List.S, in
> addition to its other contents. I can't easily do this since I didn't
> write the List module.
> c) Don't write a .mli file at all.
>
> Are there any other alternatives?
>
> Cheers,
> Peter
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs
>

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

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

* Re: [Caml-list] Extending modules and signatures
  2009-04-18  5:47 ` Ashish Agarwal
@ 2009-04-18 14:20   ` Martin Jambon
  2009-04-19 21:36     ` Ashish Agarwal
  0 siblings, 1 reply; 12+ messages in thread
From: Martin Jambon @ 2009-04-18 14:20 UTC (permalink / raw)
  To: Ashish Agarwal; +Cc: Peter Hawkins, caml-list

Ashish Agarwal wrote:
> This is a commonly requested feature.

Ah.

> One issue is that a file a.ml
> <http://a.ml> creates a module A. However, a file a.mli does not create
> a module type A. I'm not sure why this is the case. Does anyone know if
> there is a specific reason?

The module type exists, it's just that it doesn't have a name.

  let x = (123, "abc")

does not define "type x = int * string" either.



Martin

-- 
http://mjambon.com/


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-18 14:20   ` Martin Jambon
@ 2009-04-19 21:36     ` Ashish Agarwal
  2009-04-19 21:53       ` Jon Harrop
  2009-04-20  0:06       ` Martin Jambon
  0 siblings, 2 replies; 12+ messages in thread
From: Ashish Agarwal @ 2009-04-19 21:36 UTC (permalink / raw)
  To: Martin Jambon; +Cc: Peter Hawkins, caml-list

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

> The module type exists, it's just that it doesn't have a name.
Right, thanks for the clarification.


> let x = (123, "abc")
> does not define "type x = int * string" either.

True, but I think the expectations are different for module types. A file
a.ml creates a module named A, and it seems natural to expect a.mli to
create a module type A. I find it inconsistent that it does not.

Further, if you wanted to name the above type, it is easy, just write "type
x = int * string". The corresponding solution to naming module types is
burdensome. You have to define it within another module, introducing an
unnecessary layer into your module hierarchy. Also that doesn't help you
when using somebody else's library.

Having the compiler introduce module type names automatically from mli files
would be very helpful, and I don't see any disadvantages.



On Sat, Apr 18, 2009 at 10:20 AM, Martin Jambon
<martin.jambon@ens-lyon.org>wrote:

> Ashish Agarwal wrote:
> > This is a commonly requested feature.
>
> Ah.
>
> > One issue is that a file a.ml
> > <http://a.ml> creates a module A. However, a file a.mli does not create
> > a module type A. I'm not sure why this is the case. Does anyone know if
> > there is a specific reason?
>
> The module type exists, it's just that it doesn't have a name.
>
>  let x = (123, "abc")
>
> does not define "type x = int * string" either.
>
>
>
> Martin
>
> --
> http://mjambon.com/
>

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

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

* Re: [Caml-list] Extending modules and signatures
  2009-04-19 21:36     ` Ashish Agarwal
@ 2009-04-19 21:53       ` Jon Harrop
  2009-04-20  5:17         ` Goswin von Brederlow
  2009-04-20  0:06       ` Martin Jambon
  1 sibling, 1 reply; 12+ messages in thread
From: Jon Harrop @ 2009-04-19 21:53 UTC (permalink / raw)
  To: caml-list

On Sunday 19 April 2009 22:36:12 Ashish Agarwal wrote:
> > The module type exists, it's just that it doesn't have a name.
>
> Right, thanks for the clarification.
>
> > let x = (123, "abc")
> > does not define "type x = int * string" either.
>
> True, but I think the expectations are different for module types. A file
> a.ml creates a module named A, and it seems natural to expect a.mli to
> create a module type A. I find it inconsistent that it does not.

The mli and ml are equivalent to:

  module A : sig =
    ...
  end = struct
    ...
  end

i.e. no module type is defined.

> Further, if you wanted to name the above type, it is easy, just write "type
> x = int * string". The corresponding solution to naming module types is
> burdensome. You have to define it within another module, introducing an
> unnecessary layer into your module hierarchy. Also that doesn't help you
> when using somebody else's library.

True. There is also an unfortunate amount of copy'n'paste involved as well, 
and manual maintenance of signatures. I believe that often deters people from 
using module signatures and module types at all.

> Having the compiler introduce module type names automatically from mli
> files would be very helpful, and I don't see any disadvantages.

Some people contest the idea that files should automatically convey module 
information at all (SML does not). Indeed, should directories convey 
something as well?

-- 
Dr Jon Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?e


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-19 21:36     ` Ashish Agarwal
  2009-04-19 21:53       ` Jon Harrop
@ 2009-04-20  0:06       ` Martin Jambon
  2009-04-20  5:23         ` Goswin von Brederlow
  2009-04-21 16:01         ` Ashish Agarwal
  1 sibling, 2 replies; 12+ messages in thread
From: Martin Jambon @ 2009-04-20  0:06 UTC (permalink / raw)
  To: Ashish Agarwal; +Cc: Peter Hawkins, caml-list

Ashish Agarwal wrote:
>> The module type exists, it's just that it doesn't have a name.
> 
> Right, thanks for the clarification.
> 
> 
>> let x = (123, "abc")
>> does not define "type x = int * string" either.
> 
> True, but I think the expectations are different for module types. A
> file a.ml <http://a.ml> creates a module named A, and it seems natural
> to expect a.mli to create a module type A. I find it inconsistent that
> it does not.
> 
> Further, if you wanted to name the above type, it is easy, just write
> "type x = int * string". The corresponding solution to naming module
> types is burdensome. You have to define it within another module,
> introducing an unnecessary layer into your module hierarchy. Also that
> doesn't help you when using somebody else's library.
> 
> Having the compiler introduce module type names automatically from mli
> files would be very helpful, and I don't see any disadvantages.

OK, but I think the real issue is inheritance.  In order to truly extend an
existing module, one needs to access the private items of the inherited module
implementation.  In order to avoid messing up with the original module's
global variables, the inherited "module" should be more like a functor that
would create a fresh instance of the module each time it is instantiated, just
like classes generate objects.


I could imagine something like this:

module class A :
sig
  val get_x : unit -> int
end =
struct
  let x = ref 123
  let get_x () = !x
end

module class B =
struct
  inherit A
  let incr_x () = incr x
end

module B1 = new module B
module B2 = new module B
;;

B1.incr_x ();;
- : unit = ()
B1.get_x ();;
- : int = 124
B2.get_x ();;
- : int = 123


Module class implementations and signatures could be conveniently created as
whole files using new file extensions, say .mc and .mci.  These would be like
.ml files except that they would support module class inheritance and would be
evaluated only when they are instantiated with "new module".




Martin

-- 
http://mjambon.com/


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-19 21:53       ` Jon Harrop
@ 2009-04-20  5:17         ` Goswin von Brederlow
  0 siblings, 0 replies; 12+ messages in thread
From: Goswin von Brederlow @ 2009-04-20  5:17 UTC (permalink / raw)
  To: caml-list

Jon Harrop <jon@ffconsultancy.com> writes:

> On Sunday 19 April 2009 22:36:12 Ashish Agarwal wrote:
>> Having the compiler introduce module type names automatically from mli
>> files would be very helpful, and I don't see any disadvantages.
>
> Some people contest the idea that files should automatically convey module 
> information at all (SML does not). Indeed, should directories convey 
> something as well?

I thought they did.

a.ml: module B = struct let foo = ... end

and

a/b.ml : let foo = ...

could actually be equivalent and both result in A.B.foo.

MfG
        Goswin


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-20  0:06       ` Martin Jambon
@ 2009-04-20  5:23         ` Goswin von Brederlow
  2009-04-20 11:55           ` Martin Jambon
  2009-04-21 16:01         ` Ashish Agarwal
  1 sibling, 1 reply; 12+ messages in thread
From: Goswin von Brederlow @ 2009-04-20  5:23 UTC (permalink / raw)
  To: Martin Jambon; +Cc: Ashish Agarwal, caml-list

Martin Jambon <martin.jambon@ens-lyon.org> writes:

> OK, but I think the real issue is inheritance.  In order to truly extend an
> existing module, one needs to access the private items of the inherited module
> implementation.  In order to avoid messing up with the original module's
> global variables, the inherited "module" should be more like a functor that
> would create a fresh instance of the module each time it is instantiated, just
> like classes generate objects.
>
>
> I could imagine something like this:
>
> module class A :
> sig
>   val get_x : unit -> int
> end =
> struct
>   let x = ref 123
>   let get_x () = !x
> end
>
> module class B =
> struct
>   inherit A
>   let incr_x () = incr x
> end
>
> module B1 = new module B
> module B2 = new module B
> ;;
>
> B1.incr_x ();;
> - : unit = ()
> B1.get_x ();;
> - : int = 124
> B2.get_x ();;
> - : int = 123
>
>
> Module class implementations and signatures could be conveniently created as
> whole files using new file extensions, say .mc and .mci.  These would be like
> .ml files except that they would support module class inheritance and would be
> evaluated only when they are instantiated with "new module".

Which would also need

module A1 = new module A
module A2 = new module A
A1.incr_x ()
A1.get_x;;
- : int = 124
A2.get_x ();;
- : int = 123

So you see A does not have global variables but only instance
variables. What you describe are ocaml objects. Not modules.

MfG
        Goswin


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-20  5:23         ` Goswin von Brederlow
@ 2009-04-20 11:55           ` Martin Jambon
  0 siblings, 0 replies; 12+ messages in thread
From: Martin Jambon @ 2009-04-20 11:55 UTC (permalink / raw)
  To: Goswin von Brederlow; +Cc: Ashish Agarwal, caml-list

Goswin von Brederlow wrote:
> Which would also need
> 
> module A1 = new module A
> module A2 = new module A
> A1.incr_x ()
> A1.get_x;;
> - : int = 124
> A2.get_x ();;
> - : int = 123
> 
> So you see A does not have global variables but only instance
> variables. What you describe are ocaml objects. Not modules.

The tiny <ahem> difference is that objects may not contain type definitions.
Functors do, but they don't support inheritance because all the private
members are hidden behind the module interface.



Martin

-- 
http://mjambon.com/


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

* Re: [Caml-list] Extending modules and signatures
  2009-04-20  0:06       ` Martin Jambon
  2009-04-20  5:23         ` Goswin von Brederlow
@ 2009-04-21 16:01         ` Ashish Agarwal
  1 sibling, 0 replies; 12+ messages in thread
From: Ashish Agarwal @ 2009-04-21 16:01 UTC (permalink / raw)
  To: Martin Jambon; +Cc: Peter Hawkins, caml-list

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

> I think the real issue is inheritance.
Yes. Your example adds an extra complication by using references. Forgoing
that, I get around this within the current module system by defining a base
module B, which two other modules C an D "inherit", i.e. they just include
B. Module B has the common values and types needed by C and D. Only problem
with this is that I am forced to expose all the values and types in B to all
client code. It would help to restrict B's visibility to just C and D. No
big deal for internally used libraries; I just remember not to use B
elsewhere. However, it is not a good solution for libraries distributed to
others.


On Sun, Apr 19, 2009 at 8:06 PM, Martin Jambon
<martin.jambon@ens-lyon.org>wrote:

> Ashish Agarwal wrote:
> >> The module type exists, it's just that it doesn't have a name.
> >
> > Right, thanks for the clarification.
> >
> >
> >> let x = (123, "abc")
> >> does not define "type x = int * string" either.
> >
> > True, but I think the expectations are different for module types. A
> > file a.ml <http://a.ml> creates a module named A, and it seems natural
> > to expect a.mli to create a module type A. I find it inconsistent that
> > it does not.
> >
> > Further, if you wanted to name the above type, it is easy, just write
> > "type x = int * string". The corresponding solution to naming module
> > types is burdensome. You have to define it within another module,
> > introducing an unnecessary layer into your module hierarchy. Also that
> > doesn't help you when using somebody else's library.
> >
> > Having the compiler introduce module type names automatically from mli
> > files would be very helpful, and I don't see any disadvantages.
>
> OK, but I think the real issue is inheritance.  In order to truly extend an
> existing module, one needs to access the private items of the inherited
> module
> implementation.  In order to avoid messing up with the original module's
> global variables, the inherited "module" should be more like a functor that
> would create a fresh instance of the module each time it is instantiated,
> just
> like classes generate objects.
>
>
> I could imagine something like this:
>
> module class A :
> sig
>  val get_x : unit -> int
> end =
> struct
>  let x = ref 123
>  let get_x () = !x
> end
>
> module class B =
> struct
>  inherit A
>  let incr_x () = incr x
> end
>
> module B1 = new module B
> module B2 = new module B
> ;;
>
> B1.incr_x ();;
> - : unit = ()
> B1.get_x ();;
> - : int = 124
> B2.get_x ();;
> - : int = 123
>
>
> Module class implementations and signatures could be conveniently created
> as
> whole files using new file extensions, say .mc and .mci.  These would be
> like
> .ml files except that they would support module class inheritance and would
> be
> evaluated only when they are instantiated with "new module".
>
>
>
>
> Martin
>
> --
> http://mjambon.com/
>

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

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

* Re: [Caml-list] Extending modules and signatures
@ 2009-04-17 21:30 Dario Teixeira
  0 siblings, 0 replies; 12+ messages in thread
From: Dario Teixeira @ 2009-04-17 21:30 UTC (permalink / raw)
  To: caml-list, Peter Hawkins


Hi,
 
> I have a quick question. I want to extend the List module with various
> functions that I want that aren't present in the standard library,
> much as the Batteries ExtList library does.

I reckon you want something like this:

http://caml.inria.fr/mantis/view.php?id=3013

Cheers,
Dario Teixeira






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

end of thread, other threads:[~2009-04-21 16:01 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-04-17 20:51 Extending modules and signatures Peter Hawkins
2009-04-17 21:36 ` [Caml-list] " Goswin von Brederlow
2009-04-18  5:47 ` Ashish Agarwal
2009-04-18 14:20   ` Martin Jambon
2009-04-19 21:36     ` Ashish Agarwal
2009-04-19 21:53       ` Jon Harrop
2009-04-20  5:17         ` Goswin von Brederlow
2009-04-20  0:06       ` Martin Jambon
2009-04-20  5:23         ` Goswin von Brederlow
2009-04-20 11:55           ` Martin Jambon
2009-04-21 16:01         ` Ashish Agarwal
2009-04-17 21:30 Dario Teixeira

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).