December 19, 2016
Pushed again, now with the syntax using "with" proposed by Hatem Oraby and others.

https://github.com/dlang/DIPs/pull/51

https://github.com/dlang/DIPs/blob/71bde077488b566fba7603de6095b45984d9294a/DIPs/DIP1005.md


Andrei
December 19, 2016
Added this note about module constructors:

## Future Possibilities and Directions

Inline and scoped imports offer the option of better handling of static module constructors. Currently, modules that mutually `import` one another (either directly or through a longer chain) cannot simultaneously define `shared static this()` constructors. The reason is that, again, dependencies are computed at module level.

If instead modules have no top-level dependencies, then the compiler is able to compute the narrow set of dependencies needed for executing the static module constructor. The static constructor may be (a) a part of a `with` declaration, (b) use local imports within, and (c) call other functions within the module that have their own dependencies. For example:

```d
// assume no top-level import
with (module_a) void fun(T)()
{
    import module_b;
    return gun();
}
with (module_c)
static shared this()
{
    import module_d;
    fun!int;
}
```

In this case, the module constructor depends (only) on `module_a`, `module_b`, `module_c`, and `module_d`. The full information is confined within the current module so it is inferrable during separate compilation.



Andrei
December 19, 2016
On 12/14/2016 06:11 PM, H. S. Teoh via Digitalmars-d wrote:
> On thinking about this again, though, isn't the whole point of this DIP
> to add a way of attaching imports X, Y, Z to some declaration such that
> the imports are in effect for the scope of the declaration?  The
> specific syntax is really secondary.  I think we should rather be more
> concerned about the semantics of it, such as:
[snip]

Thanks very much for your review. I just pushed a commit addressing it. -- Andrei
December 19, 2016
On 12/14/2016 06:17 PM, Andrej Mitrovic wrote:
> On Wednesday, 14 December 2016 at 22:55:26 UTC, Andrei Alexandrescu wrote:
>> Made a pass through the document integrating a lot of feedback and
>> fleshing the proposal better:
>>
>> https://github.com/andralex/DIPs/blob/155ff59984b26749af7830aeb172d3af2dae8cd7/DIPs/DIP1005.md
>>
>>
>> https://github.com/dlang/DIPs/pull/51/files
>>
>>
>> Andrei
>
> I'd also mention that the advantage of this feature is for the human
> reader (and not just ddoc generators) as you can instantly tell where
> all the symbols are located which a function uses. It could save a lot
> of time for the reader when analyzing a function.
>
> For example, if we have a function like the following:
>
> ubyte[] readSomeBytes ( )
> {
>     return read(1024);
> }
>
> It's a non-trivial exercise for the reader to understand where the
> `read` symbol is coming from. It usually involves looking up the import
> list at the top of the module which is typically very long and contains
> unrelated imports as the DIP mentions.
>
> Sometimes you can use a symbol lookup shortcut in your editor, but with
> a name like `read` you'll likely get a dozen modules listed in the
> pop-up and you still couldn't immediately tell which one of the symbols
> this `read` call refers to. Someone will mention IDEs, but remember when
> you're looking at the code in another environment (say reviewing code on
> Github) you may not have quick point & click functionality to find the
> symbol declaration. That's another win for this DIP.

Cool, added that. -- Andrei

December 19, 2016
On 12/14/2016 08:59 PM, Timothee Cour via Digitalmars-d wrote:
> how about this:
>
> variant 1 // currently legal D; just need to attach semantics
>
> ```
> // applies to all below
> @deps!({import std.stdio; pragma(lib, "curl"); }):

Thanks, added. -- Andrei

December 19, 2016
On 12/15/2016 02:23 AM, Dominikus Dittes Scherkl wrote:
> Also I hate prototypes: .di-files are pretty useless - they make not
> clear what is needed to include and for templates you need the whole
> code anyway.

BTW are there outstanding issues with .di files? I recall some solid improvements were made a while ago. -- Andrei
December 19, 2016
On 12/17/2016 10:39 AM, Jacob Carlborg wrote:
> On 2016-12-13 23:33, Andrei Alexandrescu wrote:
>> Destroy.
>>
>> https://github.com/dlang/DIPs/pull/51/files
>
> A couple of questions.
>
> 1. The text says:
>
> "void process(File input) import (std.stdio);
>
> With this syntax, the import is executed only if the declared name is
> actually looked up."
>
> Is "declared name" referring to the function "process"? To me it sounds
> like it could be misinterpreted to refer to "File", which would indicate
> the import is lazily executed.
[snip]

Thanks, made a change. -- Andrei
December 19, 2016
On 12/19/2016 01:47 AM, Joakim wrote:
> Why do you care _so_ much about the module dependency graph?  To make
> this question concrete, let's look at an example, the std.array module
> you keep mentioning.
> This is what it looked like before Ilya scoped as
> many imports as he could:
>
> https://github.com/dlang/phobos/commit/3fcf723aa498b96de165361b5abb9d3450fdc069#diff-54cf8402b22024ae667d4048a5126f0e
>
> That was a mess, similar to opaque C/C++ code, 13 modules imported at
> module-scope were whittled down to 4.  You just made those more specific
> in a commit related to this DIP, by listing the actual symbols
> selectively imported from those four modules:
>
> https://github.com/dlang/phobos/commit/e064d5664f92c4b2f0866c08f6d0290ba66825ed#diff-54cf8402b22024ae667d4048a5126f0e
>
>
> If I'm looking at the template constraints for any particular function
> and see a couple symbols I don't recognize, I don't think it's a big
> deal to find the symbols in that list at the top.

It actually is. Some symbols in e.g. std.range are used in constraints, some others used in definitions; some in a UFCS manner. Some code runs during compilation, with errors gagged (as in __traits(compiles)) or not gagged. I don't know of an easy manual method to figure out who's who (which makes Vladimir's idea of tooling it with brute force awesome and scary at the same time).

At any way, I don't see how I can use this tidbit to improve the DIP. Anything I could add to it to make it more compelling?

> In other words, D already allows you to scope most imports.  I don't
> consider the dozen or two remaining symbols from templaint constraints
> and function arguments to provide much overhead.  Rather, I consider the
> weight of this additional syntax, ie the cognitive overhead from having
> to remember and parse more syntax in my head, to be worse than the
> remaining dependency reasoning problem you're trying to solve: the cost
> outweights the benefit.  Perhaps that's subjective and others may disagree.

It is subjective and difficult to convert into action. Online review among folks who know next to nothing about each other does have its challenges. What happens here is I post a proposal for a problem that I believe is important for large D projects. And I get back "eh, that's not as important to me." At a traditional work place we'd know a lot about one another's strengths, specialization areas, and design sensibilities. Here, all I can do is look at your past PRs (that's why I emailed you asking for your github handle; I figure it's @joakim-noah). This makes it difficult to act on "I don't buy it" feedback.

> Now, there's also the question of purely technical benefits, like
> compilation speed or executable bloat.  I looked at the latter a little
> last summer, after Ilya had cleaned up a lot of the standard library:
>
> http://forum.dlang.org/thread/gmjqfjoemwtvgqrtdsdr@forum.dlang.org
>
> I found that commenting out a single scoped, selective import of
> "std.string: format" in std.utf led to a 5% decrease in executable size
> for "hello world."  This is a problem with how dmd compiles or appends
> these module dependencies and would presumably still be there after this
> DIP, as you would not remove the dependency.

That might be a related but distinct issue. Can you reproduce that experiment?

> I think scoped, selective imports have been great at hacking away at the
> module dependency graph, as you lay out.  It is not clear what technical
> costs you see from the remaining few dependencies and if this DIP is the
> best way to remove them.  I think you should explain why you want to
> untangle the remaining dependency graph, and consider if this DIP is
> really doing that much.

I've made a few more passes through the DIP, but throughout I assume a couple of things without stressing them too much - dependencies are important, and associating dependencies with declarations makes the dependency graph as fine and as precise it could get. I don't see a reasonable way to make it better or clearer.

Should I add an introductory section on why dependencies are important?


Andrei
December 19, 2016
Andrei: you can use blockquotes to make long lines wrap when quoting text:

https://github.com/adam-p/markdown-here/wiki/Markdown-Here-Cheatsheet#blockquotes

that way, we don't have to scroll everytime there's a quote, eg:

replace:
<tab>Such scaffolding is of course
with:
> Such scaffolding is of course




On Mon, Dec 19, 2016 at 8:04 PM, Andrei Alexandrescu via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 12/19/2016 01:47 AM, Joakim wrote:
>
>> Why do you care _so_ much about the module dependency graph?  To make
>> this question concrete, let's look at an example, the std.array module
>> you keep mentioning.
>> This is what it looked like before Ilya scoped as
>> many imports as he could:
>>
>> https://github.com/dlang/phobos/commit/3fcf723aa498b96de1653 61b5abb9d3450fdc069#diff-54cf8402b22024ae667d4048a5126f0e
>>
>> That was a mess, similar to opaque C/C++ code, 13 modules imported at module-scope were whittled down to 4.  You just made those more specific in a commit related to this DIP, by listing the actual symbols selectively imported from those four modules:
>>
>> https://github.com/dlang/phobos/commit/e064d5664f92c4b2f0866 c08f6d0290ba66825ed#diff-54cf8402b22024ae667d4048a5126f0e
>>
>>
>> If I'm looking at the template constraints for any particular function and see a couple symbols I don't recognize, I don't think it's a big deal to find the symbols in that list at the top.
>>
>
> It actually is. Some symbols in e.g. std.range are used in constraints, some others used in definitions; some in a UFCS manner. Some code runs during compilation, with errors gagged (as in __traits(compiles)) or not gagged. I don't know of an easy manual method to figure out who's who (which makes Vladimir's idea of tooling it with brute force awesome and scary at the same time).
>
> At any way, I don't see how I can use this tidbit to improve the DIP. Anything I could add to it to make it more compelling?
>
> In other words, D already allows you to scope most imports.  I don't
>> consider the dozen or two remaining symbols from templaint constraints and function arguments to provide much overhead.  Rather, I consider the weight of this additional syntax, ie the cognitive overhead from having to remember and parse more syntax in my head, to be worse than the remaining dependency reasoning problem you're trying to solve: the cost outweights the benefit.  Perhaps that's subjective and others may disagree.
>>
>
> It is subjective and difficult to convert into action. Online review among folks who know next to nothing about each other does have its challenges. What happens here is I post a proposal for a problem that I believe is important for large D projects. And I get back "eh, that's not as important to me." At a traditional work place we'd know a lot about one another's strengths, specialization areas, and design sensibilities. Here, all I can do is look at your past PRs (that's why I emailed you asking for your github handle; I figure it's @joakim-noah). This makes it difficult to act on "I don't buy it" feedback.
>
> Now, there's also the question of purely technical benefits, like
>> compilation speed or executable bloat.  I looked at the latter a little last summer, after Ilya had cleaned up a lot of the standard library:
>>
>> http://forum.dlang.org/thread/gmjqfjoemwtvgqrtdsdr@forum.dlang.org
>>
>> I found that commenting out a single scoped, selective import of "std.string: format" in std.utf led to a 5% decrease in executable size for "hello world."  This is a problem with how dmd compiles or appends these module dependencies and would presumably still be there after this DIP, as you would not remove the dependency.
>>
>
> That might be a related but distinct issue. Can you reproduce that experiment?
>
> I think scoped, selective imports have been great at hacking away at the
>> module dependency graph, as you lay out.  It is not clear what technical costs you see from the remaining few dependencies and if this DIP is the best way to remove them.  I think you should explain why you want to untangle the remaining dependency graph, and consider if this DIP is really doing that much.
>>
>
> I've made a few more passes through the DIP, but throughout I assume a couple of things without stressing them too much - dependencies are important, and associating dependencies with declarations makes the dependency graph as fine and as precise it could get. I don't see a reasonable way to make it better or clearer.
>
> Should I add an introductory section on why dependencies are important?
>
>
> Andrei
>


December 19, 2016
what about using `lazy` instead of `with`:

`with(import foo)`
=>
`lazy(import foo)`

advantages:
* avoids confusion regarding usual scoping rules of `with` ;
* conveys that the import is indeed lazy

Furthermore (regardless of which keyword is used), what about allowing `:`
```
// case 1
lazy(import foo)
void fun(){}

// case 2
lazy(import foo) {
  void fun(){}
}

// case 3 : this is new
lazy(import foo):
void fun1(){}
void fun2(){}
```

advantages:

* same behavior as other constructs which don't introduce a scope:
```
// case 1, 2 3 are allowed:
version(A):
static if(true):
private:
void fun(){}
```

* avoids nesting when case 3 is used (compared to when using `{}`)

* I would argue that grouping lazy imports is actually a common case; without case 3, the indentation will increase.






On Mon, Dec 19, 2016 at 8:56 PM, Timothee Cour <thelastmammoth@gmail.com> wrote:

> Andrei: you can use blockquotes to make long lines wrap when quoting text:
>
> https://github.com/adam-p/markdown-here/wiki/Markdown- Here-Cheatsheet#blockquotes
>
> that way, we don't have to scroll everytime there's a quote, eg:
>
> replace:
> <tab>Such scaffolding is of course
> with:
> > Such scaffolding is of course
>
>
>
>
> On Mon, Dec 19, 2016 at 8:04 PM, Andrei Alexandrescu via Digitalmars-d < digitalmars-d@puremagic.com> wrote:
>
>> On 12/19/2016 01:47 AM, Joakim wrote:
>>
>>> Why do you care _so_ much about the module dependency graph?  To make
>>> this question concrete, let's look at an example, the std.array module
>>> you keep mentioning.
>>> This is what it looked like before Ilya scoped as
>>> many imports as he could:
>>>
>>> https://github.com/dlang/phobos/commit/3fcf723aa498b96de1653 61b5abb9d3450fdc069#diff-54cf8402b22024ae667d4048a5126f0e
>>>
>>> That was a mess, similar to opaque C/C++ code, 13 modules imported at module-scope were whittled down to 4.  You just made those more specific in a commit related to this DIP, by listing the actual symbols selectively imported from those four modules:
>>>
>>> https://github.com/dlang/phobos/commit/e064d5664f92c4b2f0866 c08f6d0290ba66825ed#diff-54cf8402b22024ae667d4048a5126f0e
>>>
>>>
>>> If I'm looking at the template constraints for any particular function and see a couple symbols I don't recognize, I don't think it's a big deal to find the symbols in that list at the top.
>>>
>>
>> It actually is. Some symbols in e.g. std.range are used in constraints, some others used in definitions; some in a UFCS manner. Some code runs during compilation, with errors gagged (as in __traits(compiles)) or not gagged. I don't know of an easy manual method to figure out who's who (which makes Vladimir's idea of tooling it with brute force awesome and scary at the same time).
>>
>> At any way, I don't see how I can use this tidbit to improve the DIP. Anything I could add to it to make it more compelling?
>>
>> In other words, D already allows you to scope most imports.  I don't
>>> consider the dozen or two remaining symbols from templaint constraints and function arguments to provide much overhead.  Rather, I consider the weight of this additional syntax, ie the cognitive overhead from having to remember and parse more syntax in my head, to be worse than the remaining dependency reasoning problem you're trying to solve: the cost outweights the benefit.  Perhaps that's subjective and others may disagree.
>>>
>>
>> It is subjective and difficult to convert into action. Online review
>> among folks who know next to nothing about each other does have its
>> challenges. What happens here is I post a proposal for a problem that I
>> believe is important for large D projects. And I get back "eh, that's not
>> as important to me." At a traditional work place we'd know a lot about one
>> another's strengths, specialization areas, and design sensibilities. Here,
>> all I can do is look at your past PRs (that's why I emailed you asking for
>> your github handle; I figure it's @joakim-noah). This makes it difficult to
>> act on "I don't buy it" feedback.
>>
>> Now, there's also the question of purely technical benefits, like
>>> compilation speed or executable bloat.  I looked at the latter a little last summer, after Ilya had cleaned up a lot of the standard library:
>>>
>>> http://forum.dlang.org/thread/gmjqfjoemwtvgqrtdsdr@forum.dlang.org
>>>
>>> I found that commenting out a single scoped, selective import of "std.string: format" in std.utf led to a 5% decrease in executable size for "hello world."  This is a problem with how dmd compiles or appends these module dependencies and would presumably still be there after this DIP, as you would not remove the dependency.
>>>
>>
>> That might be a related but distinct issue. Can you reproduce that experiment?
>>
>> I think scoped, selective imports have been great at hacking away at the
>>> module dependency graph, as you lay out.  It is not clear what technical costs you see from the remaining few dependencies and if this DIP is the best way to remove them.  I think you should explain why you want to untangle the remaining dependency graph, and consider if this DIP is really doing that much.
>>>
>>
>> I've made a few more passes through the DIP, but throughout I assume a couple of things without stressing them too much - dependencies are important, and associating dependencies with declarations makes the dependency graph as fine and as precise it could get. I don't see a reasonable way to make it better or clearer.
>>
>> Should I add an introductory section on why dependencies are important?
>>
>>
>> Andrei
>>
>
>