dune icon indicating copy to clipboard operation
dune copied to clipboard

Feature request: good interactions of `(include_subdirs qualified)` and `unqualified`

Open Niols opened this issue 2 years ago • 3 comments

Desired Behavior

I would want (include_subdirs qualified) and unqualified to interact nicely, describing only what happens to sub-directories.

Example

Let's say we have a project of this shape:

$ tree
.
├── bar
│   ├── baz
│   │   ├── baaz.ml
│   │   └── baazo.ml
│   ├── bez
│   │   └── beez.ml
│   └── dune
├── dune
├── dune-project
├── foo.ml
└── qux
    └── quux.ml

This project contains two dune files, one at top-level and one in the directory bar. I find more readable to read the names of the OCaml files:

  • bar/baz/baaz.ml
  • bar/baz/baazo.ml
  • bar/bez/beez.ml
  • qux/quux.ml

Now let us consider two different ways in which (include_subdirs qualified) and unqualified can be written in the dune files. These two examples are included in the PR https://github.com/ocaml/dune/pull/7629.

Example 1: (include_subdirs unqualified) under (include_subdirs qualified)

In this example, the top-level dune file contains (include_subdirs qualified) while bar/dune contains (include_subdirs unqualified). The latter means that, within the bar/ directory, everything should be seen as if they were at the same level, so we'd see that sub-directory as if it were:

  • bar/baaz.ml
  • bar/baazo.ml
  • bar/beez.ml

Then, at top-level, things should be built in a qualified way, giving therefore:

  • Bar.Baaz
  • Bar.Baazo
  • Bar.Beez
  • Qux.Quux

Example 2: (include_subdirs qualified) under (include_subdirs unqualified)

This example is the opposite: the top-level dune file contains (include_subdirs unqualified) while bar/dune contains (include_subdirs qualified). The latter means that, within the bar/ directory, things should be see in a qualified way, so we'd see that sub-directory as it is, with modules Baz.Baaz, Baz.Baazo and Bez.Beez. At top-level, things should be built in an unqualified way, giving therefore:

  • Baz.Baaz
  • Baz.Baazo
  • Bez.Beez
  • Quux

Discussions

I think I am basically seeing things as if we were building modules from the leaves of the file tree and deciding as we go up the file tree whether to include the sub-modules in a qualified or unqualified way (or I guess not at all if there is an (include_subdirs no)). I think the semantics of the include_subdirs stanza can be made pretty clear considering that it only applies to how we consider sub-directories. However, it might be a bit of a pain to implement, and I feel implementing the generic way (and the qualified under unqualified in particular) might be tricky.

I suppose it would also make sense to simply reject such a suggestion and to say that there may be only one (include_subdirs) stanza in a part of a file tree. However, the current situation very much allows several such stanzas to inhabit the same file tree, except somehow modules are then not findable. Those situations should probably be rejected with a clean error message instead.

Niols avatar Apr 25 '23 10:04 Niols

The feature request you're proposing is logical, but I'm not sure why you'd like to use (include_subdirs unqualified) at all. To me it sems like (include_subdirs qualified) is basically strictly superior and should always be preferred. Can you give us some concrete use cases where you think the unqualified mode is beneficial?

rgrinberg avatar May 25 '23 14:05 rgrinberg

So personally, now that the qualified mode is here, I am going to put it EVERYWHERE. However, I can imagine that some people might prefer the unqualified one, and you're probably going to keep it for compatibility anyways.

In my specific case, I encountered the issue while migrating a project that had several libraries in a qualified-like folder structure, some of which used the unqualified mode to categorise their many modules. I wanted to migrate piece by piece, replacing one library after the other by a proper qualification in another library. This led to places where I had unqualified bits within a qualified library, and things stopped working.

I think it is extremely reasonable to reject a mix of qualified and unqualified. It probably doesn't make much sense anyway and would lead to confusion in people trying to understand the project. However, as of now, Dune doesn't complain if you do something like that but it also doesn't put the modules in question in a reasonable place (if anywhere at all?) and I think that's wrong.

I guess the feature request could very well become simply: make Dune fail when using a mix of qualified and unqualified modes.

Edit: I can't report on the experience of switching from my project to a fully qualified one because I then hit https://github.com/ocaml/dune/issues/7610 which was really blocking.

Edit2: I'm actually reading again https://github.com/paris-branch/dancelor/issues/97 which says that “https://github.com/ocaml/dune/issues/7630 could be circumvented with some work, which might actually lead to a more pleasant organisation of [the project] in the end. However, it would be much easier to just keep [the project] as-is for the transition, and this issue is blocking for that.”

Niols avatar Jun 04 '23 17:06 Niols