From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id AF1FABC57 for ; Thu, 5 Aug 2010 18:11:16 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AsIBAHJ/WkzRVda0mGdsb2JhbACTHI0VCBUBAQEBAQgJDAcRIqxQiQqCEIYPLohUAQEDBYIQgyUEiSw X-IronPort-AV: E=Sophos;i="4.55,323,1278280800"; d="scan'208";a="55134607" Received: from mail-iw0-f180.google.com ([209.85.214.180]) by mail3-smtp-sop.national.inria.fr with ESMTP; 05 Aug 2010 18:11:15 +0200 Received: by iwn4 with SMTP id 4so337454iwn.39 for ; Thu, 05 Aug 2010 09:11:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:mime-version:received:in-reply-to :references:from:date:message-id:subject:to:cc:content-type; bh=5u6YYZ5ZODrrq5OizIkXr+Jd07nUmnpgAl/yN1AaqgI=; b=Wss+V7W9YS+PhMZn8fBv3/FKCvZMvYrCUBx5wQWsUMpggi5eJNuCANW0Gt6MX6TY7+ iyZVag1LK3Ljjm5TIhbHT+eKLady1eWSfA6qSKJjn3TlcJ4LOgCb7u9LEBCn5+RzbbLa BmcqrEeVDDI0PIMM1odjVNawF8l5yTyH6nJeM= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; b=ZpV/MvBZ+8D3BYaE7kDSKjC0fktX4RumRG4U+WL6by/zCG+7516fwJAQ+ZjrDewAMa MYXlQzT4k4JmIvqprJ1xVc0HgNFNZI7Rs1DV7zkdXP+vB2/9tyRgrtZxsQkMrMo3cBbF 49nzzh/pv8R1wphWkOTtzA+ggOd+ynxaaERUM= Received: by 10.231.190.149 with SMTP id di21mr12572712ibb.27.1281024674288; Thu, 05 Aug 2010 09:11:14 -0700 (PDT) MIME-Version: 1.0 Received: by 10.231.187.75 with HTTP; Thu, 5 Aug 2010 09:10:54 -0700 (PDT) In-Reply-To: <607998.18398.qm@web111514.mail.gq1.yahoo.com> References: <607998.18398.qm@web111514.mail.gq1.yahoo.com> From: Philippe Veber Date: Thu, 5 Aug 2010 18:10:54 +0200 Message-ID: Subject: Re: [Caml-list] Emulating width subtyping with 1st-class modules To: Dario Teixeira Cc: caml-list@yquem.inria.fr Content-Type: multipart/alternative; boundary=001485e77336a8d667048d15ccf7 X-Spam: no; 0.00; subtyping:01 subtyping:01 ocaml's:01 sig:01 val:01 val:01 sig:01 printf:01 printf:01 struct:01 struct:01 verbose:01 camlp:01 beginner's:01 ocaml:01 --001485e77336a8d667048d15ccf7 Content-Type: text/plain; charset=ISO-8859-1 I have a related question: the only reason why i'm not fully happy with objects used as anonymous records is that i sometimes use them as mere data containers and need to save (marshal) them at some point. Which is not permitted as soon as you want to exchange marshalled values between two different programs. Hopefully one can rely on json-static to cope with that limitation in a quite elegant way. Are first-class modules distinct in that respect ? That is, can they be marshalled if they do not contain closures ? philippe. PS For those who missed it, there was an interesting thread on this very topic a year ago http://groups.google.com/group/fa.caml/browse_thread/thread/1eb4bba668b27aa3/9192a2760ef97ca9 2010/8/5 Dario Teixeira > Hi, > > I have a problem where some form of width subtyping for records would be > useful. At the present I'm taking advantage of the structural subtyping > nature > of Ocaml's object system to emulate the width subtyping. This works and is > reasonably compact, but I'm still open to other approaches. It has > occurred > to me that 3.12's modules-as-first-class-values provide yet another > solution: > > > module type BRIEF = > sig > val a: int > val b: string > end > > > module type FULL = > sig > include BRIEF > val c: float > end > > > let print_brief m = > let module M = (val m: BRIEF) in > Printf.printf "A: %d, B: %s\n" M.a M.b > > > let print_full m = > let module M = (val m: FULL) in > Printf.printf "A: %d, B: %s, C: %f\n" M.a M.b M.c > > > module Full = > struct > let a = 1 > let b = "full" > let c = 0.5 > end > > > module Brief = > struct > let a = 0 > let b = "short" > end > > > let () = > print_brief (module Brief : BRIEF); > print_brief (module Full : BRIEF); > print_full (module Full : FULL) > > > While this approach seems awfully verbose, I reckon it could be made much > more palatable via some Camlp4 sugaring. Nevertheless, I have a question: > just how heavy would this approach be when compared to the object one? > And how would it fare in comparison to regular records? > > Thanks for your attention! > Best regards, > Dario Teixeira > > > > > > _______________________________________________ > 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 > --001485e77336a8d667048d15ccf7 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable I have a related question: the only reason why i'm not fully happy with= objects used as anonymous records is that i sometimes use them as mere dat= a containers and need to save (marshal) them at some point. Which is not pe= rmitted as soon as you want to exchange marshalled values between two diffe= rent programs. Hopefully one can rely on json-static to cope with that limi= tation in a quite elegant way. Are first-class modules distinct in that res= pect ? That is, can they be marshalled if they do not contain closures ?
philippe.

PS For those who missed it, there was an interesting t= hread on this very topic a year ago

h= ttp://groups.google.com/group/fa.caml/browse_thread/thread/1eb4bba668b27aa3= /9192a2760ef97ca9


2010/8/5 Dario Teixeira <darioteixeira@yahoo.com>
Hi,

I have a problem where some form of width subtyping for records would be useful. =A0At the present I'm taking advantage of the structural subtyp= ing nature
of Ocaml's object system to emulate the width subtyping. =A0This works = and is
reasonably compact, but I'm still open to other approaches. =A0It has o= ccurred
to me that 3.12's modules-as-first-class-values provide yet another sol= ution:


module type BRIEF =3D
sig
=A0 =A0 =A0 =A0val a: int
=A0 =A0 =A0 =A0val b: string
end


module type FULL =3D
sig
=A0 =A0 =A0 =A0include BRIEF
=A0 =A0 =A0 =A0val c: float
end


let print_brief m =3D
=A0 =A0 =A0 =A0let module M =3D (val m: BRIEF) in
=A0 =A0 =A0 =A0Printf.printf "A: %d, B: %s\n" M.a M.b


let print_full m =3D
=A0 =A0 =A0 =A0let module M =3D (val m: FULL) in
=A0 =A0 =A0 =A0Printf.printf "A: %d, B: %s, C: %f\n" M.a M.b M.c=


module Full =3D
struct
=A0 =A0 =A0 =A0let a =3D 1
=A0 =A0 =A0 =A0let b =3D "full"
=A0 =A0 =A0 =A0let c =3D 0.5
end


module Brief =3D
struct
=A0 =A0 =A0 =A0let a =3D 0
=A0 =A0 =A0 =A0let b =3D "short"
end


let () =3D
=A0 =A0 =A0 =A0print_brief (module Brief : BRIEF);
=A0 =A0 =A0 =A0print_brief (module Full : BRIEF);
=A0 =A0 =A0 =A0print_full (module Full : FULL)


While this approach seems awfully verbose, I reckon it could be made much more palatable via some Camlp4 sugaring. =A0Nevertheless, I have a question= :
just how heavy would this approach be when compared to the object one?
And how would it fare in comparison to regular records?

Thanks for your attention!
Best regards,
Dario Teixeira

--001485e77336a8d667048d15ccf7--