caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* RE: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
@ 2016-07-10 11:57 David Allsopp
  2016-07-10 19:45 ` Gerd Stolpmann
  0 siblings, 1 reply; 23+ messages in thread
From: David Allsopp @ 2016-07-10 11:57 UTC (permalink / raw)
  To: caml-list

Gerd Stolpmann wrote:
<snip>
> For example, when there is
> 
> open M1
> open M2
> 
> at the beginning of a file, ocamldep doesn't know whether M2 is 
> another top-level module, or whether it is a submodule of M1. ocamldep 
> normally errs on the side of generating too many dependencies, which 
> is then tried to be corrected by only accepting those deps 
> corresponding to existing files. In this example, this would mean that 
> a dependency to M2 is emitted when there is a file M2.ml. Note that 
> this is wrong when M2 is actually a submodule of M1 AND the file M2.ml
exists.

I hate the open statement (indeed, I hate its equivalent in every language
I've ever used), which limits how much I tend to consider it: but this is
awful in so many ways. Do you happen to know how common it is to open one
module and then open a *unqualified* submodule of that (i.e. where M2 is a
submodule of M1)?

It strikes me that that pattern requires not a new language convention as
you go on to say, but at least two warnings and possibly a deprecation to
discourage its ever being written! The first warning (including a
deprecation message) should state that [open M2] relies on the previous
[open M1] (similar idea as Warning 40) and the second warning should trigger
if M2.cmi also exists indicating that M1.M2 has been opened rather than the
actual M2 module (again, with a deprecation message). Both warnings being
eliminated by giving:

open M1
open M1.M2

The big stability nightmare that I see there is you have:

open ThirdPartyLibrary
open MyOwnProjectModule

and a new version of ThirdPartyLibrary adds a submodule MyOwnProjectModule.
It's also unfortunate that if M1, M1.M2 and "M2.ml" all define a value
[foo], it's not possible to open M1, M1.M2 and "M2.ml" in a way which gives
you "M2.ml"'s [foo] (if you follow that highly contrived example...!)


David



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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-10 11:57 [Caml-list] Warnings opening modules (was: why is building ocaml hard?) David Allsopp
@ 2016-07-10 19:45 ` Gerd Stolpmann
  2016-07-13 12:08   ` David Allsopp
  0 siblings, 1 reply; 23+ messages in thread
From: Gerd Stolpmann @ 2016-07-10 19:45 UTC (permalink / raw)
  To: David Allsopp; +Cc: caml-list

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

Am Sonntag, den 10.07.2016, 12:57 +0100 schrieb David Allsopp:
> Gerd Stolpmann wrote:
> <snip>
> > For example, when there is
> > 
> > open M1
> > open M2
> > 
> > at the beginning of a file, ocamldep doesn't know whether M2 is 
> > another top-level module, or whether it is a submodule of M1. ocamldep 
> > normally errs on the side of generating too many dependencies, which 
> > is then tried to be corrected by only accepting those deps 
> > corresponding to existing files. In this example, this would mean that 
> > a dependency to M2 is emitted when there is a file M2.ml. Note that 
> > this is wrong when M2 is actually a submodule of M1 AND the file M2.ml
> exists.
> 
> I hate the open statement (indeed, I hate its equivalent in every language
> I've ever used), which limits how much I tend to consider it: but this is
> awful in so many ways. Do you happen to know how common it is to open one
> module and then open a *unqualified* submodule of that (i.e. where M2 is a
> submodule of M1)?

I cannot give numbers, but imagine M2 is actually called Types or Util.
This trap is a real one. It is not one that makes the build tools
completely unusable, but it adds a litte bit of the unreliability that
is observed by the users. If we want to address these issues ocamldep
needs to be part of this effort.

Successive opens are quite normal when you have packed libraries.

> It strikes me that that pattern requires not a new language convention as
> you go on to say, but at least two warnings and possibly a deprecation to
> discourage its ever being written! The first warning (including a
> deprecation message) should state that [open M2] relies on the previous
> [open M1] (similar idea as Warning 40) and the second warning should trigger
> if M2.cmi also exists indicating that M1.M2 has been opened rather than the
> actual M2 module (again, with a deprecation message). Both warnings being
> eliminated by giving:
> 
> open M1
> open M1.M2
> 
> The big stability nightmare that I see there is you have:
> 
> open ThirdPartyLibrary
> open MyOwnProjectModule
> 
> and a new version of ThirdPartyLibrary adds a submodule MyOwnProjectModule.

I think that we need a syntax for toplevel module paths (e.g. I
suggested "open ^MyOwnProjectModule", resembling anchored regular
expressions).

Gerd

> It's also unfortunate that if M1, M1.M2 and "M2.ml" all define a value
> [foo], it's not possible to open M1, M1.M2 and "M2.ml" in a way which gives
> you "M2.ml"'s [foo] (if you follow that highly contrived example...!)
> 
> 
> David
> 
> 
> 

-- 
------------------------------------------------------------
Gerd Stolpmann, Darmstadt, Germany    gerd@gerd-stolpmann.de
My OCaml site:          http://www.camlcity.org
Contact details:        http://www.camlcity.org/contact.html
Company homepage:       http://www.gerd-stolpmann.de
------------------------------------------------------------


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* RE: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-10 19:45 ` Gerd Stolpmann
@ 2016-07-13 12:08   ` David Allsopp
  2016-07-13 12:20     ` Gerd Stolpmann
  2016-07-14  9:03     ` Goswin von Brederlow
  0 siblings, 2 replies; 23+ messages in thread
From: David Allsopp @ 2016-07-13 12:08 UTC (permalink / raw)
  To: Gerd Stolpmann; +Cc: caml-list

Gerd Stolpmann wrote:
> Am Sonntag, den 10.07.2016, 12:57 +0100 schrieb David Allsopp:
> > Gerd Stolpmann wrote:
> > <snip>
> > > For example, when there is
> > >
> > > open M1
> > > open M2
> > >
> > > at the beginning of a file, ocamldep doesn't know whether M2 is
> > > another top-level module, or whether it is a submodule of M1.
> > > ocamldep normally errs on the side of generating too many
> > > dependencies, which is then tried to be corrected by only accepting
> > > those deps corresponding to existing files. In this example, this
> > > would mean that a dependency to M2 is emitted when there is a file
> > > M2.ml. Note that this is wrong when M2 is actually a submodule of M1
> > > AND the file M2.ml
> > exists.
> >
> > I hate the open statement (indeed, I hate its equivalent in every
> > language I've ever used), which limits how much I tend to consider it:
> > but this is awful in so many ways. Do you happen to know how common it
> > is to open one module and then open a *unqualified* submodule of that
> > (i.e. where M2 is a submodule of M1)?
> 
> I cannot give numbers, but imagine M2 is actually called Types or Util.
> This trap is a real one. It is not one that makes the build tools
> completely unusable, but it adds a litte bit of the unreliability that is
> observed by the users. If we want to address these issues ocamldep needs
> to be part of this effort.
> 
> Successive opens are quite normal when you have packed libraries.

Sure, but in which case, isn't encouraging (and eventually mandating)

open ReallyCoolLibraryPack.Util

considerably better than:

open ReallyCoolLibraryPack
(* myriad more open statements *)
open Util

and eventually solves considerably more problems.

> > It strikes me that that pattern requires not a new language convention
> > as you go on to say, but at least two warnings and possibly a
> > deprecation to discourage its ever being written! The first warning
> > (including a deprecation message) should state that [open M2] relies
> > on the previous [open M1] (similar idea as Warning 40) and the second
> > warning should trigger if M2.cmi also exists indicating that M1.M2 has
> > been opened rather than the actual M2 module (again, with a
> > deprecation message). Both warnings being eliminated by giving:
> >
> > open M1
> > open M1.M2
> >
> > The big stability nightmare that I see there is you have:
> >
> > open ThirdPartyLibrary
> > open MyOwnProjectModule
> >
> > and a new version of ThirdPartyLibrary adds a submodule
> MyOwnProjectModule.
> 
> I think that we need a syntax for toplevel module paths (e.g. I suggested
> "open ^MyOwnProjectModule", resembling anchored regular expressions).

Indeed, but rather than adding yet another piece of syntax, does it cause so much pain to move in the direction of just making the open declaration always require a toplevel module path?


David


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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-13 12:08   ` David Allsopp
@ 2016-07-13 12:20     ` Gerd Stolpmann
  2016-07-13 12:30       ` David Allsopp
  2016-07-14  9:03     ` Goswin von Brederlow
  1 sibling, 1 reply; 23+ messages in thread
From: Gerd Stolpmann @ 2016-07-13 12:20 UTC (permalink / raw)
  To: David Allsopp; +Cc: caml-list

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

Am Mittwoch, den 13.07.2016, 12:08 +0000 schrieb David Allsopp:
> > I think that we need a syntax for toplevel module paths (e.g. I suggested
> > "open ^MyOwnProjectModule", resembling anchored regular expressions).
> 
> Indeed, but rather than adding yet another piece of syntax, does it cause so much pain to move in the direction of just making the open declaration always require a toplevel module path?

I'm suggesting that mainly because it makes the transition easier - the
old and the new conventions could be used in parallel. Also, I don't
know whether there are actually reasonable applications of relative
module paths. It would be good to hear from other users about that.

Gerd
-- 
------------------------------------------------------------
Gerd Stolpmann, Darmstadt, Germany    gerd@gerd-stolpmann.de
My OCaml site:          http://www.camlcity.org
Contact details:        http://www.camlcity.org/contact.html
Company homepage:       http://www.gerd-stolpmann.de
------------------------------------------------------------


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* RE: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-13 12:20     ` Gerd Stolpmann
@ 2016-07-13 12:30       ` David Allsopp
  0 siblings, 0 replies; 23+ messages in thread
From: David Allsopp @ 2016-07-13 12:30 UTC (permalink / raw)
  To: Gerd Stolpmann; +Cc: caml-list

Gerd Stolpmann wrote:
> Am Mittwoch, den 13.07.2016, 12:08 +0000 schrieb David Allsopp:
> > > I think that we need a syntax for toplevel module paths (e.g. I
> > > suggested "open ^MyOwnProjectModule", resembling anchored regular
> expressions).
> >
> > Indeed, but rather than adding yet another piece of syntax, does it
> cause so much pain to move in the direction of just making the open
> declaration always require a toplevel module path?
> 
> I'm suggesting that mainly because it makes the transition easier - the
> old and the new conventions could be used in parallel.

Agreed - but couldn't that therefore be done "my way" with a compiler switch (cf. -safe-string, etc.)?

> Also, I don't know whether there are actually reasonable applications
> of relative module paths. It would be good to hear from other users
> about that.

Also agreed - though, so far, I don't think unqualified opening of packed modules is one of the reasonable examples :o)


David

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-13 12:08   ` David Allsopp
  2016-07-13 12:20     ` Gerd Stolpmann
@ 2016-07-14  9:03     ` Goswin von Brederlow
  2016-07-15  9:52       ` David Allsopp
  1 sibling, 1 reply; 23+ messages in thread
From: Goswin von Brederlow @ 2016-07-14  9:03 UTC (permalink / raw)
  To: caml-list

On Wed, Jul 13, 2016 at 12:08:30PM +0000, David Allsopp wrote:
> Gerd Stolpmann wrote:
> > Am Sonntag, den 10.07.2016, 12:57 +0100 schrieb David Allsopp:
> > > Gerd Stolpmann wrote:
> > > <snip>
> > > > For example, when there is
> > > >
> > > > open M1
> > > > open M2
> > > >
> > > > at the beginning of a file, ocamldep doesn't know whether M2 is
> > > > another top-level module, or whether it is a submodule of M1.
> > > > ocamldep normally errs on the side of generating too many
> > > > dependencies, which is then tried to be corrected by only accepting
> > > > those deps corresponding to existing files. In this example, this
> > > > would mean that a dependency to M2 is emitted when there is a file
> > > > M2.ml. Note that this is wrong when M2 is actually a submodule of M1
> > > > AND the file M2.ml
> > > exists.
> > >
> > > I hate the open statement (indeed, I hate its equivalent in every
> > > language I've ever used), which limits how much I tend to consider it:
> > > but this is awful in so many ways. Do you happen to know how common it
> > > is to open one module and then open a *unqualified* submodule of that
> > > (i.e. where M2 is a submodule of M1)?
> > 
> > I cannot give numbers, but imagine M2 is actually called Types or Util.
> > This trap is a real one. It is not one that makes the build tools
> > completely unusable, but it adds a litte bit of the unreliability that is
> > observed by the users. If we want to address these issues ocamldep needs
> > to be part of this effort.
> > 
> > Successive opens are quite normal when you have packed libraries.
> 
> Sure, but in which case, isn't encouraging (and eventually mandating)
> 
> open ReallyCoolLibraryPack.Util
> 
> considerably better than:
> 
> open ReallyCoolLibraryPack
> (* myriad more open statements *)
> open Util
> 
> and eventually solves considerably more problems.

How does that change anything? A (for me) more common code would be:

    open ReallyCoolLibraryPack
    (* myriad more open statements *)

    Util.foo bla baz
    module Bla = Util.MAKE(M : FOOABLE)

You still get the same dependency on ReallyCoolLibraryPack.Util,
ReallyCoolLibraryPack.Util.MAKE, ReallyCoolLibraryPack.FOOABLE, ...
without successive opens.

> > > It strikes me that that pattern requires not a new language convention
> > > as you go on to say, but at least two warnings and possibly a
> > > deprecation to discourage its ever being written! The first warning
> > > (including a deprecation message) should state that [open M2] relies
> > > on the previous [open M1] (similar idea as Warning 40) and the second
> > > warning should trigger if M2.cmi also exists indicating that M1.M2 has
> > > been opened rather than the actual M2 module (again, with a
> > > deprecation message). Both warnings being eliminated by giving:
> > >
> > > open M1
> > > open M1.M2
> > >
> > > The big stability nightmare that I see there is you have:
> > >
> > > open ThirdPartyLibrary
> > > open MyOwnProjectModule
> > >
> > > and a new version of ThirdPartyLibrary adds a submodule
> > MyOwnProjectModule.
> > 
> > I think that we need a syntax for toplevel module paths (e.g. I suggested
> > "open ^MyOwnProjectModule", resembling anchored regular expressions).
> 
> Indeed, but rather than adding yet another piece of syntax, does it cause so much pain to move in the direction of just making the open declaration always require a toplevel module path?

It's not just open but every module path anywhere.
 
> David

MfG
	Goswin

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

* RE: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-14  9:03     ` Goswin von Brederlow
@ 2016-07-15  9:52       ` David Allsopp
  2016-07-15 16:13         ` Hendrik Boom
  0 siblings, 1 reply; 23+ messages in thread
From: David Allsopp @ 2016-07-15  9:52 UTC (permalink / raw)
  To: caml-list

Goswin von Brederlow wrote:
> On Wed, Jul 13, 2016 at 12:08:30PM +0000, David Allsopp wrote:
> > Gerd Stolpmann wrote:
> > > Am Sonntag, den 10.07.2016, 12:57 +0100 schrieb David Allsopp:
> > > > Gerd Stolpmann wrote:
> > > > <snip>
> > > > > For example, when there is
> > > > >
> > > > > open M1
> > > > > open M2
> > > > >
> > > > > at the beginning of a file, ocamldep doesn't know whether M2 is
> > > > > another top-level module, or whether it is a submodule of M1.
> > > > > ocamldep normally errs on the side of generating too many
> > > > > dependencies, which is then tried to be corrected by only
> > > > > accepting those deps corresponding to existing files. In this
> > > > > example, this would mean that a dependency to M2 is emitted when
> > > > > there is a file M2.ml. Note that this is wrong when M2 is
> > > > > actually a submodule of M1 AND the file M2.ml
> > > > exists.
> > > >
> > > > I hate the open statement (indeed, I hate its equivalent in every
> > > > language I've ever used), which limits how much I tend to consider
> it:
> > > > but this is awful in so many ways. Do you happen to know how
> > > > common it is to open one module and then open a *unqualified*
> > > > submodule of that (i.e. where M2 is a submodule of M1)?
> > >
> > > I cannot give numbers, but imagine M2 is actually called Types or
> Util.
> > > This trap is a real one. It is not one that makes the build tools
> > > completely unusable, but it adds a litte bit of the unreliability
> > > that is observed by the users. If we want to address these issues
> > > ocamldep needs to be part of this effort.
> > >
> > > Successive opens are quite normal when you have packed libraries.
> >
> > Sure, but in which case, isn't encouraging (and eventually mandating)
> >
> > open ReallyCoolLibraryPack.Util
> >
> > considerably better than:
> >
> > open ReallyCoolLibraryPack
> > (* myriad more open statements *)
> > open Util
> >
> > and eventually solves considerably more problems.
> 
> How does that change anything?

I don't follow what you mean - what I propose changing is that [open Util]
would cause a warning and eventually, in some future version of OCaml, be
rejected by the compiler. The problem it would solve is that
ocamldep/whatever knows that open Foo always refers to a toplevel (or fully
qualified) module path.

> A (for me) more common code would be:
> 
>     open ReallyCoolLibraryPack
>     (* myriad more open statements *)
> 
>     Util.foo bla baz
>     module Bla = Util.MAKE(M : FOOABLE)
> 
> You still get the same dependency on ReallyCoolLibraryPack.Util,
> ReallyCoolLibraryPack.Util.MAKE, ReallyCoolLibraryPack.FOOABLE, ...
> without successive opens.

Indeed, that's my preference, although I'm stupidly picky and actually
prefer to write:

module Util = ReallyCoolLibraryPack.Util

but that comes under my list of "strange habits which normal people don't
agree with" :o) I'm allergic to anything which involves a wildcard ([open
ReallyCoolLibraryPack] being rather too like writing [import
ReallyCoolLibraryPack.*;])

> > > > It strikes me that that pattern requires not a new language
> > > > convention as you go on to say, but at least two warnings and
> > > > possibly a deprecation to discourage its ever being written! The
> > > > first warning (including a deprecation message) should state that
> > > > [open M2] relies on the previous [open M1] (similar idea as
> > > > Warning 40) and the second warning should trigger if M2.cmi also
> > > > exists indicating that M1.M2 has been opened rather than the
> > > > actual M2 module (again, with a deprecation message). Both warnings
> being eliminated by giving:
> > > >
> > > > open M1
> > > > open M1.M2
> > > >
> > > > The big stability nightmare that I see there is you have:
> > > >
> > > > open ThirdPartyLibrary
> > > > open MyOwnProjectModule
> > > >
> > > > and a new version of ThirdPartyLibrary adds a submodule
> > > MyOwnProjectModule.
> > >
> > > I think that we need a syntax for toplevel module paths (e.g. I
> > > suggested "open ^MyOwnProjectModule", resembling anchored regular
> expressions).
> >
> > Indeed, but rather than adding yet another piece of syntax, does it
> cause so much pain to move in the direction of just making the open
> declaration always require a toplevel module path?
> 
> It's not just open but every module path anywhere.

Possibly addressing a separate problem here. However, that can be fixed (I
think) by adding an warning if an open statement shadows locally available
modules. e.g. if module FooPack contains module Foo then [open FooPack]
would trigger a warning if there is another module Foo either already
defined previously in the ml file (for the very ugly case where your [open]
statements are littered through your sources!) or if it's defined by having
Foo.ml/Foo.cmi/Foo.cmo present. In this case, you'd have to use the form
[module Foo = FooPack.Foo] to avoid the warning - and of course you then
provide syntax which ocamldep can use to work out the correct dependency.

However, that's a problem in both ideas, I think?


David



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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15  9:52       ` David Allsopp
@ 2016-07-15 16:13         ` Hendrik Boom
  2016-07-15 16:57           ` Yotam Barnoy
                             ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: Hendrik Boom @ 2016-07-15 16:13 UTC (permalink / raw)
  To: caml-list

On Fri, Jul 15, 2016 at 10:52:38AM +0100, David Allsopp wrote:
> Goswin von Brederlow wrote:
> 
> I don't follow what you mean - what I propose changing is that [open Util]
> would cause a warning and eventually, in some future version of OCaml, be
> rejected by the compiler. The problem it would solve is that
> ocamldep/whatever knows that open Foo always refers to a toplevel (or fully
> qualified) module path.
> 
> > A (for me) more common code would be:
> > 
> >     open ReallyCoolLibraryPack
> >     (* myriad more open statements *)
> > 
> >     Util.foo bla baz
> >     module Bla = Util.MAKE(M : FOOABLE)
> > 
> > You still get the same dependency on ReallyCoolLibraryPack.Util,
> > ReallyCoolLibraryPack.Util.MAKE, ReallyCoolLibraryPack.FOOABLE, ...
> > without successive opens.
> 
> Indeed, that's my preference, although I'm stupidly picky and actually
> prefer to write:
> 
> module Util = ReallyCoolLibraryPack.Util
> 
> but that comes under my list of "strange habits which normal people don't
> agree with" :o) I'm allergic to anything which involves a wildcard ([open
> ReallyCoolLibraryPack] being rather too like writing [import
> ReallyCoolLibraryPack.*;])

And that's a real problem -- that fact that openning a module can fill 
the namespace with lots of stray identifiers, which the user does not 
control.

It may reduce the amount of code you have to write.

But it makes the code unstable in the long run, and it makes it hard to 
read.  The naive reader will encounter identifiers and have no idea 
where to look for their definitions.

It's not just a problem with modules that define modules.  It'a a 
problem with modules that define anything.

To alleviate this, either specify explicitly what names you are 
accepting definitions of when you open a module, or, after you open a 
module, mention the module name very time you use one if its defined 
names, as, Module.name instead of just name.

And make the compiler check this.  Withiut a constraint like this, I 
find much OCaml code incomprehensible.

Or is there some kind of code browsing tool that explicates all this?

-- hendrik

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 16:13         ` Hendrik Boom
@ 2016-07-15 16:57           ` Yotam Barnoy
  2016-07-15 18:09             ` Jeremy Yallop
  2016-07-15 18:50             ` Alain Frisch
  2016-07-15 17:04           ` Gerd Stolpmann
  2016-07-16  7:40           ` Petter A. Urkedal
  2 siblings, 2 replies; 23+ messages in thread
From: Yotam Barnoy @ 2016-07-15 16:57 UTC (permalink / raw)
  To: Hendrik Boom; +Cc: Ocaml Mailing List

The problem seems to stem from the fact that the same open statements
which we use to import code (and which are available in every
language) are also used as part of OCaml's super-flexible module
system. This makes it hard to come up with easy, simple shortcuts for
functionality available in other languages, because it needs to fit in
the far more complex general module language.

In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
exactly what I want to import. This is because haskell has a
half-baked module system that isn't nearly as powerful as OCaml's,
which allows it to create syntax that doesn't need to go anywhere but
at the toplevel.

We need this functionality in OCaml, but the closest thing is to say
'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
= A.t end'

I'm not sure if there's a performance cost to doing things this way,
but it's also incredibly verbose and therefore nearly unusable in the
general case simply because it needs to fit into the general module
language.

Additionally, haskell handles module hierarchies gracefully (tying
them to the OS filesystem), while OCaml is stuck with a flat
hierarchy, needing modular tricks to get the same hierarchies that
other languages have naturally (via specialized syntax).

The generality of OCaml's module language is killing its usability for
the most common cases.

On Fri, Jul 15, 2016 at 12:13 PM, Hendrik Boom <hendrik@topoi.pooq.com> wrote:
> On Fri, Jul 15, 2016 at 10:52:38AM +0100, David Allsopp wrote:
>> Goswin von Brederlow wrote:
>>
>> I don't follow what you mean - what I propose changing is that [open Util]
>> would cause a warning and eventually, in some future version of OCaml, be
>> rejected by the compiler. The problem it would solve is that
>> ocamldep/whatever knows that open Foo always refers to a toplevel (or fully
>> qualified) module path.
>>
>> > A (for me) more common code would be:
>> >
>> >     open ReallyCoolLibraryPack
>> >     (* myriad more open statements *)
>> >
>> >     Util.foo bla baz
>> >     module Bla = Util.MAKE(M : FOOABLE)
>> >
>> > You still get the same dependency on ReallyCoolLibraryPack.Util,
>> > ReallyCoolLibraryPack.Util.MAKE, ReallyCoolLibraryPack.FOOABLE, ...
>> > without successive opens.
>>
>> Indeed, that's my preference, although I'm stupidly picky and actually
>> prefer to write:
>>
>> module Util = ReallyCoolLibraryPack.Util
>>
>> but that comes under my list of "strange habits which normal people don't
>> agree with" :o) I'm allergic to anything which involves a wildcard ([open
>> ReallyCoolLibraryPack] being rather too like writing [import
>> ReallyCoolLibraryPack.*;])
>
> And that's a real problem -- that fact that openning a module can fill
> the namespace with lots of stray identifiers, which the user does not
> control.
>
> It may reduce the amount of code you have to write.
>
> But it makes the code unstable in the long run, and it makes it hard to
> read.  The naive reader will encounter identifiers and have no idea
> where to look for their definitions.
>
> It's not just a problem with modules that define modules.  It'a a
> problem with modules that define anything.
>
> To alleviate this, either specify explicitly what names you are
> accepting definitions of when you open a module, or, after you open a
> module, mention the module name very time you use one if its defined
> names, as, Module.name instead of just name.
>
> And make the compiler check this.  Withiut a constraint like this, I
> find much OCaml code incomprehensible.
>
> Or is there some kind of code browsing tool that explicates all this?
>
> -- hendrik
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 16:13         ` Hendrik Boom
  2016-07-15 16:57           ` Yotam Barnoy
@ 2016-07-15 17:04           ` Gerd Stolpmann
  2016-07-20  7:49             ` Louis Gesbert
  2016-07-16  7:40           ` Petter A. Urkedal
  2 siblings, 1 reply; 23+ messages in thread
From: Gerd Stolpmann @ 2016-07-15 17:04 UTC (permalink / raw)
  To: Hendrik Boom; +Cc: caml-list

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

Am Freitag, den 15.07.2016, 12:13 -0400 schrieb Hendrik Boom:
> Or is there some kind of code browsing tool that explicates all this?

I don't know any tool that just shows the full path of identifiers.
Merlin could do it (has all infos) but it doesn't so far. It "only"
shows the type (also useful, but in a different way).

Gerd
-- 
------------------------------------------------------------
Gerd Stolpmann, Darmstadt, Germany    gerd@gerd-stolpmann.de
My OCaml site:          http://www.camlcity.org
Contact details:        http://www.camlcity.org/contact.html
Company homepage:       http://www.gerd-stolpmann.de
------------------------------------------------------------


[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 16:57           ` Yotam Barnoy
@ 2016-07-15 18:09             ` Jeremy Yallop
  2016-07-15 18:26               ` Hendrik Boom
  2016-07-15 18:58               ` Yotam Barnoy
  2016-07-15 18:50             ` Alain Frisch
  1 sibling, 2 replies; 23+ messages in thread
From: Jeremy Yallop @ 2016-07-15 18:09 UTC (permalink / raw)
  To: Yotam Barnoy; +Cc: Hendrik Boom, Ocaml Mailing List

On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
> exactly what I want to import. This is because haskell has a
> half-baked module system that isn't nearly as powerful as OCaml's,
> which allows it to create syntax that doesn't need to go anywhere but
> at the toplevel.
>
> We need this functionality in OCaml, but the closest thing is to say
> 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
> = A.t end'

This can be written more succinctly:

   let foo, bar, baz = A.(foo, bar, baz)
   type t = A.t

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 18:09             ` Jeremy Yallop
@ 2016-07-15 18:26               ` Hendrik Boom
  2016-07-15 18:58               ` Yotam Barnoy
  1 sibling, 0 replies; 23+ messages in thread
From: Hendrik Boom @ 2016-07-15 18:26 UTC (permalink / raw)
  To: Ocaml Mailing List

On Fri, Jul 15, 2016 at 07:09:22PM +0100, Jeremy Yallop wrote:
> On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> > In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
> > exactly what I want to import. This is because haskell has a
> > half-baked module system that isn't nearly as powerful as OCaml's,
> > which allows it to create syntax that doesn't need to go anywhere but
> > at the toplevel.
> >
> > We need this functionality in OCaml, but the closest thing is to say
> > 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
> > = A.t end'
> 
> This can be written more succinctly:
> 
>    let foo, bar, baz = A.(foo, bar, baz)
>    type t = A.t

And that even allows renaming in case several modules try to define the 
same name!

-- hendrik

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 16:57           ` Yotam Barnoy
  2016-07-15 18:09             ` Jeremy Yallop
@ 2016-07-15 18:50             ` Alain Frisch
  2016-07-15 19:44               ` Hendrik Boom
  1 sibling, 1 reply; 23+ messages in thread
From: Alain Frisch @ 2016-07-15 18:50 UTC (permalink / raw)
  To: Yotam Barnoy, Hendrik Boom; +Cc: Ocaml Mailing List

On 15/07/2016 18:57, Yotam Barnoy wrote:
> The problem seems to stem from the fact that the same open statements
> which we use to import code (and which are available in every
> language) are also used as part of OCaml's super-flexible module
> system. This makes it hard to come up with easy, simple shortcuts for
> functionality available in other languages, because it needs to fit in
> the far more complex general module language.

There would really be no difficulty to allow specifying which components 
to bring in scope in an "open" statement.  One just need to decide if it 
is a good idea from a language design point of view, and then agree on / 
fight over a syntax.  (One needs to distinguish of course between 
various kinds of components.)


Alain

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 18:09             ` Jeremy Yallop
  2016-07-15 18:26               ` Hendrik Boom
@ 2016-07-15 18:58               ` Yotam Barnoy
  2016-07-15 19:26                 ` Hezekiah M. Carty
  1 sibling, 1 reply; 23+ messages in thread
From: Yotam Barnoy @ 2016-07-15 18:58 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: Hendrik Boom, Ocaml Mailing List

Ok I have to admit that's pretty convenient.

> On Jul 15, 2016, at 2:09 PM, Jeremy Yallop <yallop@gmail.com> wrote:
>
>> On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
>> In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
>> exactly what I want to import. This is because haskell has a
>> half-baked module system that isn't nearly as powerful as OCaml's,
>> which allows it to create syntax that doesn't need to go anywhere but
>> at the toplevel.
>>
>> We need this functionality in OCaml, but the closest thing is to say
>> 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
>> = A.t end'
>
> This can be written more succinctly:
>
>   let foo, bar, baz = A.(foo, bar, baz)
>   type t = A.t

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 18:58               ` Yotam Barnoy
@ 2016-07-15 19:26                 ` Hezekiah M. Carty
  2016-07-15 19:42                   ` Yotam Barnoy
  0 siblings, 1 reply; 23+ messages in thread
From: Hezekiah M. Carty @ 2016-07-15 19:26 UTC (permalink / raw)
  To: Yotam Barnoy, Jeremy Yallop; +Cc: Hendrik Boom, Ocaml Mailing List

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

type t = M.t does not bring M.t's constructors into scope.  ppx_import (
https://github.com/whitequark/ppx_import) can help with this if you don't
mind preprocessing.

Hez

On Fri, Jul 15, 2016 at 2:58 PM Yotam Barnoy <yotambarnoy@gmail.com> wrote:

> Ok I have to admit that's pretty convenient.
>
> > On Jul 15, 2016, at 2:09 PM, Jeremy Yallop <yallop@gmail.com> wrote:
> >
> >> On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> >> In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
> >> exactly what I want to import. This is because haskell has a
> >> half-baked module system that isn't nearly as powerful as OCaml's,
> >> which allows it to create syntax that doesn't need to go anywhere but
> >> at the toplevel.
> >>
> >> We need this functionality in OCaml, but the closest thing is to say
> >> 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
> >> = A.t end'
> >
> > This can be written more succinctly:
> >
> >   let foo, bar, baz = A.(foo, bar, baz)
> >   type t = A.t
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> 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: 2293 bytes --]

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 19:26                 ` Hezekiah M. Carty
@ 2016-07-15 19:42                   ` Yotam Barnoy
  2016-07-15 19:52                     ` Jeremy Yallop
  0 siblings, 1 reply; 23+ messages in thread
From: Yotam Barnoy @ 2016-07-15 19:42 UTC (permalink / raw)
  To: Hezekiah M. Carty; +Cc: Jeremy Yallop, Hendrik Boom, Ocaml Mailing List

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

That's a great point. Without that last bit of functionality, this isn't
really a solution to the problem.

On Jul 15, 2016, at 3:26 PM, Hezekiah M. Carty <hez@0ok.org> wrote:

type t = M.t does not bring M.t's constructors into scope.  ppx_import (
https://github.com/whitequark/ppx_import) can help with this if you don't
mind preprocessing.

Hez

On Fri, Jul 15, 2016 at 2:58 PM Yotam Barnoy <yotambarnoy@gmail.com> wrote:

> Ok I have to admit that's pretty convenient.
>
> > On Jul 15, 2016, at 2:09 PM, Jeremy Yallop <yallop@gmail.com> wrote:
> >
> >> On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> >> In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
> >> exactly what I want to import. This is because haskell has a
> >> half-baked module system that isn't nearly as powerful as OCaml's,
> >> which allows it to create syntax that doesn't need to go anywhere but
> >> at the toplevel.
> >>
> >> We need this functionality in OCaml, but the closest thing is to say
> >> 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
> >> = A.t end'
> >
> > This can be written more succinctly:
> >
> >   let foo, bar, baz = A.(foo, bar, baz)
> >   type t = A.t
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> 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: 2725 bytes --]

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 18:50             ` Alain Frisch
@ 2016-07-15 19:44               ` Hendrik Boom
  0 siblings, 0 replies; 23+ messages in thread
From: Hendrik Boom @ 2016-07-15 19:44 UTC (permalink / raw)
  To: Ocaml Mailing List

On Fri, Jul 15, 2016 at 08:50:25PM +0200, Alain Frisch wrote:
> On 15/07/2016 18:57, Yotam Barnoy wrote:
> >The problem seems to stem from the fact that the same open statements
> >which we use to import code (and which are available in every
> >language) are also used as part of OCaml's super-flexible module
> >system. This makes it hard to come up with easy, simple shortcuts for
> >functionality available in other languages, because it needs to fit in
> >the far more complex general module language.
> 
> There would really be no difficulty to allow specifying which components to
> bring in scope in an "open" statement.  One just need to decide if it is a
> good idea from a language design point of view, and then agree on / fight
> over a syntax.  (One needs to distinguish of course between various kinds of
> components.)

Modula 3 does it this way, and allows you to rename on import.
It also allows you to just import an emtire module, but then you have 
to mention the name of the module every time you use the something it 
provides.

It has no promiscuous 'give me whatever'.

It works.  And it's usually easy to find where something is defined.

Except for methids of object types.  Identifying the particular 
function being called then depends on run-time information.  That's 
inherent to inheritance and overriding.

-- hendrik


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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 19:42                   ` Yotam Barnoy
@ 2016-07-15 19:52                     ` Jeremy Yallop
  2016-07-15 20:25                       ` Yotam Barnoy
  0 siblings, 1 reply; 23+ messages in thread
From: Jeremy Yallop @ 2016-07-15 19:52 UTC (permalink / raw)
  To: Yotam Barnoy; +Cc: Hezekiah M. Carty, Hendrik Boom, Ocaml Mailing List

On 15/07/2016, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> On Jul 15, 2016, at 3:26 PM, Hezekiah M. Carty <hez@0ok.org> wrote:
> > On Fri, Jul 15, 2016 at 2:58 PM Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> > > > On Jul 15, 2016, at 2:09 PM, Jeremy Yallop <yallop@gmail.com> wrote:
> > > > > On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
> > > > > In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
> > > > > exactly what I want to import. This is because haskell has a
> > > > > half-baked module system that isn't nearly as powerful as OCaml's,
> > > > > which allows it to create syntax that doesn't need to go anywhere but
> > > > > at the toplevel.
> > > > >
> > > > > We need this functionality in OCaml, but the closest thing is to say
> > > > > 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
> > > > > = A.t end'
> > > >
> > > > This can be written more succinctly:
> > > >
> > > >   let foo, bar, baz = A.(foo, bar, baz)
> > > >   type t = A.t
> > >
> > > Ok I have to admit that's pretty convenient.
> > >
> > type t = M.t does not bring M.t's constructors into scope.  ppx_import (
> > https://github.com/whitequark/ppx_import) can help with this if you don't
> > mind preprocessing.
>
> That's a great point. Without that last bit of functionality, this isn't
> really a solution to the problem.

The Haskell example you gave:

   import A(T)

doesn't bring T's constructors into scope, either; it needs to be
written like this:

   import A(T(..))

In OCaml you can bring A.t's constructors into scope by repeating the
definition:

   type t = A.t = T of int

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 19:52                     ` Jeremy Yallop
@ 2016-07-15 20:25                       ` Yotam Barnoy
  0 siblings, 0 replies; 23+ messages in thread
From: Yotam Barnoy @ 2016-07-15 20:25 UTC (permalink / raw)
  To: Jeremy Yallop; +Cc: Hezekiah M. Carty, Hendrik Boom, Ocaml Mailing List

That's right -- I haven't touched our Haskell code in a while and
forgot about this detail.

It's nice to know that this is possible in ocaml, but it's clearly
inadequate for manually importing constructors. Perhaps this aspect
(importing constructors) should be improved, since the others can be
emulated. Or maybe open should be enhanced.

While thinking about open, it would also be nice to think of similarly
adequate solutions for modules that aren't opened but are still
limited to a specific interface (qualified importing in Haskell).

 A solution that covers both cases with minimal changes would
obviously be ideal.

> On Jul 15, 2016, at 3:52 PM, Jeremy Yallop <yallop@gmail.com> wrote:
>
>> On 15/07/2016, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
>>> On Jul 15, 2016, at 3:26 PM, Hezekiah M. Carty <hez@0ok.org> wrote:
>>> On Fri, Jul 15, 2016 at 2:58 PM Yotam Barnoy <yotambarnoy@gmail.com> wrote:
>>>>>> On Jul 15, 2016, at 2:09 PM, Jeremy Yallop <yallop@gmail.com> wrote:
>>>>>> On 15 July 2016 at 17:57, Yotam Barnoy <yotambarnoy@gmail.com> wrote:
>>>>>> In haskell, I can just say 'import A (foo, bar, baz, t)' to limit
>>>>>> exactly what I want to import. This is because haskell has a
>>>>>> half-baked module system that isn't nearly as powerful as OCaml's,
>>>>>> which allows it to create syntax that doesn't need to go anywhere but
>>>>>> at the toplevel.
>>>>>>
>>>>>> We need this functionality in OCaml, but the closest thing is to say
>>>>>> 'include struct let foo = A.foo let bar = A.bar let baz = A.baz type t
>>>>>> = A.t end'
>>>>>
>>>>> This can be written more succinctly:
>>>>>
>>>>>  let foo, bar, baz = A.(foo, bar, baz)
>>>>>  type t = A.t
>>>>
>>>> Ok I have to admit that's pretty convenient.
>>> type t = M.t does not bring M.t's constructors into scope.  ppx_import (
>>> https://github.com/whitequark/ppx_import) can help with this if you don't
>>> mind preprocessing.
>>
>> That's a great point. Without that last bit of functionality, this isn't
>> really a solution to the problem.
>
> The Haskell example you gave:
>
>   import A(T)
>
> doesn't bring T's constructors into scope, either; it needs to be
> written like this:
>
>   import A(T(..))
>
> In OCaml you can bring A.t's constructors into scope by repeating the
> definition:
>
>   type t = A.t = T of int

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 16:13         ` Hendrik Boom
  2016-07-15 16:57           ` Yotam Barnoy
  2016-07-15 17:04           ` Gerd Stolpmann
@ 2016-07-16  7:40           ` Petter A. Urkedal
  2016-07-16  9:58             ` vrotaru.md
  2 siblings, 1 reply; 23+ messages in thread
From: Petter A. Urkedal @ 2016-07-16  7:40 UTC (permalink / raw)
  To: Hendrik Boom; +Cc: caml users

On 15 July 2016 at 18:13, Hendrik Boom <hendrik@topoi.pooq.com> wrote:
> And that's a real problem -- that fact that openning a module can fill
> the namespace with lots of stray identifiers, which the user does not
> control.

Apart from the selective opens discussed, it would be good to tell
apart which modules are meant to be open and which are intrusive
without looking through them.  Most importantly the writer of the
library should be clear about it from the start when designing a
module, then the names will be consistent with the choice, and users
should be able to decide without evaluating the whole interface.

A warning when opening an invasive module in a global scope could
help, as well.  One could maybe decide a module to be invasive from a
few heuristics with fall-back to a declaration:

- A module interface defining a single-letter identifier, most
importantly a type "t" or a signature "S", is invasive.
- A module interface overriding any operator (or identifier?) defined
in Pervasives is invasive.
- A module interface declaring itself `[@@@ocaml.invasive]` is invasive.

Conversely the user may silence the warning with `open M [@@ocaml.invasive]`.

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-16  7:40           ` Petter A. Urkedal
@ 2016-07-16  9:58             ` vrotaru.md
  2016-07-19 16:37               ` Yotam Barnoy
  0 siblings, 1 reply; 23+ messages in thread
From: vrotaru.md @ 2016-07-16  9:58 UTC (permalink / raw)
  To: Petter A. Urkedal, Hendrik Boom; +Cc: caml users

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

About that missing type constructors problem. Seems doable:

module A = struct
  module T = struct
    type t1 = ...
    type t2 = ...
  end
  include T

  let foo _ = ...
  let bar : t2 -> t1  = ...
end

module B = struct

  include A.T
  let foo, bar = A.( foo, bar )

end

Obviously, not for already existing code.

În sâm., 16 iul. 2016 la 10:41, Petter A. Urkedal <paurkedal@gmail.com> a
scris:

> On 15 July 2016 at 18:13, Hendrik Boom <hendrik@topoi.pooq.com> wrote:
> > And that's a real problem -- that fact that openning a module can fill
> > the namespace with lots of stray identifiers, which the user does not
> > control.
>
> Apart from the selective opens discussed, it would be good to tell
> apart which modules are meant to be open and which are intrusive
> without looking through them.  Most importantly the writer of the
> library should be clear about it from the start when designing a
> module, then the names will be consistent with the choice, and users
> should be able to decide without evaluating the whole interface.
>
> A warning when opening an invasive module in a global scope could
> help, as well.  One could maybe decide a module to be invasive from a
> few heuristics with fall-back to a declaration:
>
> - A module interface defining a single-letter identifier, most
> importantly a type "t" or a signature "S", is invasive.
> - A module interface overriding any operator (or identifier?) defined
> in Pervasives is invasive.
> - A module interface declaring itself `[@@@ocaml.invasive]` is invasive.
>
> Conversely the user may silence the warning with `open M
> [@@ocaml.invasive]`.
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> 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: 2827 bytes --]

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-16  9:58             ` vrotaru.md
@ 2016-07-19 16:37               ` Yotam Barnoy
  0 siblings, 0 replies; 23+ messages in thread
From: Yotam Barnoy @ 2016-07-19 16:37 UTC (permalink / raw)
  Cc: caml users, Jeremy Yallop

Jeremy, how about taking a page from haskell, and having

type t = A.t(..)

This would import the same constructors locally. It also means we have
the full functionality covered, in terms of both opens and creating
limited local modules:

haskell:
import A(foo, bar, T(..))

ocaml:
let foo, bar = A.(foo, bar)
type t = A.t(..)

haskell:
import qualified LongA(foo, bar, T(..)) as A

ocaml:
module A = struct LongA.(let foo, bar = foo, bar type nonrec t = t(..)) end

It's still more verbose (especially the limited-qualified module) but
at least it's decent.



On Sat, Jul 16, 2016 at 5:58 AM, vrotaru.md@gmail.com
<vrotaru.md@gmail.com> wrote:
>
> About that missing type constructors problem. Seems doable:
>
> module A = struct
>   module T = struct
>     type t1 = ...
>     type t2 = ...
>   end
>   include T
>
>   let foo _ = ...
>   let bar : t2 -> t1  = ...
> end
>
> module B = struct
>
>   include A.T
>   let foo, bar = A.( foo, bar )
>
> end
>
> Obviously, not for already existing code.
>
> În sâm., 16 iul. 2016 la 10:41, Petter A. Urkedal <paurkedal@gmail.com> a
> scris:
>>
>> On 15 July 2016 at 18:13, Hendrik Boom <hendrik@topoi.pooq.com> wrote:
>> > And that's a real problem -- that fact that openning a module can fill
>> > the namespace with lots of stray identifiers, which the user does not
>> > control.
>>
>> Apart from the selective opens discussed, it would be good to tell
>> apart which modules are meant to be open and which are intrusive
>> without looking through them.  Most importantly the writer of the
>> library should be clear about it from the start when designing a
>> module, then the names will be consistent with the choice, and users
>> should be able to decide without evaluating the whole interface.
>>
>> A warning when opening an invasive module in a global scope could
>> help, as well.  One could maybe decide a module to be invasive from a
>> few heuristics with fall-back to a declaration:
>>
>> - A module interface defining a single-letter identifier, most
>> importantly a type "t" or a signature "S", is invasive.
>> - A module interface overriding any operator (or identifier?) defined
>> in Pervasives is invasive.
>> - A module interface declaring itself `[@@@ocaml.invasive]` is invasive.
>>
>> Conversely the user may silence the warning with `open M
>> [@@ocaml.invasive]`.
>>
>> --
>> Caml-list mailing list.  Subscription management and archives:
>> https://sympa.inria.fr/sympa/arc/caml-list
>> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
>> Bug reports: http://caml.inria.fr/bin/caml-bugs

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

* Re: [Caml-list] Warnings opening modules (was: why is building ocaml hard?)
  2016-07-15 17:04           ` Gerd Stolpmann
@ 2016-07-20  7:49             ` Louis Gesbert
  0 siblings, 0 replies; 23+ messages in thread
From: Louis Gesbert @ 2016-07-20  7:49 UTC (permalink / raw)
  To: Gerd Stolpmann, caml-list

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

ocp-index does that, in the most simple way possible: the file is parsed to find any scope-changing constructs (open, include, functor parameters...), then it tries to resolve the identifier, reading any .cmi file corresponding to an open module it can find to check for a match.

It's not 100% perfect (e.g. in its current version, it won't distinguish identifiers corresponding to values, field names, or types), but it works extremely well in practice and, using it, pulling hair because I have to lose time looking up an identifier in the presence of 'open' statements is a thing of the past. Just run '(ocp-index-print-info-at-point)' in emacs (and from the shell, it's 'ocp-index print IDENT --context FILE:LINE:COL "%p"')

Of course, it's not as light-weight, but if you have Merlin configured on your project and working, that's even better: in either case you get jump-to-source which also gives that information, and Merlin is more accurate.



> - Gerd Stolpmann, 15/07/2016 19:04 -
> Am Freitag, den 15.07.2016, 12:13 -0400 schrieb Hendrik Boom:
> > Or is there some kind of code browsing tool that explicates all this?
> 
> I don't know any tool that just shows the full path of identifiers.
> Merlin could do it (has all infos) but it doesn't so far. It "only"
> shows the type (also useful, but in a different way).
> 
> Gerd
> 

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 473 bytes --]

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

end of thread, other threads:[~2016-07-20  7:49 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-10 11:57 [Caml-list] Warnings opening modules (was: why is building ocaml hard?) David Allsopp
2016-07-10 19:45 ` Gerd Stolpmann
2016-07-13 12:08   ` David Allsopp
2016-07-13 12:20     ` Gerd Stolpmann
2016-07-13 12:30       ` David Allsopp
2016-07-14  9:03     ` Goswin von Brederlow
2016-07-15  9:52       ` David Allsopp
2016-07-15 16:13         ` Hendrik Boom
2016-07-15 16:57           ` Yotam Barnoy
2016-07-15 18:09             ` Jeremy Yallop
2016-07-15 18:26               ` Hendrik Boom
2016-07-15 18:58               ` Yotam Barnoy
2016-07-15 19:26                 ` Hezekiah M. Carty
2016-07-15 19:42                   ` Yotam Barnoy
2016-07-15 19:52                     ` Jeremy Yallop
2016-07-15 20:25                       ` Yotam Barnoy
2016-07-15 18:50             ` Alain Frisch
2016-07-15 19:44               ` Hendrik Boom
2016-07-15 17:04           ` Gerd Stolpmann
2016-07-20  7:49             ` Louis Gesbert
2016-07-16  7:40           ` Petter A. Urkedal
2016-07-16  9:58             ` vrotaru.md
2016-07-19 16:37               ` Yotam Barnoy

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