February 29, 2016
On Monday, 29 February 2016 at 19:03:53 UTC, Sebastien Alaiwan wrote:
> What if I change the name of the package? Now I might have to change hundreds of module declarations from "module oldname.algo;" to "module newname.algo;".

That's easy to automate, just run a find/replace across all the files, or if you want to go really fancy, modify hackerpilot's dfix to do it for you.
February 29, 2016
On Monday, 29 February 2016 at 21:33:37 UTC, Adam D. Ruppe wrote:
> On Monday, 29 February 2016 at 21:04:52 UTC, Sebastien Alaiwan wrote:
>> Ok so now let's say I rename the directory "lib" to "foo". If I don't change the "import lib.hello" to "import foo.hello", how is the compiler going to find "hello.d"?
>
> You have to tell the compiler where it is.
Is it only possible with separate compilation?

> Either way, the module name is *not* optional.
>
>> (As a reminder, as I said, I'm using separate compilation)
>
> meh that's part of your problem, why are you doing it that way?
Because it reduces turnaround time (this is something I actually measured on the project I'm currently working on). Having to recompile everything each time I make a modification takes up to 25s on this project. By the way, I'm using gdc. Is it also part of my problem? :-)


February 29, 2016
On Monday, 29 February 2016 at 21:35:48 UTC, Adam D. Ruppe wrote:
> On Monday, 29 February 2016 at 19:03:53 UTC, Sebastien Alaiwan wrote:
>> What if I change the name of the package? Now I might have to change hundreds of module declarations from "module oldname.algo;" to "module newname.algo;".
>
> That's easy to automate, just run a find/replace across all the files, or if you want to go really fancy, modify hackerpilot's dfix to do it for you.

Yes, I know ; but how can you say there's no redundancy when I have to rely on find/replace to keep all these declarations in sync?
March 01, 2016
On Monday, 29 February 2016 at 21:43:31 UTC, Sebastien Alaiwan wrote:

>>> Ok so now let's say I rename the directory "lib" to "foo". If I don't change the "import lib.hello" to "import foo.hello", how is the compiler going to find "hello.d"?
>>
>> You have to tell the compiler where it is.
> Is it only possible with separate compilation?


Given two modules, src/lib/foo.d and and src/main.d, you can pass them both to the command line and not worry about passing -I to the compiler.

dmd src/main.d src/lib/foo.d

In this case, foo.d can have a module statement that gives it any name at all. It does not need to match its directory structure:

module wicked.cool.mod;

This works because you've given the module directly to the compiler and it doesn't need to search for it. If you compile them separately:

dmd -c src/lib/foo.d
dmd src/main.d foo.obj

Now you will see a compiler error. You've given the compiler foo's object file, but it doesn't know where the source file is. When main.d imported wicked.foo.mod, the compiler tried to find wicked/foo/mod.d from its current working directory. No joy. You can test this changing the module declaration in foo.d to lib.foo, then importing lib.foo in main.d. The you can do this:

cd src
dmd -c lib/foo.d
dmd main.d foo.obj

Now when it encounters import lib.foo, it will look for lib/foo.d and find it. Now do this:

cd ..
dmd -c src/lib/foo.d
dmd src/main.d foo.obj

Again, failure, because it's looking for lib/foo.d. So now you have to tell it where to find lib/foo.d:

dmd -Isrc src/main.d foo.obj

Now it will look for src/lib/foo.d and find it.

This is why you shouldn't muck about with package names. If you want to change the name of the src directory, that's fine. You can simply pass -I to the compiler with the correct value. But if you want to change the name of lib, you are now affecting the compiler's ability to find imports. This becomes a problem with separate compilation (as above), which also means it's a problem when using libraries. If you change a package name for something you're distributing as a library, then all the import statements in client code will need to be changed as well.



March 01, 2016
Hi Mike, thanks for taking the time to answer.
If I understand you correctly, you're advising me to keep my file hierarchy mostly in sync with my module hierarchy (except for one potential leading "src/" or "libs/" that I would add to the import search directories). That's fine with me.

However, what's the point of having module declarations directives in the language then?

If I understand correctly, the only way to make an interesting use of these directives makes separate compilation impossible.

I know dmd is lightning-fast and everything, and not having to manage build dependencies anymore is very attractive.

However, we still need separate compilation. Otherwise your turnaround time is going to resemble a tractor pulling competition as your project grows. Recompiling everything everytime you change one module is not an option ; Some of the source files I work on in my company require 30s to compile *alone* ; it's easy to reach, especially when the language has features like templates and CTFE (Pegged anyone?).


March 02, 2016
On Monday, 29 February 2016 at 19:03:53 UTC, Sebastien Alaiwan wrote:
> Hi all,
>
> I've came across the following problem number of times.
> Let's say I have project A and B, sharing code but having a different tree structure.
>
> $ find projectA
> ./projectA/internal/math/algo.d
> ./projectA/internal/math/lcp.d
> ./projectA/internal/math/optimize.d
> ./projectA/gui/main.d
>
> $ find projectB
> ./projectB/app/render/gfx.d
> ./projectB/app/render/algo.d
> ./projectB/app/physics/math/algo.d
> ./projectB/app/physics/math/lcp.d
> ./projectB/app/physics/math/optimize.d
> ./projectB/main.d
>
> The directory "math" is shared between projects. It actually is an external/submodule. So it has a standalone existence as a library, and might one day be used by projectC.
> (In the context of this issue, I'm using separate compilation).
>
> I'd like to be able to write, in projectA's main:
>
> import internal.math.optimize;
>
> This requires me to add, at the beginning of "optimize.d" file, this module definition:
> module internal.math.optimize;
>
> However, this "optimize.d" file is shared between projects, now it's becoming specific to projectA.
>
> How am I supposed to share code between projects then?


Would this work?

1. pick a single module name like

    module math.optimize;

2. import that module with:

    import math.optimize;

3. put this module in a hierarchy like that:

    math/optimize.d

4. pass -I<directory-containing-math-directory> to the compiler

However it may clutter your module namespace a bit more.




March 02, 2016
On Wednesday, 2 March 2016 at 00:16:57 UTC, Guillaume Piolat wrote:
> Would this work?
>
> 1. pick a single module name like
>
>     module math.optimize;
>
> 2. import that module with:
>
>     import math.optimize;
>
> 3. put this module in a hierarchy like that:
>
>     math/optimize.d
>
> 4. pass -I<directory-containing-math-directory> to the compiler
>
> However it may clutter your module namespace a bit more.

Yeah, this is what I going to do: flat hierarchy, like one 'src' directory and one 'extra' directory in the project root, globally unique package names, passing -Isrc and -Iextra to the compiler, and ... module declaration directives.
I was trying to avoid them, but maybe it's not possible.

I still think that software entities shouldn't depend upon their own name, or their absolute location in the top-level namespace.

This is true for classes, functions/methods, variables, structures ... maybe this rule becomes invalid when third-party packages enter a project?

March 02, 2016
On Wednesday, 2 March 2016 at 06:40:53 UTC, Sebastien Alaiwan wrote:

> Yeah, this is what I going to do: flat hierarchy, like one 'src' directory and one 'extra' directory in the project root, globally unique package names, passing -Isrc and -Iextra to the compiler, and ... module declaration directives.
> I was trying to avoid them, but maybe it's not possible.

Every module you create will have a module name whether you use a module declaration or not. If you don't use one, the compiler uses the file name by default, but *only* the file name. The path on the file system is in no way taken into account (I suppose it could be by adding a flag to the compiler, but it seems to me that would needlessly complicate what is a really simple and easy to use system). A module with no package name is in the default package, i.e. given src/foo.d, using the following declaration:

module foo;

Is the same as using none at all. If you are content with keeping all of your modules in one or more top-level directory and use no packages, then you can leave out the module declarations and just pass each top-level directory to the compiler with -I.

>
> I still think that software entities shouldn't depend upon their own name, or their absolute location in the top-level namespace.
>
> This is true for classes, functions/methods, variables, structures ... maybe this rule becomes invalid when third-party packages enter a project?

The module names and package names are mangled into the symbol names in the binary. They also serve as namespaces to distinguish conflicting symbols in code. So yes, all of the symbols in a module are dependent on their location in the namespace. It's baked into the language.

I'm curious what sort of system you have in mind. How does the current system not work for you and what would you prefer to see?
March 02, 2016
On Wednesday, 2 March 2016 at 06:40:53 UTC, Sebastien Alaiwan wrote:
>
> Yeah, this is what I going to do: flat hierarchy, like one 'src' directory and one 'extra' directory in the project root, globally unique package names, passing -Isrc and -Iextra to the compiler, and ... module declaration directives.
> I was trying to avoid them, but maybe it's not possible.

TBH I'm not sure what module directives do now that you mention them.

March 02, 2016
On Tuesday, 1 March 2016 at 06:33:06 UTC, Sebastien Alaiwan wrote:
> However, we still need separate compilation. Otherwise your turnaround time is going to resemble a tractor pulling competition as your project grows. Recompiling everything everytime you change one module is not an option ; Some of the source files I work on in my company require 30s to compile *alone* ; it's easy to reach, especially when the language has features like templates and CTFE (Pegged anyone?).

Let me hype DUB a bit. :)

DUB provides completely composable dependencies, in a chain (A => B => C) with A not knowing about C.

Compile-times are excellent since DUB can do package-wise, file-wise or all-at-once builds from the same description and use caching.

Having a declarative build description allows for some goodies like IDE project generation.

The package namespace is global, but hierarchical with names like "myorg:mypackage".

However, you can't have versionned dependencies for private packages [painlessly] which is quite a big limitation.