December 14, 2016
On 12/14/2016 12:32 PM, H. S. Teoh via Digitalmars-d wrote:
> 	import {
> 		std.range : isInputRange,
> 		std.traits : isNum = isNumeric
> 	}

This seems ambiguous. In

import { a : b, c.d }

did you meant to import c.d from a, or a different module?


Andrei
December 14, 2016
On 12/14/2016 02:22 PM, Timothee Cour via Digitalmars-d wrote:
> What about simply this:
>
>
> ```
> module foo;
>
> {
> import std.stdio;
> void fun(File foo){}
> }
>
> {
> import sd.range;
> void foo(T) if(isInputRange!T){}
> }
>
> ```

Walter proposed this as well. We found two problems with it: (a) it is not clear that the import is effected only if the name is looked up; (b) the common case is one import clause for one declaration, which makes the code awkward. Either you have an indirection level to start with:

{
    import std.range;
    void foo(T) if(isInputRange!T)
    {
        ... one extra indent already ...
    }
}

or the horror of C++ namespaces:

{import std.range;

void foo(T) if(isInputRange!T)
{
   ...
}
}

The fact that C++ namespaces introduce scopes has been an unpleasant mistake. Virtually all coding standards I've seen make namespace-introduced scopes special in that they don't participate in the usual indentation rules. Even special emacs and vi rules have been devised for that. Something we can learn from.


Andrei
December 14, 2016
On 12/14/2016 02:04 PM, Meta wrote:
> On Wednesday, 14 December 2016 at 17:32:10 UTC, H. S. Teoh wrote:
>> What about:
>>
>>     /* Showing full declaration just for context */
>>     bool myFunc(R1, R2)(R1 r1, R2 r2)
>>     import {
>>         std.range : isInputRange,
>>         std.traits : isNum = isNumeric
>>     }
>>     if (isInputRange!R1 && isInputRange!R2 &&
>>         isNum!(ElementType!R1))
>>     in { assert(someCondition!R1); }
>>     out(result) { assert(result == expectedResult(...)); }
>>     body
>>     {
>>         ...
>>     }
>>
>>
>> T
>
> The fact that declarations like this WILL show up in Phobos or elsewhere
> if this proposal is implemented triggers my gag reflex. There's got to
> be a better way than tacking yet another pre-ambulatory clause to the
> function body.

What I see here is a function definition that has:

* parameters and return types
* dependencies on other modules
* the static condition under which arguments are acceptable
* the dynamic condition under which arguments are acceptable
* the guarantee made upon successful completion
* the implementation

... each of which is:

* easily distinguishable
* opt-in


Andrei

December 14, 2016
On 12/13/2016 05:33 PM, Andrei Alexandrescu wrote:
> Destroy.
>
> https://github.com/dlang/DIPs/pull/51/files

I just realized there is a ddoc consequence to this: ddoc could generate the import list and make that available to the generated documentation. I'll add that to the DIP. -- Andrei

December 14, 2016
On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
> Destroy.
>
> https://github.com/dlang/DIPs/pull/51/files
>
>
> Andrei

I think the DIP indicated you may have considered this, but why not just remove the requirement of 'static import ..' for using fully qualified names?

struct Buffered(Range) if (std.range.isInputRange!Range)
{
    import std.range;
    // ...
}

You could then simply qualify any parameters or constraints and use local imports for the body.

    Bit

December 14, 2016
On 12/14/2016 03:13 PM, bitwise wrote:
> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>> Destroy.
>>
>> https://github.com/dlang/DIPs/pull/51/files
>>
>>
>> Andrei
>
> I think the DIP indicated you may have considered this, but why not just
> remove the requirement of 'static import ..' for using fully qualified
> names?
>
> struct Buffered(Range) if (std.range.isInputRange!Range)
> {
>     import std.range;
>     // ...
> }
>
> You could then simply qualify any parameters or constraints and use
> local imports for the body.

We'd like people and simplistic tools such as grep to indicate quickly where imports are present. -- Andrei

December 14, 2016
On Wed, Dec 14, 2016 at 02:30:29PM -0500, Andrei Alexandrescu via Digitalmars-d wrote:
> On 12/14/2016 12:32 PM, H. S. Teoh via Digitalmars-d wrote:
> > 	import {
> > 		std.range : isInputRange,
> > 		std.traits : isNum = isNumeric
> > 	}
> 
> This seems ambiguous. In
> 
> import { a : b, c.d }
> 
> did you meant to import c.d from a, or a different module?
> 
[...]

That's easy to fix:

	import { a : b, c;  d: e, f; }


T

-- 
There is no gravity. The earth sucks.
December 14, 2016
On Wednesday, 14 December 2016 at 12:30:33 UTC, ketmar wrote:
> On Wednesday, 14 December 2016 at 12:15:20 UTC, Joseph Rushton Wakeling wrote:
>> Yea, I think you put your finger on it: almost all of the stuff this feature could help achieve in Phobos could be just as well achieved by splitting stuff up better.
>
> no, it can't. why should i remember that i have to import "std.range.xyz" for something? of course, i will write `import std.range;` and forget about it. no kind of splitting will allow me to have self-contained "hygienic" declarations.

Yeah, modularity from the standpoint of importing a set of functions and modularity from the standpoint of what those functions import are orthogonal concerns. Without this DIP, we're often unable to treat them orthogonally, but in principle, they are. Are this DIP (regardless of the exact syntax) would allow us to.

- Jonathan M Davis
December 14, 2016
On 12/14/2016 03:33 PM, H. S. Teoh via Digitalmars-d wrote:
> That's easy to fix:
>
> 	import { a : b, c;  d: e, f; }

The cost being adding new syntax. -- Andrei
December 14, 2016
On Wednesday, 14 December 2016 at 14:11:47 UTC, Andrei Alexandrescu wrote:
> * I predict 90% of the time there will be one import per declaration, which takes it down to:
>
> with (import std.range)
> void foo(T) if (isInputRange!T) {}
>
> which underlines the redundancy of the "with".

Honestly, while I can see some value in what Jacob is suggesting, because it allows you to restrict some imports without repeating them, I think that the reality of the matter is that in practice, it would result in the imports just being at the top of the module - particularly when you consider that function signtaures are actually pretty far apart in most cases, since you have the function body (which is often not small), the unittest block, and the documentation for the next function, making it pretty ugly to wrap all of those in an import block.

- Jonathan M Davis