www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Module Clarification

reply Jonathan Marler <johnnymarler gmail.com> writes:
I'm working on a code generation tool and wanted to make sure my 
module approach was correct.  The generated code has a module 
hierarchy, where modules can appear at any level of the hierarchy.

module foo;
module foo.bar;

In this case, module foo and foo.bar are independent modules.  
The foo module does not publicly import foo.bar, like a typical 
package.d module would do. At first I organized the modules like 
this:

foo.d     (module foo)
foo/bar.d (module foo.bar)

But this doesn't work because the module file foo.d, cannot have 
the same name as a the directory foo.  So now I organize it like 
this:

foo/package.d (module foo)
foo/bar.d     (module foo.bar)

This is not the typical usage for the "package.d" file.  
Normally, package.d would publicly import other modules, however, 
in this case, package.d is an independent module.  This also 
means that if another module was added, say foo.bar.baz, the new 
file system would have to look like this:

foo/package.d     (module foo)
foo/bar/package.d (module foo.bar)
foo/bar/baz.d     (module foo.bar.baz)

This technique seems a bit odd, but it works.  I'm just wondering 
if there's a better way to achieve these semantics, or if this is 
the appropriate solution?
Sep 21 2016
next sibling parent tcak <1ltkrs+3wyh1ow7kzn1k sharklasers.com> writes:
On Wednesday, 21 September 2016 at 14:17:56 UTC, Jonathan Marler 
wrote:
 I'm working on a code generation tool and wanted to make sure 
 my module approach was correct.  The generated code has a 
 module hierarchy, where modules can appear at any level of the 
 hierarchy.

 module foo;
 module foo.bar;

 In this case, module foo and foo.bar are independent modules.  
 The foo module does not publicly import foo.bar, like a typical 
 package.d module would do. At first I organized the modules 
 like this:

 foo.d     (module foo)
 foo/bar.d (module foo.bar)

 But this doesn't work because the module file foo.d, cannot 
 have the same name as a the directory foo.  So now I organize 
 it like this:

 foo/package.d (module foo)
 foo/bar.d     (module foo.bar)

 This is not the typical usage for the "package.d" file.  
 Normally, package.d would publicly import other modules, 
 however, in this case, package.d is an independent module.  
 This also means that if another module was added, say 
 foo.bar.baz, the new file system would have to look like this:

 foo/package.d     (module foo)
 foo/bar/package.d (module foo.bar)
 foo/bar/baz.d     (module foo.bar.baz)

 This technique seems a bit odd, but it works.  I'm just 
 wondering if there's a better way to achieve these semantics, 
 or if this is the appropriate solution?
I can be wrong, but if I remember correctly, when I used package.d as you do a while ago (~1.5 years ago), it was acting a little different compared to a normal module file. Some declarations were not working as in a normal module. It could be my bad observation as well. I hope it works for you, but your design might break at some point.
Sep 21 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/21/16 10:17 AM, Jonathan Marler wrote:
 I'm working on a code generation tool and wanted to make sure my module
 approach was correct.  The generated code has a module hierarchy, where
 modules can appear at any level of the hierarchy.

 module foo;
 module foo.bar;

 In this case, module foo and foo.bar are independent modules.  The foo
 module does not publicly import foo.bar, like a typical package.d module
 would do. At first I organized the modules like this:

 foo.d     (module foo)
 foo/bar.d (module foo.bar)

 But this doesn't work because the module file foo.d, cannot have the
 same name as a the directory foo.  So now I organize it like this:

 foo/package.d (module foo)
 foo/bar.d     (module foo.bar)

 This is not the typical usage for the "package.d" file.  Normally,
 package.d would publicly import other modules, however, in this case,
 package.d is an independent module.
This is not a requirement for the package.d usage. You can do anything you want in package.d For example, in std/experimental/allocator/package.d, sub modules are not imported unless you do it yourself.
  This also means that if another
 module was added, say foo.bar.baz, the new file system would have to
 look like this:

 foo/package.d     (module foo)
 foo/bar/package.d (module foo.bar)
 foo/bar/baz.d     (module foo.bar.baz)

 This technique seems a bit odd, but it works.  I'm just wondering if
 there's a better way to achieve these semantics, or if this is the
 appropriate solution?
This should be fine. x/package.d is equivalent to module x. -Steve
Sep 22 2016
parent reply Jonathan Marler <johnnymarler gmail.com> writes:
On Thursday, 22 September 2016 at 11:40:17 UTC, Steven 
Schveighoffer wrote:
 This should be fine. x/package.d is equivalent to module x.
Ok, it looks like no-one thought what I was doing was off-base. I guess this brings up another question. Why doesn't the compiler support modules in a hierarchy? foo.d foo/bar.d The only reason I can see is that you would have to setup some rules on how to handle it when you have both a module file, and a package.d file in a directory with the same name: foo.d foo/package.d // huh? error? Actually, the more I think about it, I'm not sure there's a good reason for the "package.d" semantics to exist. I guess it establishes a pattern when people would like to combine smaller modules into one public module, but it doesn't have to be used that way. The opposite is true that you could use a normal module (not a package.d module) to publicly import smaller modules: Instead of: foo/package.d // publically imports fooPart1 and fooPart2 foo/fooPart1.d foo/fooPart2.d What was wrong with: foo.d // still publically imports fooPart1 and fooPart2 foo/fooPart1.d foo/fooPart2.d If the package.d file didn't exist, then I don't think there would be any problem with hierarchical modules. Is this the right conclusion? Was package.d a mistake? Maybe the reasoning is that D doesn't really like hierarchical modules, so creating them should look a bit odd? foo/package.d foo/bar/package.d foo/bar/baz/package.d
Sep 22 2016
next sibling parent reply Lodovico Giaretta <lodovico giaretart.net> writes:
On Thursday, 22 September 2016 at 14:29:20 UTC, Jonathan Marler 
wrote:
 Actually, the more I think about it, I'm not sure there's a 
 good reason for the "package.d" semantics to exist.  I guess it 
 establishes a pattern when people would like to combine smaller 
 modules into one public module, but it doesn't have to be used 
 that way.  The opposite is true that you could use a normal 
 module (not a package.d module) to publicly import smaller 
 modules:

 Instead of:
 foo/package.d // publically imports fooPart1 and fooPart2
 foo/fooPart1.d
 foo/fooPart2.d

 What was wrong with:
 foo.d // still publically imports fooPart1 and fooPart2
 foo/fooPart1.d
 foo/fooPart2.d

 If the package.d file didn't exist, then I don't think there 
 would be any problem with hierarchical modules.  Is this the 
 right conclusion?  Was package.d a mistake?  Maybe the 
 reasoning is that D doesn't really like hierarchical modules, 
 so creating them should look a bit odd?

 foo/package.d
 foo/bar/package.d
 foo/bar/baz/package.d
I think that having package.d provides a better layout. Look at the difference between this:
 ls std/experimental
drw-rw-rw- allocator drw-rw-rw- logger drw-rw-rw- ndslice -rw-rw-rw- typecons.d and this:
 ls std/experimental
drw-rw-rw- allocator -rw-rw-rw- allocator.d drw-rw-rw- logger -rw-rw-rw- logger.d drw-rw-rw- ndslice -rw-rw-rw- ndslice.d -rw-rw-rw- typecons.d Having to put part of a package outside the package folder is ugly to see and a bit more difficult to manage.
Sep 22 2016
parent Jonathan Marler <johnnymarler gmail.com> writes:
On Thursday, 22 September 2016 at 15:02:01 UTC, Lodovico Giaretta 
wrote:
 I think that having package.d provides a better layout. Look at 
 the difference between this:

 ls std/experimental
drw-rw-rw- allocator drw-rw-rw- logger drw-rw-rw- ndslice -rw-rw-rw- typecons.d and this:
 ls std/experimental
drw-rw-rw- allocator -rw-rw-rw- allocator.d drw-rw-rw- logger -rw-rw-rw- logger.d drw-rw-rw- ndslice -rw-rw-rw- ndslice.d -rw-rw-rw- typecons.d Having to put part of a package outside the package folder is ugly to see and a bit more difficult to manage.
Yes that does seem like a nice benefit. What do you think about hierarchical modules? Do you think we should have supported modules that also have modules underneath them? i.e. foo.d foo/bar.d foo/bar/baz.d Or do you think it's fine to require the higher level modules to exist in package.d files? foo/package.d foo/bar/package.d foo/bar/baz.d It just seems odd because the modules aren't packages. I suppose I would understand if hierarchical modules are discouraged, is that the case? I ran into this problem because I'm working on a .NET to D transpiler, and put all the symbols in a .NET namespace into the same D module. So currently I have to do this: System/package.d System/Net/package.d System/Net/Sockets.d but I think it would make more sense to have this: System.d System/Net.d System/Net/Sockets.d
Sep 22 2016
prev sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/22/16 10:29 AM, Jonathan Marler wrote:

 If the package.d file didn't exist, then I don't think there would be
 any problem with hierarchical modules.  Is this the right conclusion?
 Was package.d a mistake?  Maybe the reasoning is that D doesn't really
 like hierarchical modules, so creating them should look a bit odd?
Before package.d support, you could not do any importing of packages. You could only import modules. package.d was how the compiler allowed importing packages. I don't know that there is a fundamental difference between foo/package.d and foo.d, but this is just the solution that was chosen. Is it a mistake? I don't think so, it's just a preference. Prior to this, it was common to put "package" imports into an "all.d" file: foo/all.d // import fooPart1.d fooPart2.d foo/fooPart1.d -Steve
Sep 22 2016
parent reply Jonathan Marler <johnnymarler gmail.com> writes:
On Thursday, 22 September 2016 at 20:09:41 UTC, Steven 
Schveighoffer wrote:
 Before package.d support, you could not do any importing of 
 packages. You could only import modules. package.d was how the 
 compiler allowed importing packages.

 I don't know that there is a fundamental difference between 
 foo/package.d and foo.d, but this is just the solution that was 
 chosen. Is it a mistake? I don't think so, it's just a 
 preference.

 Prior to this, it was common to put "package" imports into an 
 "all.d" file:

 foo/all.d // import fooPart1.d fooPart2.d
 foo/fooPart1.d

 -Steve
Ok, do you know why is this not allowed? foo.d foo/bar.d
Sep 22 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 9/22/16 4:16 PM, Jonathan Marler wrote:
 On Thursday, 22 September 2016 at 20:09:41 UTC, Steven Schveighoffer wrote:
 Before package.d support, you could not do any importing of packages.
 You could only import modules. package.d was how the compiler allowed
 importing packages.

 I don't know that there is a fundamental difference between
 foo/package.d and foo.d, but this is just the solution that was
 chosen. Is it a mistake? I don't think so, it's just a preference.

 Prior to this, it was common to put "package" imports into an "all.d"
 file:

 foo/all.d // import fooPart1.d fooPart2.d
 foo/fooPart1.d
Ok, do you know why is this not allowed?
I'm sure if you search the forums, you can find discussions of this. Walter probably had a reason. I'm not sure if the reason is valid anymore now that package.d is supported. -Steve
Sep 27 2016
parent Jonathan Marler <johnnymarler gmail.com> writes:
On Tuesday, 27 September 2016 at 13:48:39 UTC, Steven 
Schveighoffer wrote:
 On 9/22/16 4:16 PM, Jonathan Marler wrote:
 On Thursday, 22 September 2016 at 20:09:41 UTC, Steven 
 Schveighoffer wrote:
 Before package.d support, you could not do any importing of 
 packages.
 You could only import modules. package.d was how the compiler 
 allowed
 importing packages.

 I don't know that there is a fundamental difference between
 foo/package.d and foo.d, but this is just the solution that 
 was
 chosen. Is it a mistake? I don't think so, it's just a 
 preference.

 Prior to this, it was common to put "package" imports into an 
 "all.d"
 file:

 foo/all.d // import fooPart1.d fooPart2.d
 foo/fooPart1.d
Ok, do you know why is this not allowed?
I'm sure if you search the forums, you can find discussions of this. Walter probably had a reason. I'm not sure if the reason is valid anymore now that package.d is supported. -Steve
foo.d foo/bar.d I would think the reason for not supporting this is you wouldn't want something to be a "module" and a "package" at the same time, but introduction of the "package.d" semantics has broken that rule. From what I can see, it seems like the concept of "packages" doesn't have any useful meaning anymore. Before adding "package.d" support, a "package" was a directory/node you could find modules underneath, but now that it can also be a module itself, saying something is a "package" doesn't really have any meaning. Take the following 2 cases: Case 1: foo.d Case 2: foo/package.d In case 1, foo is a "module", and in case 2, foo is a "package". The problem is that foo can behave EXACTLY THE SAME in both cases. foo could contain typical module code, or publicly import other modules like a typical "package.d" file, in both cases. Saying that foo is a "package" doesn't tell you anything about how "foo" behaves. The "package" concept seems pretty meaningless now.
Sep 27 2016