From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: ** X-Spam-Status: No, score=2.5 required=5.0 tests=AWL,DNS_FROM_RFC_POST, HTML_MESSAGE,SPF_NEUTRAL autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by yquem.inria.fr (Postfix) with ESMTP id 01083BBAF for ; Tue, 21 Apr 2009 18:01:05 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AlECAF+K7UlKfS4eimdsb2JhbACCITGSVVo/AQEBCgkMBw8FrDmBCZA8AQMBA4N3Bg X-IronPort-AV: E=Sophos;i="4.38,431,1233529200"; d="scan'208";a="28045745" Received: from yw-out-2324.google.com ([74.125.46.30]) by mail1-smtp-roc.national.inria.fr with ESMTP; 21 Apr 2009 18:01:05 +0200 Received: by yw-out-2324.google.com with SMTP id 5so1709608ywh.3 for ; Tue, 21 Apr 2009 09:01:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:cc:content-type; bh=y/Q2n9GgRpFuvp9PfRIJuq4sMsn0tod6TtdukeOblWI=; b=xDmt+UYw8JZLfoU5i0GysNOsbp4F5p9WqXndifh/voc47SbpibhTjGOYzqL9ZI5ZIX JGLyFmOCfalUDo2JWeEt2Wd2QM33z5ojXs7tsc/r2aMMB4ta2+6OJVB5pFZawwMwMe0p LtBJxaJTCK8xlEM2GZG2hcrp5aTUwIZ0B9XVI= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; b=G+S4kvMoHAoGMpNFa9kJaqVfGxotRFf7EzZqjVdiS7yjjnTXipWv1DiTEKaR8S3JVN 6vDp1PigwtXqQSprEMcfTDynxUOs0Q9+t2OMB6frhzrcV+F626mLWIFreYGJio4X2mGz eEBXz2Jz6z/g+nV0fjTrqAf/oulKMUBbThF4o= MIME-Version: 1.0 Received: by 10.90.26.3 with SMTP id 3mr9059612agz.27.1240329664463; Tue, 21 Apr 2009 09:01:04 -0700 (PDT) In-Reply-To: <49EBBC6C.8000502@ens-lyon.org> References: <49E9E195.6030603@ens-lyon.org> <49EBBC6C.8000502@ens-lyon.org> Date: Tue, 21 Apr 2009 12:01:04 -0400 Message-ID: Subject: Re: [Caml-list] Extending modules and signatures From: Ashish Agarwal To: Martin Jambon Cc: Peter Hawkins , caml-list@yquem.inria.fr Content-Type: multipart/alternative; boundary=00163630efc90e0463046812c1c2 X-Spam: no; 0.00; ens-lyon:01 mli:01 compiler:01 mli:01 module's:01 functor:01 sig:01 val:01 struct:01 struct:01 ens-lyon:01 compiler:01 module's:01 functor:01 sig:01 --00163630efc90e0463046812c1c2 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit > 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 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 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/ > --00163630efc90e0463046812c1c2 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable > I think the real issue is inheritance.

Yes. Your ex= ample adds an extra complication by using references. Forgoing that, I get = around this within the current module system by defining a base module B, w= hich 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 al= l 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 e= lsewhere. However, it is not a good solution for libraries distributed to o= thers.


On Sun, Apr 19, 2009 at 8:06 PM, Ma= rtin Jambon <martin.jambon@ens-lyon.org> wrote:
Ashish Agarwal wrote:
>> The module type exists, it's just that it doesn't have a n= ame.
>
> Right, thanks for the clarification.
>
>
>> let x =3D (123, "abc")
>> does not define "type x =3D 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<= br> > "type x =3D int * string". The corresponding solution to nam= ing 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. =A0In order to truly e= xtend an
existing module, one needs to access the private items of the inherited mod= ule
implementation. =A0In order to avoid messing up with the original module= 9;s
global variables, the inherited "module" should be more like a fu= nctor that
would create a fresh instance of the module each time it is instantiated, j= ust
like classes generate objects.


I could imagine something like this:

module class A :
sig
=A0val get_x : unit -> int
end =3D
struct
=A0let x =3D ref 123
=A0let get_x () =3D !x
end

module class B =3D
struct
=A0inherit A
=A0let incr_x () =3D incr x
end

module B1 =3D new module B
module B2 =3D new module B
;;

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


Module class implementations and signatures could be conveniently created a= s
whole files using new file extensions, say .mc and .mci. =A0These 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/

--00163630efc90e0463046812c1c2--