* 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