caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* 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 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

* 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

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;
as well as URLs for NNTP newsgroup(s).