www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - really why module declarations?

reply XavierAP <n3minis-git yahoo.es> writes:
I've perused both the spec[1] and Andrei's book, and I the idea I 
get is that module declarations are optional, recommended only in 
case of file names not being valid D names. But in the community 
(and Phobos) I see it's strongly recommended and used throughout.

What's the reason? If the declaration overrides the path 
(provided the file is found) rather than enforcing path 
consistency by outputting a compile error, then what's the 
benefit of module declarations, if we have to be disciplined to 
keep it consistent with paths anyway?

I'm busy starting my first big multi file D project, thanks for 
any feedback!


[1] https://dlang.org/spec/module.html#ModuleDeclaration
Mar 26 2017
next sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 26 March 2017 at 20:51:01 UTC, XavierAP wrote:
 I've perused both the spec[1] and Andrei's book, and I the idea 
 I get is that module declarations are optional, recommended 
 only in case of file names not being valid D names.
Module declarations are only optional in the most trivial case that is rarely useful in real world code. I recommend you ALWAYS use them (and always put a ddoc comment on them!), and moreover that you avoid top name modules (use `myproject.modname` instead of `modname`) to avoid conflicts. If you don't, you are depending on implicit magic and just hoping that there's no conflict from third party libraries, and those lead to problems, almost guaranteed before long.
 if we have to be disciplined to keep it consistent with paths 
 anyway?
That's false, the path is irrelevant to the D language, ONLY the module declaration gives the canonical name. The path is just a helper for automatic tools to find the module given an import, but my preference is to ditch those things and actually just list your modules by name anyway. Then everything works reliably and consistently.
Mar 26 2017
parent reply XavierAP <n3minis-git yahoo.es> writes:
On Sunday, 26 March 2017 at 20:58:24 UTC, Adam D. Ruppe wrote:
 Module declarations are only optional in the most trivial case 
 that is rarely useful in real world code. I recommend you 
 ALWAYS use them (and always put a ddoc comment on them!), and 
 moreover that you avoid top name modules (use 
 `myproject.modname` instead of `modname`) to avoid conflicts.
OK I was already doing it all this in the multi-file project. I was curious but I guess it's long to explain the different things that can go wrong if one doesn't declare module names. Followup question: if I am inside module myproj.pack1.mod1 and want to import myproj.pack1.mod2... should I import myproj.pack1.mod2; or import mod2; ?
Mar 26 2017
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 26 March 2017 at 22:10:07 UTC, XavierAP wrote:
 I was curious but I guess it's long to explain the different 
 things that can go wrong if one doesn't declare module names.
You'll just get a name conflict eventually. Either two modules with the same name, or "module `foo` must be imported as `foo.bar`" errors when stuff fails to line up, then you'll need to go in and change all the imports to fix it. Real hassle to do later, real easy to do now.
 Followup question: if I am inside module myproj.pack1.mod1 and 
 want to import myproj.pack1.mod2... should I import 
 myproj.pack1.mod2; or import mod2; ?
Always use the full module name in import. If you want to abbreviate it, do module something = myproj.pack.mod2; then you can refer to it as `something` throughout the usage points in that file.
Mar 26 2017
prev sibling next sibling parent Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 26 March 2017 at 20:51:01 UTC, XavierAP wrote:
 I've perused both the spec[1] and Andrei's book, and I the idea 
 I get is that module declarations are optional, recommended 
 only in case of file names not being valid D names. But in the 
 community (and Phobos) I see it's strongly recommended and used 
 throughout.

 What's the reason? If the declaration overrides the path 
 (provided the file is found) rather than enforcing path 
 consistency by outputting a compile error, then what's the 
 benefit of module declarations, if we have to be disciplined to 
 keep it consistent with paths anyway?

 I'm busy starting my first big multi file D project, thanks for 
 any feedback!


 [1] https://dlang.org/spec/module.html#ModuleDeclaration
In addition to what Adam has said, they allow you to treat the module as a symbol during compilation. You _can_ do that with the implicitly generated one, but you can't do things that requires the declared symbol, e.g. attach UDAs which is how dcompute distinguishes device modules from host modules and possibly reflect of the symbols (although you can use __MODULE__ for that).
Mar 26 2017
prev sibling parent Jonathan M Davis via Digitalmars-d-learn writes:
On Sunday, March 26, 2017 20:51:01 XavierAP via Digitalmars-d-learn wrote:
 I've perused both the spec[1] and Andrei's book, and I the idea I
 get is that module declarations are optional, recommended only in
 case of file names not being valid D names. But in the community
 (and Phobos) I see it's strongly recommended and used throughout.

 What's the reason? If the declaration overrides the path
 (provided the file is found) rather than enforcing path
 consistency by outputting a compile error, then what's the
 benefit of module declarations, if we have to be disciplined to
 keep it consistent with paths anyway?

 I'm busy starting my first big multi file D project, thanks for
 any feedback!


 [1] https://dlang.org/spec/module.html#ModuleDeclaration
What it really comes down to is that if you don't give the module name, the compiler infers it, and it doesn't infer packages. So, if you have foo/bar.d where bar.d's contents are ========================================== void main() { pragma(msg, __MODULE__); } ========================================== and you compile with dmd foo/bar.d, you're going to see bar printed, whereas if you have ========================================== module foo.bar void main() { pragma(msg, __MODULE__); } ========================================== then you'll see foo.bar printed. So, if all you're ever doing is one file programs, then it really doesn't matter, but if you're doing anything with packages, you have to use module declarations. You also have to use them if you want to document a module. As for "overiding" the path... the compiler and other tools use the module path as the path on disk to look for the files - e.g. if you tell the compiler that /usr/local/include/dlang/ is an import directory, it'll start looking for modules in there, and if it's looking for foo.bar, that means that it's looking for /usr/local/include/dlang/foo/bar.d. On some level, it is possible to give a module name or package name that doesn't match the exact file or folder names on disk, but really, that's just asking for trouble. It'll work in some basic cases, but it'll fall flat on its face in real projects. rdmd goes a step further and will compile additional modules based on what's imported (i.e. if a module is imported but wasn't previously compiled, it'll compile it), and when a tool does something like that, it makes it that much worse if your module path isn't equivalent to the path on disk. - Jonathan M Davis
Mar 26 2017