From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 7B5137FA5E for ; Wed, 10 May 2017 14:17:23 +0200 (CEST) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=ivg@ieee.org; spf=Pass smtp.mailfrom=ivg@ieee.org; spf=None smtp.helo=postmaster@mail-yw0-f172.google.com Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of ivg@ieee.org) identity=pra; client-ip=209.85.161.172; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="ivg@ieee.org"; x-sender="ivg@ieee.org"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of ivg@ieee.org designates 209.85.161.172 as permitted sender) identity=mailfrom; client-ip=209.85.161.172; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="ivg@ieee.org"; x-sender="ivg@ieee.org"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-yw0-f172.google.com) identity=helo; client-ip=209.85.161.172; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="ivg@ieee.org"; x-sender="postmaster@mail-yw0-f172.google.com"; x-conformance=sidf_compatible IronPort-PHdr: =?us-ascii?q?9a23=3AhyaykRSFaezUbplZTHhdeOLo29psv+yvbD5Q0YIu?= =?us-ascii?q?jvd0So/mwa6yYxCN2/xhgRfzUJnB7Loc0qyN4vymATRIyK3CmUhKSIZLWR4BhJ?= =?us-ascii?q?detC0bK+nBN3fGKuX3ZTcxBsVIWQwt1Xi6NU9IBJS2PAWK8TW94jEIBxrwKxd+?= =?us-ascii?q?KPjrFY7OlcS30P2594HObwlSijewZbx/IA+qoQnNq8IbnZZsJqEtxxXTv3BGYf?= =?us-ascii?q?5WxWRmJVKSmxbz+MK994N9/ipTpvws6ddOXb31cKokQ7NYCi8mM30u683wqRbD?= =?us-ascii?q?VwqP6WACXWgQjxFFHhLK7BD+Xpf2ryv6qu9w0zSUMMHqUbw5Xymp4qF2QxHqlS?= =?us-ascii?q?gHLSY0/2PZisJwgqxVow+vqQJjzIPPeo6ZKOBzc7nBcd8GR2dMWNtaWSxbAoO7?= =?us-ascii?q?aosCF+kPPfhCoIn7ulAArBy+BRWrBOPx1jBIhn723bEh0+88FgzG3RIgH90VvX?= =?us-ascii?q?TVstr6KrkdXfqyzKnSwjXOdvVb0irz5ojPdxAuu/CMXbRofMrUzkkvERnKgUiI?= =?us-ascii?q?poP5ODOV0+ENs2+d7+Z6UOKvj3YrqwR2ojip3Mgjl5HGhpgLxV/e6Cp23pw1Kc?= =?us-ascii?q?e9SE5/edKkH5pQtz2aN4trWcwuWX1nuCE/yrEevJ67ey4Kx446yBHHcPyHb5KH?= =?us-ascii?q?4g79W+qLJDd4gGppeLe4hxa060ev1/fwVsyw0FpSqypFld/MuWoQ2BPL9siGSu?= =?us-ascii?q?N98Vm62TqV0gDT7udJKl03m6rDM5Mt3KI8m54JvUnAHiL6glj6ga6Lekk+5+Sl?= =?us-ascii?q?6frrb7P7rZGGLYB0kBvxMqE2l8y/H+s4Ng8OUnCe+eum1b3j+VT1QbVEj/Eqi6?= =?us-ascii?q?XZvo3WKMYFqqKjDA9V1YEj6xm7Dzi4ytgXgX4HLFdddBKGiYjmJU3OLejmAfuj?= =?us-ascii?q?h1mgijRmyvDcMrH8A5jBM2LPnKrjcLpj80JczRA8zdFb55JaELEBJ/fzV1fwtN?= =?us-ascii?q?zGAR80KA20zPj5B9pjzI8eXniPAqCBPKPIrVCI/v4vI/WLZIINpDnyMf0l5/r3?= =?us-ascii?q?gX89mF8dZrWp0IAMaHG4G/RmO1+WbWDtgtcHC2cKvxAxQPbkiF2YAnZvYCOeVq?= =?us-ascii?q?Q96zUMIhagH4PCDtShibqA0SP9FIBbYHJCC3iBC23ha4SdRvpKYyLEceF7lTlR?= =?us-ascii?q?dKaoTccO0g2pqgT6yqZ8Zr7V5CIwtJ/u2Z5y/eKFxkJ6ziB9E8nIizLFdGpzhG?= =?us-ascii?q?5dHzI=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0DyAQDVAxNZhqyhVdFdGgEBAQECAQEBA?= =?us-ascii?q?QgBAQEBFgEBAQMBAQEJAQEBhAyBDAeDYoEEmmqCaJUZLoV2AoR1B0MUAQEBAQE?= =?us-ascii?q?BAQEBAQESAQEBCAsLCCgvgjMggkIBAQEBAgEjBBkBATcBBAsLCw0qAgIiEgEFA?= =?us-ascii?q?RwGExkCiXkFCA6lfj+LHWqBbDqDCQEBBYdlAQEBAQEFAQEBAQEBGggShk2DbYE?= =?us-ascii?q?MhChogmGCYJAnjWiHHIt/glmPEos5h0IUH4EVNoErfQhGGQaESB+CCyQ2AYZqg?= =?us-ascii?q?i4BAQE?= X-IPAS-Result: =?us-ascii?q?A0DyAQDVAxNZhqyhVdFdGgEBAQECAQEBAQgBAQEBFgEBAQM?= =?us-ascii?q?BAQEJAQEBhAyBDAeDYoEEmmqCaJUZLoV2AoR1B0MUAQEBAQEBAQEBAQESAQEBC?= =?us-ascii?q?AsLCCgvgjMggkIBAQEBAgEjBBkBATcBBAsLCw0qAgIiEgEFARwGExkCiXkFCA6?= =?us-ascii?q?lfj+LHWqBbDqDCQEBBYdlAQEBAQEFAQEBAQEBGggShk2DbYEMhChogmGCYJAnj?= =?us-ascii?q?WiHHIt/glmPEos5h0IUH4EVNoErfQhGGQaESB+CCyQ2AYZqgi4BAQE?= X-IronPort-AV: E=Sophos;i="5.38,319,1491256800"; d="scan'208,217";a="272488270" Received: from mail-yw0-f172.google.com ([209.85.161.172]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 10 May 2017 14:17:21 +0200 Received: by mail-yw0-f172.google.com with SMTP id l14so14366986ywk.1 for ; Wed, 10 May 2017 05:17:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ieee-org.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=oA7kyouFdnbl77y4MFboyKcuVLo8mdaM07aVhl3pxx4=; b=SGtqZ3h9Oa07rpOembHrnKep24GhrEuUqr+KC9PBvx3vzw4vAl1Nn1bn0rJZux10JN 9Nj8MbinFfwvyOvyIrRy9De5O5LMgxNDkq35NvIgrq/HPyO0LnmxhxXDvBUsCvuqAUW9 Bbt5a0hWqvzQZMRCr/01Is0KNUl7VmIYeVtsJZCakcJ5lGQMNZtPbIqD1ATqBP6pfewT 7wQc6YfNqRKj+uGcWuas5V1jDuT7pPn0SrtRauckPnZda6ueI+S+JOzS/TuVlSa1VHxE f3kiIHqzVMFp1TuPQV3ju1Pm3wFSebfZ1Gq33Y+kAQnlKub90Lcxolhv1WDSP3ipkTce HqUQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=oA7kyouFdnbl77y4MFboyKcuVLo8mdaM07aVhl3pxx4=; b=GvO2s+tGHzY+sglvz3wgT4sxczs1JAPNZlbSEwr7SA1gzyDF3RJLM1UNYVoqVXEouk 3vkoG/N11SQuy/W1w3GzPzqJG18IkoosUKtGFPCLmgpTf3qpR9W4bTOgOnP+6ia5V1eo J6/TGajL5PbdWimdQtPHN45E7OygpYsCAzmuFWb7vS2glq50fOsNzpzU83pu6LPotGQh 2tg5rFDuYizyJ/Whz+EDyTkXTN+vr62aB6IQzRXtMxZSu2gYZs7lHYpy1lgapdGMFMJ3 yP3MLfEvR8tE5vgejJUnkgepqaQPJDhrUBLcsCp7q6IEStA5AevBuNhPOB1LEC0oZ6hU fCwg== X-Gm-Message-State: AODbwcD24lfwHvYL9vqU7zTCyLU9HrJF2o3TuFsmarQR/WdNxoXf4bzx dPHfZY9rQtkzlmB0bjVDYE92gwWRz/a0 X-Received: by 10.129.81.194 with SMTP id f185mr4467021ywb.308.1494418639967; Wed, 10 May 2017 05:17:19 -0700 (PDT) MIME-Version: 1.0 Received: by 10.129.130.66 with HTTP; Wed, 10 May 2017 05:17:19 -0700 (PDT) In-Reply-To: <53B38F9A1D3D4732A24E8EF40B907B3F@erratique.ch> References: <1494134647.612201743@f426.i.mail.ru> <645DF7BCD0884CF29575F7F16193744D@erratique.ch> <53B38F9A1D3D4732A24E8EF40B907B3F@erratique.ch> From: Ivan Gotovchits Date: Wed, 10 May 2017 08:17:19 -0400 Message-ID: To: =?UTF-8?Q?Daniel_B=C3=BCnzli?= Cc: Alexey Egorov , caml-list Content-Type: multipart/alternative; boundary=001a11456cbc2eb944054f2a74da Subject: Re: [Caml-list] Installing library with hidden modules --001a11456cbc2eb944054f2a74da Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Hi Daniel, You're absolutely right in all details. And yes the devil is in details. I should be more precise and disclose all the ingredients of my recipe. Indeed, we are not using module aliases, and yes hiding the cmi file, of course, will not fix the flat namespace of compilation units. So, the solution that we are using for our libraries in CMU is pretty simple, for a library/project named LIB do the following: 1. prefix all internal modules with the `LIB_` 2. provide a public module `LIB.ml` that reexports some of the internals 3. describe the public interface in `LIB.mli` 4. do not install `cmi` and `mli` files for the internal modules. The public interface, of course, should not mention any internals. Given a concrete example, suppose we want to implement a Monad library and name it `monad`. The project structure would be the following: ``` monad_types.ml monad_common.ml monad_state.ml monad_state.mli monad_reader.ml monad_reader.mli ... monad.ml monad.mli ``` A possible contents of the `monad.ml`: ``` include Monad_types module State =3D Monad_state module Reader =3D Monad_reader ... ``` The contents of the `monad.mli` ``` (** Lot's of docs *) module type S =3D sig type 'a t val map : 'a t -> ('a -> 'b) -> 'b t val bind : 'a t -> ('a -> 'b t) -> 'b t val return : 'a -> 'a t ... end ... module State : sig type ('a,'e) t include S2 with type ('a,'e) t :=3D ('a,'e) t ... val run : ('a,'e) t -> 'e -> 'a * 'e end ... ``` The most controversial part is the duplication of the `mli` files. Of course, one can omit `mli` for the internals, but I myself is a strong proponent of writing mli files, and will not go that way. Thus, we decided to support the two sets of mli files. The internal set, describes our internal developer's interface, that is sometimes richer and less stable than the external. The external defines the public API, that is stable and versioned, it also must be well-documented. The internal interfaces usually do not contain documents, except technical notes and implementation details. For a real life example, look at the graphlib library: library structure: https://github.com/BinaryAnalysisPlatform/bap/tree/master/lib/graphlib oasis file: https://github.com/BinaryAnalysisPlatform/bap/blob/master/oasis/graphlib P.S. This is not the only solution. Another, probably better, solution, that I was using before, is to use packing. It is much nicer in the sense, that it solves the flat namespace issue. However, OASIS messes with the packed modules, so we were forced to use this, more ad-hoc approach. P.P.S. Strictly speaking we do not need to install even the `cmx` of the internal modules, however, their absence will prevent cross-module optimization if my understanding of the latter is correct. Best wishes, Ivan On Tue, May 9, 2017 at 5:01 PM, Daniel B=C3=BCnzli wrote: > On Monday, 8 May 2017 at 14:49, Ivan Gotovchits wrote: > > An absence of the cmi file, will prevent users from accessing the module > directly. The OASIS system provides an easy way to hide modules, with the > `InternalModules` field. OASIS will install all the necessary parts of the > module (i.e., cmxs, cma, o, a, etc), but will not install the interface > part. > > > If I'm not mistaken you can't do that with module aliases, you'll need the > cmi files of the right hand side of the alias (`module M : sig end =3D M`= is > invalid syntax). > > Besides it's not because you hide the cmi files that the names won't show > up at link time. If your "hidden" toplevel names are generic (let's say > `Config`), they will still prevent linking with other libraries that defi= ne > the same generic names. > > Again, you can't hide toplevel names using module aliases. > > Best, > > Daniel > > > --001a11456cbc2eb944054f2a74da Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
Hi Daniel,

You're absolutely right = in all details. And yes the devil is in details. I should be more precise a= nd disclose all the ingredients of my recipe. Indeed, we are not using modu= le aliases, and yes hiding the cmi=C2=A0file, of course, will not fix the f= lat namespace of compilation units. So, the solution that we are using for = our libraries in CMU is pretty simple, for a library/project named LIB do t= he following:

1. prefix all internal modules with = the `LIB_`=C2=A0
2. provide a public module `LIB.ml` that reexpor= ts some of the internals=C2=A0
3. describe the public interface i= n `LIB.mli`=C2=A0
4. do not install `cmi` and `mli` files for the= internal modules.=C2=A0

The public interface, of = course, should not mention any internals.=C2=A0

Gi= ven a concrete example, suppose we want to implement a Monad library=C2=A0a= nd name it `monad`. The project structure would be the following:

```
monad_common.ml
mona= d_state.mli
monad.mli
```

A possible contents of the `monad.ml`:

```
include Monad_types
module = State =3D Monad_state
module Reader =3D Monad_reader
..= .
```

The contents of the `monad.mli`

```
(** Lot's of docs *)
mod= ule type S =3D sig=C2=A0
=C2=A0 =C2=A0type 'a t=C2=A0
=C2=A0 =C2=A0val map : 'a t -> ('a -> 'b) -> 'b= t
=C2=A0 =C2=A0val bind : 'a t -> ('a -> 'b t)= -> 'b t
=C2=A0 =C2=A0val return : 'a -> 'a t
=C2=A0 =C2=A0...
end

...
<= div>
module State :=C2=A0sig
=C2=A0 =C2=A0 type (&#= 39;a,'e) t
=C2=A0 =C2=A0 include S2 with type ('a,'e)= t :=3D ('a,'e) t
=C2=A0 =C2=A0 ...
=C2=A0 =C2= =A0 val run : ('a,'e) t -> 'e -> 'a * 'e
end

...
```

<= br>

The most controversial part is the duplication= of the `mli` files. Of course, one can omit `mli`=C2=A0for the internals, = but I myself is a strong proponent of writing mli files, and will not go th= at way. Thus, we decided to support the two sets of mli=C2=A0files. The int= ernal set, describes our internal developer's interface, that is someti= mes richer and less stable=C2=A0than the external. The external defines the= public API, that is stable and versioned, it also must be well-documented.= The internal interfaces usually do not contain documents, except technical= notes and implementation details.=C2=A0


For a real life example, look at the=C2=A0graphlib=C2=A0library:=



P.S. Thi= s is not the only solution. Another, probably better, solution, that I was = using before, is to use packing. It is much nicer in the sense, that it sol= ves the flat namespace issue. However, OASIS messes with the packed modules= , so we were forced to use this, more ad-hoc approach.=C2=A0

=
P.P.S. Strictly speaking we do not need to install even the `cmx= ` of the internal modules, however, their absence will prevent cross-module= optimization=C2=A0if my understanding of the latter is correct.
=
Best wishes,
Ivan


On Tue, May 9, 2017 at = 5:01 PM, Daniel B=C3=BCnzli <daniel.buenzli@erratique.ch>= wrote:
On Monday= , 8 May 2017 at 14:49, Ivan Gotovchits wrote:
> An absence of the cmi file, will prevent users from accessing the modu= le directly. The OASIS system provides an easy way to hide modules, with th= e `InternalModules` field. OASIS will install all the necessary parts of th= e module (i.e., cmxs, cma, o, a, etc), but will not install the interface p= art.


If I'm not mistaken you can't do that with module aliases, y= ou'll need the cmi files of the right hand side of the alias (`module M= : sig end =3D M` is invalid syntax).

Besides it's not because you hide the cmi files that the names won'= t show up at link time. If your "hidden" toplevel names are gener= ic (let's say `Config`), they will still prevent linking with other lib= raries that define the same generic names.

Again, you can't hide toplevel names using module aliases.

Best,

Daniel



--001a11456cbc2eb944054f2a74da--