How to structure classes as files

Hi Chapel developers.

Lately I have started writing chapel code with classes.
So if I want to group a bunch of related classes together, like I am used to with c++ namespaces, It looks like modules is the right way.

In chapel every file becomes a module.
Quoting the documentation I find on Modules — Chapel Documentation 1.32 it says.

If all the code of a file is not enclosed in an explicit module, defined using the module keyword, then the file itself is treated as a module with the same name as the file (minus the .chpl suffix).

The question the becomes. Can I group classes into as single module without storing them in the same file? I am concerned that one file per module can become unmanageable. The modules I am planning to write are too large to handle as one file.

Hello,

There isn't a way to split a single module across multiple files,
however there are a couple of options that might accomplish what you're
looking for anyways.

First, you can "re-export" a symbol from another module with a public use or public import statement. While it does not yet impact the
module documentation, it will enable you to treat the symbols brought in
as though they were defined in the module with the use or import
statement. Here's some code illustrating that:

module A {
var x: int = 2;
}

module B {
public import A.x; // This re-exports "x" from A

var y: int = 6; // some other code in B
}

module C {
use B;

proc main() {
writeln(B.x); // Even though x is not defined in B itself, you can
still treat it as though it is
writeln(B.y);
}
}

Note that there are some changes coming to public use and public import this release cycle, so it is probably best to work from main to
avoid confusion until 1.27 is released (which should be soon).

Second, there is a prototypical feature for treating a module in another
file as a submodule:
https://chapel-lang.org/docs/latest/technotes/module_include.html

Would one of those options accomplish what you are looking for?

Thanks,
Lydia

Hi lydia

thank you for the quick reply. This is just what I am looking for. I will experiment public use and public import and see if I am able to sort it out.

Hi Andreas —

Note also that the two techniques Lydia mentioned can be used together:

  • the include option can be used to bring distinct files into the current module as submodules
  • a public use or import of those submodules can make them appear as though they were defined within the module itself

There have also been discussions over time about whether or not to extend the include feature to do C/C++-style (or LaTeX-style) "literally insert this file's contents here", which have met with mixed reviews. If you think that would be more attractive for your use cases than the above features, that'd be good to know.

-Brad

so far what you have said is easy to follow. my code compile and exposes the new values that I imported.
My trouble then is to get these constraints to play along with both the chpl compile and chpldoc documentation.

With lydia's example I want to export variable x through module B while at the same time keeping module A hidden. When I do chapldoc A.chpl B.chpl it will produce an index.html where both A and B are exposed.

I have seen you put pragma "no doc" in chapel code. however putting this on the additional module A makes the variable x disappear in the documentation both as module A and through module B.
All the ways i have tried to structure my code I end up documenting all or nothing.

I did not solve my little problem. Instead of trying to tightly control the module content I stopped overthinking it and started embracing sub modules.

I ended up doing this module structure for my project

https://ahysing.github.io/BitArray/modules/src/BitArrays.html

I am happy with this.

Awesome, glad that worked out for you! We definitely intend to improve
the situation around documentation and re-exporting, it just hasn't
bubbled up to the top of our priorities yet.

Thanks,
Lydia

Hi Andreas —

Glad you found an approach that you like well enough.

The fact that chpldoc isn't aware of publicly used/imported modules is a known issue (chpldoc should document transitive (public) uses · Issue #14601 · chapel-lang/chapel · GitHub) and one that probably has a relatively easy fix. We haven't prioritized it because we aren't leaning on these features enough ourselves to be suffering from the lack, but if a user were blocked by it, it would up the priority significantly.

So, if you feel the lack of chpldoc support for the re-exporting case is putting you into a corner you don't like, feel free to say so on that issue and we'll bump it up in priority in response.

-Brad