www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Multiple modules per file

reply Dennis <dkorpel gmail.com> writes:
What if you could just concatenate .d files?

You could write a file `pkg.d` that looks like this:
```D
/// Helper module
module pkg.sub;

string name;

/// Main application module
module pkg.app;

import pkg.sub;
void main()
{
     writeln("hello ", name);
}

/// My package
module pkg;

public import pkg.app;
public import pkg.sub;
```

And then this works:
```
dmd pkg.g
```

No new syntax like `module {}` or fancy tricks like 
`mixin("module x;")`, it would be as if the compiler splits up 
the file into multiple files as a preprocessing step.

Other files can only `import pkg`, since the compiler can't find 
e.g. `pkg/sub.d`.



It's best practice to keep modules small, but it's not always fun 
to deal with many small files.

In many text editors/IDEs it's easier to scan through a file than 
a file tree.

It's also easier to distribute. Notice how some libraries use 
stand alone files for convenience: 
[arsd](https://github.com/adamdruppe/arsd), 
[stb](https://github.com/nothings/stb), [the SQLite 
Amalgamation](https://www.sqlite.org/amalgamation.html). 
Sometimes, your code *has* to be condensed to one string of text 
for a web IDE, like [codingame](codingame.com/), 
[godbolt](https://d.godbolt.org/), 
[run.dlang.io](https://run.dlang.io/), or when just posting in 
the forums / bugzilla.

And, of course, the recent discussion about `private` to the 
`class`, where putting a `class` in its own file is rejected as a 
solution.

Thoughts?
Jun 20 2022
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 20 June 2022 at 15:48:08 UTC, Dennis wrote:
 What if you could just concatenate .d files?
[...]
 Other files can only `import pkg`, since the compiler can't 
 find e.g. `pkg/sub.d`.
Well, presumably you could do it if you passed `pkg.d` explicitly on the command line. But it wouldn't work with `dmd -i` (and probably not with dub either). This seems to me like a feature where the number of ways to use it right (e.g., for package-internal modules that aren't intended for outside use) is much smaller than the number of ways you could potentially shoot yourself in the foot with it. If we adopt this feature, I expect we'll end up getting a regular stream of questions in the Learn forum where someone asks "why doesn't my project build?", and the answer is "you need to put your modules in separate files." You could mitigate the issue by requiring that all modules in a file belong to the same package, but then you lose out on some of the desirable godbolt/run.dlang.io use cases, so it's not a clear win.
Jun 20 2022
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/20/22 12:34 PM, Paul Backus wrote:
 On Monday, 20 June 2022 at 15:48:08 UTC, Dennis wrote:
 What if you could just concatenate .d files?
[...]
 Other files can only `import pkg`, since the compiler can't find e.g. 
 `pkg/sub.d`.
Well, presumably you could do it if you passed `pkg.d` explicitly on the command line. But it wouldn't work with `dmd -i` (and probably not with dub either).
Another option is to use a different filename for such "package modules", like `.dp` for "d package"?
 This seems to me like a feature where the number of ways to use it right 
 (e.g., for package-internal modules that aren't intended for outside 
 use) is much smaller than the number of ways you could potentially shoot 
 yourself in the foot with it. If we adopt this feature, I expect we'll 
 end up getting a regular stream of questions in the Learn forum where 
 someone asks "why doesn't my project build?", and the answer is "you 
 need to put your modules in separate files."
Well, we already get messages because of the terrible error message you get when it can't find your module file (`module object is in object.d which cannot be read`). In this case, it might be even worse, suggesting that it can't read your module, when it's obviously in the right place. In any case, I think the idea is worth exploring, but I don't know that it's a necessary addition. -Steve
Jun 20 2022
parent Paul Backus <snarwin gmail.com> writes:
On Monday, 20 June 2022 at 17:15:07 UTC, Steven Schveighoffer 
wrote:
 Another option is to use a different filename for such "package 
 modules", like `.dp` for "d package"?
Yeah, this could work if you restrict it to one package per file.
 Well, we already get messages because of the terrible error 
 message you get when it can't find your module file (`module 
 object is in object.d which cannot be read`). In this case, it 
 might be even worse, suggesting that it can't read your module, 
 when it's obviously in the right place.
That message has actually been improved in DMD 2.100: ``` $ cat test.d import no_such_module; $ dmd -c test.d test.d(1): Error: unable to read module `no_such_module` test.d(1): Expected 'no_such_module.d' or 'no_such_module/package.d' in one of the following import paths: import path[0] = /usr/include/dmd/phobos import path[1] = /usr/include/dmd/druntime/import ```
Jun 20 2022
prev sibling next sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 6/20/22 11:48 AM, Dennis wrote:
 Other files can only `import pkg`, since the compiler can't find e.g. 
 `pkg/sub.d`.
This one thing might make it unsavory. But I still like it as a starting point. -Steve
Jun 20 2022
prev sibling next sibling parent kinke <noone nowhere.com> writes:
On Monday, 20 June 2022 at 15:48:08 UTC, Dennis wrote:
 Thoughts?
Terrible. ;) - run.dlang.io supports something called HAR: ``` --- foo.d void bla() {} --- bar.d import foo; void main() { bla(); } ```
Jun 20 2022
prev sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
For reference:

ML modules which I think are closer to the origin of the feature, did 
support multiple to a file. They were a little bit like a struct.

Of course they were paired with signatures, which as we all know are now 
in deep demand for a large range of reasons ;)
Jun 20 2022