Jump to page: 1 2 3
Thread overview
Is package.d a good idea?
Jul 01, 2018
Yuxuan Shui
Jul 01, 2018
rikki cattermole
Jul 01, 2018
Jonathan M Davis
Jul 01, 2018
Yuxuan Shui
Jul 01, 2018
Adam D. Ruppe
Jul 01, 2018
Yuxuan Shui
Jul 02, 2018
12345swordy
Jul 01, 2018
Basile B.
Jul 02, 2018
Jonathan M Davis
Jul 03, 2018
bauss
Jul 03, 2018
bauss
Jul 03, 2018
aliak
Jul 04, 2018
WebFreak001
Jul 04, 2018
Adam D. Ruppe
Jul 04, 2018
aliak
Jul 04, 2018
Jonathan M Davis
Jul 04, 2018
Jonathan M Davis
July 01, 2018
In Rust, they have something call mod.rs, which is very similar to package.d. When you use a module 'foo' in Rust, it can either be 'foo.rs' or 'foo/mod.rs'. If 'foo' has sub-modules, it has to be 'foo/mod.rs'.

Now in the Rust 2018 edition, they are getting rid of mod.rs. So when you import 'foo', rustc will always look for 'foo.rs', and if 'foo' has submodules, it can still reside in 'foo/submodule.rs'.

This makes me think if package.d is a good idea, and if we should try to get rid of it as well.
July 01, 2018
On 01/07/2018 11:36 PM, Yuxuan Shui wrote:
> In Rust, they have something call mod.rs, which is very similar to package.d. When you use a module 'foo' in Rust, it can either be 'foo.rs' or 'foo/mod.rs'. If 'foo' has sub-modules, it has to be 'foo/mod.rs'.
> 
> Now in the Rust 2018 edition, they are getting rid of mod.rs. So when you import 'foo', rustc will always look for 'foo.rs', and if 'foo' has submodules, it can still reside in 'foo/submodule.rs'.
> 
> This makes me think if package.d is a good idea, and if we should try to get rid of it as well.

We added it a few years ago after 10+ years of people having a module called 'all' which did the same exact job just without the compiler help.

So no, we should not get rid of it, because its works pretty well over here :)
July 01, 2018
On Sunday, July 01, 2018 11:36:51 Yuxuan Shui via Digitalmars-d wrote:
> In Rust, they have something call mod.rs, which is very similar to package.d. When you use a module 'foo' in Rust, it can either be 'foo.rs' or 'foo/mod.rs'. If 'foo' has sub-modules, it has to be 'foo/mod.rs'.
>
> Now in the Rust 2018 edition, they are getting rid of mod.rs. So when you import 'foo', rustc will always look for 'foo.rs', and if 'foo' has submodules, it can still reside in 'foo/submodule.rs'.
>
> This makes me think if package.d is a good idea, and if we should try to get rid of it as well.

The entire reason that package.d was added as a feature was so that modules could be split into packages without breaking code, and it's still valuable for that.

Now, other folks have liked the idea of using it to import a lot of code with a single module - potentially even importing entire librares at once - but with the increasing focus on local and scoped imports, best practice really leans towards importing each symbol individually, which is the complete opposite of the spectrum from importing entire packages at once and means that using package.d in order to import a bunch of other modules arguably goes against current best practice. Regardless, I expect that some folks will continue to want to do it - especially for stuff like scripts where you really don't want to bother importing each symbol individually.

- Jonathan M Davis

July 01, 2018
On Sunday, 1 July 2018 at 11:55:17 UTC, Jonathan M Davis wrote:
> On Sunday, July 01, 2018 11:36:51 Yuxuan Shui via Digitalmars-d wrote:
>> [...]
>
> The entire reason that package.d was added as a feature was so that modules could be split into packages without breaking code, and it's still valuable for that.
>
> [...]

I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.
July 01, 2018
On Sunday, 1 July 2018 at 14:23:36 UTC, Yuxuan Shui wrote:
> I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.

Yeah, that's the way it should have been done in the first place. Nowhere else in D does it require a specific filename except package.d - it is a pointless inconsistency anyway.
July 01, 2018
On Sunday, 1 July 2018 at 14:23:36 UTC, Yuxuan Shui wrote:
> On Sunday, 1 July 2018 at 11:55:17 UTC, Jonathan M Davis wrote:
>> On Sunday, July 01, 2018 11:36:51 Yuxuan Shui via Digitalmars-d wrote:
>>> [...]
>>
>> The entire reason that package.d was added as a feature was so that modules could be split into packages without breaking code, and it's still valuable for that.
>>
>> [...]
>
> I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.

You mean that if no package.d is present, the import that *would* match to the missing package is then equivalent to an automatic public import for each module prefixed ?

- case 1 : `import foo;` use package.d


foo/package.d
   /bar.d
   /baz.d

- case 2 : `import foo;` make all stuff (bar/baz) public imports automatically if no package.d

foo/bar.d
   /baz.d

If this is what you mean then this could indeed be added, as sugar, in addition to the existing system of package. By "could" i mean from a technical P.o.V, because of course this kind of stuff are decided elsewhere.
July 01, 2018
On Sunday, 1 July 2018 at 18:03:41 UTC, Adam D. Ruppe wrote:
> On Sunday, 1 July 2018 at 14:23:36 UTC, Yuxuan Shui wrote:
>> I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.
>
> Yeah, that's the way it should have been done in the first place. Nowhere else in D does it require a specific filename except package.d - it is a pointless inconsistency anyway.

Now we just need to wait for someone to write the DIP....
July 02, 2018
On Sunday, 1 July 2018 at 21:40:05 UTC, Yuxuan Shui wrote:
> On Sunday, 1 July 2018 at 18:03:41 UTC, Adam D. Ruppe wrote:
>> On Sunday, 1 July 2018 at 14:23:36 UTC, Yuxuan Shui wrote:
>>> I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.
>>
>> Yeah, that's the way it should have been done in the first place. Nowhere else in D does it require a specific filename except package.d - it is a pointless inconsistency anyway.
>
> Now we just need to wait for someone to write the DIP....

There nothing prevent you from writing one, is there?

-Alexander Heistermann
July 01, 2018
On Sunday, July 01, 2018 14:23:36 Yuxuan Shui via Digitalmars-d wrote:
> On Sunday, 1 July 2018 at 11:55:17 UTC, Jonathan M Davis wrote:
> > On Sunday, July 01, 2018 11:36:51 Yuxuan Shui via Digitalmars-d
> >
> > wrote:
> >> [...]
> >
> > The entire reason that package.d was added as a feature was so that modules could be split into packages without breaking code, and it's still valuable for that.
> >
> > [...]
>
> I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.

So, basically, we'd implicitly have a package.d for every package where each implicit package.d publicly imported every module in its package (including the implicit package.d from any sub-packages)? Well, for starters, that's going in pretty much the opposite direction of where best practice in D has been going. Local and scoped imports have become best practice, which means writing stuff like

import std.conv : to;

inside the function that's using std.conv.to rather than

import std.conv;

at the top of the file, let alone

import std;

So, the suggestion that you could just import any package and get everything in it recursively, doesn't really fit with where we've been going. Regardless of that though, I'm not even sure that it works with D's import model.

As things stand, D only ever imports exactly the modules that you tell it to import. It doesn't even have the concept of importing a package. package.d is a file like any other. It's just that the compiler has the little bit of magic to know that if it's told to import a.b that if a/b/package.d exists and has the module declaration for a.b, then it should be treated as being module a.b. The only reason that package.d then ends up importing the entire package is because the programmer explicitly pubicly imports each module from the package. They could do something else, and in some cases, it makes good sense to do stuff like include modules from elsewhere or to exclude modules from within the package. Your suggestion gives no such control, which could be a serious downside.

But aside from the control issue, the fact of the matter is that D currently only imports what it's told to import. It doesn't have to know or care what all of the modules in a package are. It just goes and grabs what it's told to grab, whereas if it has to search recursively, then that probably negatively impacts the performance of imports, and it fundamentally changes how importing works, because then instead of just grabbing what it's told to grab, it has to compile the list based on what it finds - which may or may not be the correct list. If any modules are missing for some reason, or if the compiler's import paths are misconfigured, then you could think that you're importing a module when you're not, which could lead to function hijacking when you try to use the function. In most cases, it would just be a compilation error, because the symbol is missing, but if another symbol which isn't missing happens to match, then instead of getting a symbol conflict, it would call the wrong function. It's the sort of thing that's a lot more likely to happen when installs and upgrades go wrong than during your typical development, but it does make the situation more error-prone than it is now.

It also wouldn't work well if anyone did something like split a package across libraries (which is a questionable practice but perfectly legal). When you compiled one library, you'd get one set of modules when importing the package, and when you imported another module, you'd get a different set (whereas right now, you just get the modules that you explicitly imported). What you'd get when using both libraries would then be highly dependent on how you compile your code. The idea that you're going to recursively find all of the modules in a package simply doesn't work well with a separate compilation model. It's not impossible to make work, but it's error-prone.

And of course, I have no clue how any of this interacts with modules where the file name doesn't match the module declaration (which is unfortunately very purposefully legal). It's something that I never do (and doesn't tend to work well with some build tools), so I don't understand the details very well, but it's the sort of detail that makes the whole situation much more complicated.

If someone wants to write a DIP on this, then they can, but the whole idea seems to fly in the face of current best practice in D, and honestly, the whole idea just seems error-prone. It would probably work a decent percentage of the time, but it looks like it has some nasty corner cases, and it would almost certainly hurt compilation speed.

As it is, Walter approved package.d precisely because it added almost nothing. It just used the pre-existing import rules with the change that the compiler would know to check for the existance of package.d. The import rules themselves didn't change at all. So, the whole thing was simple and clean. It also was never done with the intention of making it common practice to import entire packages at once but simply as a way to aid in refactoring a module without breaking existing code. So, the goal which got it approved was very different.

- Jonathan M Davis

July 03, 2018
On 07/01/2018 10:23 AM, Yuxuan Shui wrote:
> 
> I was suggesting we do what Rust did. i.e. 'import foo', imports foo.d, which can in turn do 'import foo.bar', which will import foo/bar.d.

AIUI, D doesn't support having *both* a module (ie, file 'foo.d') and a package (ie, directory 'foo/') with the same name (ie, 'foo')...for some goofy unknown reason. I agree that suggestion is how it should've been from the start.
« First   ‹ Prev
1 2 3