* Hiding private types
@ 2009-02-10 17:14 David Rajchenbach-Teller
2009-02-10 18:05 ` [Caml-list] " Martin Jambon
2009-02-10 18:14 ` Daniel Bünzli
0 siblings, 2 replies; 4+ messages in thread
From: David Rajchenbach-Teller @ 2009-02-10 17:14 UTC (permalink / raw)
To: OCaml
Dear list,
I'm looking for a way to remove one or two annoyances of Batteries,
which are related to private magic leaking into the type system and into
the documentation.
We define a module [IO] with, among other things, a type [output]. In
fact, in order to avoid circular dependencies, [output] is actually
defined in a private module [InnerIO], which lets other modules such as
[ExtString] use [output] and still be used by [IO]. For instance,
[ExtString] defines a function [print : InnerIO.output -> string ->
unit].
At a later stage, we pack [IO], [InnerIO], [ExtString] and others into a
module [Extlib] and we later define a module [Batteries] containing
module IO = Extlib.IO
module String = ExtString.String
etc.
Now, all of this works. Unfortunately, the types visible by the user,
either from the toplevel, from error messages or from -dannot, reveal
too much from the inner workings of Batteries.
For instance, [InnerIO], as implied by the name, is private. The
existence of this module should not be visible by the user.
Unfortunately, on the toplevel, we have
# String.print;;
- : Extlib.InnerIO.output -> string -> unit = <fun>
Two abstractions have leaked out:
* the existence of [InnerIO]
* the existence of [Extlib]
I would rather have
# String.print;;
- : IO.output -> string -> unit = <fun>
or, at worst
# String.print;;
- : Batteries.IO.output -> string -> unit = <fun>
Does anyone have an idea of how we could/should do this?
Thanks,
David
--
David Teller-Rajchenbach
Security of Distributed Systems
http://www.univ-orleans.fr/lifo/Members/David.Teller
« Ce matin Un crétin A tué un chercheur. » (air connu)
Latest News of French Research: System being liquidated. Researchers angry.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Hiding private types
2009-02-10 17:14 Hiding private types David Rajchenbach-Teller
@ 2009-02-10 18:05 ` Martin Jambon
2009-02-10 18:24 ` David Rajchenbach-Teller
2009-02-10 18:14 ` Daniel Bünzli
1 sibling, 1 reply; 4+ messages in thread
From: Martin Jambon @ 2009-02-10 18:05 UTC (permalink / raw)
To: David Rajchenbach-Teller; +Cc: OCaml
David Rajchenbach-Teller wrote:
> Dear list,
>
> I'm looking for a way to remove one or two annoyances of Batteries,
> which are related to private magic leaking into the type system and into
> the documentation.
>
>
>
> We define a module [IO] with, among other things, a type [output]. In
> fact, in order to avoid circular dependencies, [output] is actually
> defined in a private module [InnerIO], which lets other modules such as
> [ExtString] use [output] and still be used by [IO]. For instance,
> [ExtString] defines a function [print : InnerIO.output -> string ->
> unit].
>
> At a later stage, we pack [IO], [InnerIO], [ExtString] and others into a
> module [Extlib] and we later define a module [Batteries] containing
>
> module IO = Extlib.IO
> module String = ExtString.String
>
> etc.
>
>
> Now, all of this works. Unfortunately, the types visible by the user,
> either from the toplevel, from error messages or from -dannot, reveal
> too much from the inner workings of Batteries.
>
> For instance, [InnerIO], as implied by the name, is private. The
> existence of this module should not be visible by the user.
> Unfortunately, on the toplevel, we have
>
> # String.print;;
> - : Extlib.InnerIO.output -> string -> unit = <fun>
>
> Two abstractions have leaked out:
> * the existence of [InnerIO]
> * the existence of [Extlib]
>
> I would rather have
>
> # String.print;;
> - : IO.output -> string -> unit = <fun>
>
> or, at worst
>
> # String.print;;
> - : Batteries.IO.output -> string -> unit = <fun>
>
>
> Does anyone have an idea of how we could/should do this?
It looks like you can applying a signature to Batteries.IO does the trick:
(* IO's signature *)
module type A_sig =
sig
type t
val add : t -> t -> t
val create : unit -> t
end
(* Extlib.IO *)
module A : A_sig =
struct
type t = int
let add = ( + )
let create () = 1
end
(* Batteries.IO, version 1 *)
module B = A
(* Batteries.IO, version 2 *)
module C : A_sig = A
This is the problem that you're having, i.e. A.t appears in the error message:
# B.create () = 1;;
Characters 14-15:
B.create () = 1;;
^
This expression has type int but is here used with type B.t = A.t
This looks better:
# C.create () = A.create ();;
Characters 14-25:
C.create () = A.create ();;
^^^^^^^^^^^
This expression has type A.t but is here used with type C.t
I just hope it works for your problem.
Martin
--
http://mjambon.com/
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Hiding private types
2009-02-10 18:05 ` [Caml-list] " Martin Jambon
@ 2009-02-10 18:24 ` David Rajchenbach-Teller
0 siblings, 0 replies; 4+ messages in thread
From: David Rajchenbach-Teller @ 2009-02-10 18:24 UTC (permalink / raw)
To: Martin Jambon; +Cc: OCaml
On Tue, 2009-02-10 at 19:05 +0100, Martin Jambon wrote:
> (* IO's signature *)
> module type A_sig =
> sig
> type t
> val add : t -> t -> t
> val create : unit -> t
> end
>(* Extlib.IO *)
> module A : A_sig =
> struct
> type t = int
> let add = ( + )
> let create () = 1
> end
>
Thanks.
I can probably do that, if I find a nice way of
* extracting the signature and contents from .mli files
* replacing every occurrence of the private types of IO.mli with an
abstract type
* replacing every occurrence of these types in modules which use
InnerIO.output with IO.output
Of course, if anyone can think of a simpler solution, I'm interested.
> I just hope it works for your problem.
>
So do I, it's going to take some work just to reach a testable solution.
Thanks,
David
>
--
David Teller-Rajchenbach
Security of Distributed Systems
http://www.univ-orleans.fr/lifo/Members/David.Teller
« Ce matin Un crétin A tué un chercheur. » (air connu)
Latest News of French Research: System being liquidated. Researchers
angry.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] Hiding private types
2009-02-10 17:14 Hiding private types David Rajchenbach-Teller
2009-02-10 18:05 ` [Caml-list] " Martin Jambon
@ 2009-02-10 18:14 ` Daniel Bünzli
1 sibling, 0 replies; 4+ messages in thread
From: Daniel Bünzli @ 2009-02-10 18:14 UTC (permalink / raw)
To: David Rajchenbach-Teller; +Cc: OCaml
Le 10 févr. 09 à 18:14, David Rajchenbach-Teller a écrit :
> Does anyone have an idea of how we could/should do this?
I already encoutered these kind of visilibility problems, I'm not sure
the following applies to your case but it's a case I managed to solve
(e.g. in react [1]).
Suppose you have two types Pack.a and Pack.b, and two submodule Pack.A
and Pack.B that define functions on the respective types. In these two
modules you also want to
have Pack.A.t = Pack.a and Pack.B.t = Pack.b so that the submodules
can be given to the usual functors.
The problem is then that when you use functions from Pack.A in the
toplevel you get values of type A.Pack.t = Pack.a but you would like
Pack.a to be printed. The solution is simple : in the mli of A and B
the signature of functions should use Pack.a and Pack.b, in other
words your signature should look like this :
module Pack = struct
type a
type b
module A : sig
type t = a
val create : unit -> a (* instead of unit -> t *)
end
module B : sig
type t = b
val create : unit -> b (* instead of unit -> t *)
end
end
This way you never get Pack.A.t and Pack.B.t in errors and in the
toplevel unless you request it by a type annotation (or use functors).
But I don't know if you can reorder your definitions to match this
pattern.
Best,
Daniel
[1] http://erratique.ch/software/react
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2009-02-10 18:24 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-02-10 17:14 Hiding private types David Rajchenbach-Teller
2009-02-10 18:05 ` [Caml-list] " Martin Jambon
2009-02-10 18:24 ` David Rajchenbach-Teller
2009-02-10 18:14 ` Daniel Bünzli
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox