April 06, 2012
On Thu, 05 Apr 2012 17:43:24 -0400, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 4/5/12 4:26 PM, Steven Schveighoffer wrote:
>> On Thu, 05 Apr 2012 17:00:56 -0400, Jonathan M Davis
>> <jmdavisProg@gmx.com> wrote:
>>
>>> On Thursday, April 05, 2012 15:30:17 Steven Schveighoffer wrote:
>>
>>>> I don't see how. Just move the code into another module and publicly
>>>> import that module from std/algorithm.d. Problem pretty much solved.
>>>
>>> The issue is code organization. If you want to split up std.algorithm (or
>>> std.datetime or whatever) into multiple modules, you have to create a new
>>> package with a completely different name with no connection to the
>>> original
>>> save for the fact that the original publicly imports it.
>>
>> My view is that people will not import the smaller modules, they will
>> only ever import std.algorithm.
>
> I think we should be looking for a solution that not only allows replacing module -> package transparently, but also allows people to import the newly introduced fine-grained modules.

Of course you *can* do this.  I think you mean "and allows one to refer to the fine grained module as if it were imported from the top-level module".

I don't think that benefit is very great.  Why shouldn't we expect people to use the module name they actually imported to refer to a module?  If you want selective import, we have:

import std.algorithm : sort;

I think the real benefit to splitting up the module comes from being able to draw clear lines between which pieces of a large module are related.

I feel like most people will still import the main package module, and not the submodules.  I don't think I ever wrote a piece of java code that didn't have:

import java.io.*;

I keep coming back to std.container.  Already it's large, and full of unrelated types.  It's only going to get worse.

Now, I fully agree that having some way to import a package by itself without having to import all its modules would be ideal (as well as splitting a large module into submodules that live in the same namespace).  I think DIP15 has that covered.

-Steve
April 06, 2012
On 2012-04-06 09:41:27 +0000, deadalnix <deadalnix@gmail.com> said:

> Why not limit name collision to name which make sense ?

You're proposing that fully qualified names sometime work and sometime do not work based on what you've imported and the context of usage. This makes any FQN conflict hard to detect, because the error will be dependent on the context in which you use the name.

You say it'll never happen for modules spitted in submodules, but I disagree. Someday, someone will add a symbol to a submodule without checking every package/module file underneath. Unit tests in the module won't catch the problem because for them to catch the problem the parent module/package has to be imported. Only on certain usages, with the right imports and in the right context will the error occur.

In fact, if you add disambiguation based on what "makes sense" you're making the error more obscure and harder to detect in the first place because sometime it'll occur and sometime not depending on hard to predict conditions.

If we allow arbitrary symbols to live inside a package, any conflict in FQN should be caught as soon as possible, ideally as soon as you compile after having added the symbol, and even if you don't use the symbol anywhere. Just like how you get an error today when you try to import a module matching a known package name, you shouldn't be allowed to import a module matching a known symbol name, or create a symbol matching a module fully qualified name.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

April 06, 2012
On 4/6/12 4:43 AM, deadalnix wrote:
> Le 06/04/2012 01:32, Michel Fortin a écrit :
>> On 2012-04-05 21:43:24 +0000, Andrei Alexandrescu
>> <SeeWebsiteForEmail@erdani.org> said:
>>
>>> I think we should be looking for a solution that not only allows
>>> replacing module -> package transparently, but also allows people to
>>> import the newly introduced fine-grained modules.
>>
>> I think it'd be valuable too. But how do you do that without creating
>> ambiguous fully qualified names?
>>
>
> It isn't possible. But as already mentioned, all name doesn't make sense
> in all situation, so most of the time, disambiguation can be done.
>
> Plus, we want to be able to split module when they grow, and in such a
> situation, collisions will never happen, because all symbols comes from
> the same module in a first place.

One other desirable feature is library distribution. Library writers should be able to offer library xyz as a sheer directory. Then library users should be able to import path.to.xyz and simply get going, or even rename xyz to xyz1 and import path.to.xyz1 without a problem.

Andrei
April 06, 2012
Le 06/04/2012 16:49, Andrei Alexandrescu a écrit :
> On 4/6/12 4:43 AM, deadalnix wrote:
>> Le 06/04/2012 01:32, Michel Fortin a écrit :
>>> On 2012-04-05 21:43:24 +0000, Andrei Alexandrescu
>>> <SeeWebsiteForEmail@erdani.org> said:
>>>
>>>> I think we should be looking for a solution that not only allows
>>>> replacing module -> package transparently, but also allows people to
>>>> import the newly introduced fine-grained modules.
>>>
>>> I think it'd be valuable too. But how do you do that without creating
>>> ambiguous fully qualified names?
>>>
>>
>> It isn't possible. But as already mentioned, all name doesn't make sense
>> in all situation, so most of the time, disambiguation can be done.
>>
>> Plus, we want to be able to split module when they grow, and in such a
>> situation, collisions will never happen, because all symbols comes from
>> the same module in a first place.
>
> One other desirable feature is library distribution. Library writers
> should be able to offer library xyz as a sheer directory. Then library
> users should be able to import path.to.xyz and simply get going, or even
> rename xyz to xyz1 and import path.to.xyz1 without a problem.
>
> Andrei

Good point. That is an argument for package.d, all.d or _.d .
April 06, 2012
On 4/6/12 10:52 AM, deadalnix wrote:
> Good point. That is an argument for package.d, all.d or _.d .

Or [packagename].d, where [packagename] is the name of its sibling folder (std/algorithm.d in the case of std/algorithm/sort.d).
April 06, 2012
Le 06/04/2012 20:03, David Gileadi a écrit :
> On 4/6/12 10:52 AM, deadalnix wrote:
>> Good point. That is an argument for package.d, all.d or _.d .
>
> Or [packagename].d, where [packagename] is the name of its sibling
> folder (std/algorithm.d in the case of std/algorithm/sort.d).

No, because in this case, this isn't in the same folder. Still I prefer that opetion because :

1/ You mostly distribute lib as archives, or in a managed way (package manager, build system, etc . . .)
2/ It is simpler as import a.b.c always does the same thing, and other solution introduce complexity in that process, and possible cases of error.
April 07, 2012
On Friday, April 06, 2012 08:09:28 Steven Schveighoffer wrote:
> I feel like most people will still import the main package module, and not the submodules.  I don't think I ever wrote a piece of java code that didn't have:
> 
> import java.io.*;

Which is actually considered bad practice in Java, though a lot of people do like to do it. What's generally considered good practice is to explicitly import every module/class, and Eclipse likes to underline imports in red if you don't.

> I keep coming back to std.container.  Already it's large, and full of unrelated types.  It's only going to get worse.
> 
> Now, I fully agree that having some way to import a package by itself without having to import all its modules would be ideal (as well as splitting a large module into submodules that live in the same namespace).  I think DIP15 has that covered.

DIP15 doesn't fix the explicit path problem though. You can't change std/algorithm.d into std/algorithm/ (with sorting.d, search.d, etc.) without breaking code. You could make std/algorithm.d publicly import std/alg/* and then DIP15 would allow you to import std.alg to get all of its sub-modules, but you're still forced to use a module to publicly import symbols as part of a migration path, and you can't split a module in place.

DIP15 also less powerful than having a package.d, since it'll automatically import ever public symbol when it may be desirable to have it only import a subset of them or to publicly import something from another module (e.g. as part of a migration path - like moving the benchmarking code in std.datetime to std.benchmark rather than lumping it with the std.datetime stuff when it's split into separate modules). That may or may not be a big deal, but it does mean that DIP15 isn't as powerful as DIP16's package.d solution in that regard.

DIP15 also doesn't give a means of documentating a package. By having a package.d file, we have a really good place to provide an overarching description for the package in ddoc.

So, while I don't like the second part of DIP16 at all (i.e. the std.sort stuff), I think that the package.d part is a much better way to go.

- Jonathan M Davis
April 07, 2012
On Friday, April 06, 2012 07:56:41 Steven Schveighoffer wrote:
> On Thu, 05 Apr 2012 19:14:42 -0400, Jonathan M Davis <jmdavisProg@gmx.com>
> 
> wrote:
> > On Thursday, April 05, 2012 17:33:50 Steven Schveighoffer wrote:
> >> Why do we ever need to split modules for documentation? Just fix the doc generator so it's not as monolithic. For instance, have one page per class or struct.
> > 
> > That may or may not be desirable (certainly in the case of smaller
> > types, I'd
> > argue that it isn't). By doing it on a module basis, you have far more
> > control. But regardless, that would be a major change to ddoc.
> 
> ddoc's output leaves a lot to be desired.  The unorganized links at the top suck.  Using module order to show symbols instead of category of symbols.
> 
> How is a doc page ever "too big"?  Even std.datetime loads in a second. It's more that it's "too disorganized".

There's no question that the links at the top suck, and std.datetime is the poster child for why they suck. The page is too large for how its organized, and it _does_ take significantly longer to load than other Phobos pages, even if it's still usable. There's no question that better links would help significantly though.

Regardless, there's enough content there that it would arguably be better served if it were multiple pages.

> >> > And if all you care
> >> > about is sub-modules for implementation and want all of the functions
> >> 
> >> in
> >> 
> >> > the
> >> > same module still, then this DIP is pointless. All you have to do is
> >> > declare
> >> > undocumented sub-modules which hold the various implementations and
> >> 
> >> have
> >> 
> >> > the
> >> > actual module call them. We already do this sort of thing in Phobos to
> >> > get
> >> > around static destructors screaming about circular dependencies.
> >> 
> >> You are starting to see my point :) But I think the issue is not so much that you are splitting the implementation, but splitting up the API into related modules.
> > 
> > As I understand it, the entire point of this DIP is to enable splitting
> > up the
> > API cleanly without breaking code. The implementation can already be
> > split up
> > seemlessly.
> 
> As can the API via public imports.

Not and keep stuff in the same place in the hierarchy. You have to create a completely separate package. The point of the DIP was to make it so that you could do it _in place_ by turning a module like std/algorithm.d into the package std/algorithm/ with modules inside it.

Right now, I can go and split up std.datetime into a new package (e.g. std.dtime) and then publicly import it all from std.datetime, but then the new package is completely separate from the module which imports everything. It also makes it look like std.datetime should go away in favor of just keeping std.dtime (the same with std.algorithm if it gets split), which may or may not actually be desirable. Organizationally, it would be much nicer to be able to turn std/datetime.d into std/datetime/, and _that_ is what the DIP is trying to enable. The rest can be done now but not that. You can't split up the API in place.

- Jonathan M Davis
April 07, 2012
On 2012-04-07 02:25, Jonathan M Davis wrote:
> On Friday, April 06, 2012 08:09:28 Steven Schveighoffer wrote:
>> I feel like most people will still import the main package module, and not
>> the submodules.  I don't think I ever wrote a piece of java code that
>> didn't have:
>>
>> import java.io.*;
>
> Which is actually considered bad practice in Java, though a lot of people do
> like to do it. What's generally considered good practice is to explicitly
> import every module/class, and Eclipse likes to underline imports in red if
> you don't.

import foo.bar.*

Is used all over the place in SWT.

-- 
/Jacob Carlborg
April 07, 2012
On Saturday, April 07, 2012 18:45:15 Jacob Carlborg wrote:
> On 2012-04-07 02:25, Jonathan M Davis wrote:
> > On Friday, April 06, 2012 08:09:28 Steven Schveighoffer wrote:
> >> I feel like most people will still import the main package module, and
> >> not
> >> the submodules.  I don't think I ever wrote a piece of java code that
> >> didn't have:
> >> 
> >> import java.io.*;
> > 
> > Which is actually considered bad practice in Java, though a lot of people do like to do it. What's generally considered good practice is to explicitly import every module/class, and Eclipse likes to underline imports in red if you don't.
> 
> import foo.bar.*
> 
> Is used all over the place in SWT.

Like I said, some people do like to do it, but Eclipse doesn't like you to, and there are quite a few Java folks who argue that it's bad practice. I forget what the reasons were (maybe increased buld times due to pulling in more symbols or more issues with symbol conflicts - I don't recall), but I wasn't particularly convinced when I heard them. Regardless though, there's a definite contingent against importing with * in the Java community, and it was my understanding that that contigent was the majority of that community, but I don't know.

- Jonathan M Davis