caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Emulating width subtyping with 1st-class modules
@ 2010-08-05 15:02 Dario Teixeira
  2010-08-05 16:10 ` [Caml-list] " Philippe Veber
  2010-08-05 16:35 ` Alain Frisch
  0 siblings, 2 replies; 5+ messages in thread
From: Dario Teixeira @ 2010-08-05 15:02 UTC (permalink / raw)
  To: caml-list

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






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

* Re: [Caml-list] Emulating width subtyping with 1st-class modules
  2010-08-05 15:02 Emulating width subtyping with 1st-class modules Dario Teixeira
@ 2010-08-05 16:10 ` Philippe Veber
  2010-08-05 16:17   ` Alain Frisch
  2010-08-05 16:35 ` Alain Frisch
  1 sibling, 1 reply; 5+ messages in thread
From: Philippe Veber @ 2010-08-05 16:10 UTC (permalink / raw)
  To: Dario Teixeira; +Cc: caml-list

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

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 <darioteixeira@yahoo.com>

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

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

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

* Re: [Caml-list] Emulating width subtyping with 1st-class modules
  2010-08-05 16:10 ` [Caml-list] " Philippe Veber
@ 2010-08-05 16:17   ` Alain Frisch
  0 siblings, 0 replies; 5+ messages in thread
From: Alain Frisch @ 2010-08-05 16:17 UTC (permalink / raw)
  To: Philippe Veber; +Cc: Dario Teixeira, caml-list

On 08/05/2010 06:10 PM, Philippe Veber wrote:
> 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 ?

Yes, they can be marshaled. As usual with marshaling, you don't get any 
type safety.

That said, first-class modules cannot really be used to simulate 
anonymous records since they rely on nominal typing: even if S and S' 
refer to identical signatures, the types (module S) and (module S') are 
not equal.


Alain


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

* Re: [Caml-list] Emulating width subtyping with 1st-class modules
  2010-08-05 15:02 Emulating width subtyping with 1st-class modules Dario Teixeira
  2010-08-05 16:10 ` [Caml-list] " Philippe Veber
@ 2010-08-05 16:35 ` Alain Frisch
  2010-08-05 19:02   ` Dario Teixeira
  1 sibling, 1 reply; 5+ messages in thread
From: Alain Frisch @ 2010-08-05 16:35 UTC (permalink / raw)
  To: Dario Teixeira; +Cc: caml-list

On 08/05/2010 05:02 PM, Dario Teixeira wrote:
> 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:
>...
> 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?

It depends on what you call "heavy". For the syntactic aspects, as you 
say, Camlp4 can be helpful. One could also imagine future extensions in 
the compiler itself, e.g.:

- Extending the pattern algebra to directly unpack modules
   (allowing to write: "let print_brief (module M : BRIEF) = ....")

- Adding more type inference, to avoid some of the verbosity of 
first-class module. Jacques Garrigue had an experimental extension to 
allow implicit unpacking (when the context gives enough information to 
infer the module type). See the implicit-unpack branch in the OCaml 
Subversion repository.


Compared to object types, modules have some extra flexibility thanks to 
the "include" statement (you cannot "inherit" fields from an existing 
object, only from a class). For instance, you can write a function to 
merge two modules without having to enumerate all their fields:


module type S = sig
   val x: int
   (* ... *)
end

module type T = sig
   val y: int
   (* ... *)
end

module type S_T = sig
   include S
   include T
end

let merge s t =
   (module struct
     include (val s : S)
     include (val t : T)
   end : S_T)



Similar to object types, you cannot use pattern matching to deconstruct 
modules and filter on their fields.

Concerning performance, modules imply some copying to enable width 
subtyping used (in order to forget extra fields), which is not the case 
for objects. The runtime representation for modules is the same as for 
records; field access and value construction are very cheap.



Alain


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

* Re: [Caml-list] Emulating width subtyping with 1st-class modules
  2010-08-05 16:35 ` Alain Frisch
@ 2010-08-05 19:02   ` Dario Teixeira
  0 siblings, 0 replies; 5+ messages in thread
From: Dario Teixeira @ 2010-08-05 19:02 UTC (permalink / raw)
  To: Alain Frisch; +Cc: caml-list

Hi,

> It depends on what you call "heavy". For the syntactic
> aspects, as you say, Camlp4 can be helpful. One could also
> imagine future extensions in the compiler itself, e.g.:

I meant "heavy" performance-wise, which you've also clarified -- thanks!

Incidentally, has the Ocaml team ever entertained adding native support
for a record type with width subtyping?  From my type-theory-non-expert
point of view, what strikes me about width subtyping is how closely related
it seems to the structural subtyping found in the object system and in
polymorphic variants.  It would therefore fit very nicely along those
features.  Perhaps it could even leverage the same row variable mechanism.

While 1st-class-modules add yet another user-space solution to the width
subtyping problem (the other prominent approaches being the object system
and Jacques Garrigue's Polymap [1]), these user-space solutions always
imply some -- albeit small -- price to pay performance-wise.

Cheers,
Dario Teixeira

[1] http://www.math.nagoya-u.ac.jp/~garrigue/code/ocaml.html






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

end of thread, other threads:[~2010-08-05 19:02 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-08-05 15:02 Emulating width subtyping with 1st-class modules Dario Teixeira
2010-08-05 16:10 ` [Caml-list] " Philippe Veber
2010-08-05 16:17   ` Alain Frisch
2010-08-05 16:35 ` Alain Frisch
2010-08-05 19:02   ` 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).