December 14, 2016
On Wednesday, 14 December 2016 at 07:17:57 UTC, Jacob Carlborg wrote:
> On 2016-12-14 03:23, Andrei Alexandrescu wrote:
>> On 12/13/16 9:22 PM, Hatem Oraby wrote:
>
>>> with(import std.range)
>>> bool equal(R1, R2) if (isInputRange!R1 && isInputRange!R2)
>>> { ... }
>>
>> I considered this, then figured with is superfluous. -- Andrei
>
> It could allow to have a better control of the scope which the import affects, i.e.:
>
> with(import std.range)
> {
>   void foo(T) if (isInputRange!T)
>   void bar(T) if (isInputRange!T)
> }

Trouble is, there's no real difference between doing that, vs. creating a standalone module containing `foo` and `bar` with `import std.range;` as a top-level import.

The `with` syntax could also be used internally in functions to narrow the functionality that has access to the imported symbols, but something like:

void foo(T)(T input)
{
    with (import some_module)
    {
        // only stuff in here has access
        // to some_module's symbols
    }

    // nothing here has access to
    // some_module's symbols
}

... doesn't give you anything that you can't already get using:

void foo(T)(T input)
{
    {
        import some_module;
        // only stuff in here has access
        // to some_module's symbols
    }

    // nothing here has access to
    // some_module's symbols
}

In fact that's a good argument against the `with` syntax entirely, because in typical usage AFAIR, it creates a scope, whereas one wouldn't want the symbols defined in Hatem's proposal to be scoped relative to the module.

It's a shame, because unlike Andrei I don't feel use of `with` is in principle superfluous: it has a value in clarifying intention, while allowing the use of traditional `import something` syntax.  But special-casing of where `with` does and doesn't create a scope seems ... less good.
December 14, 2016
On Wednesday, 14 December 2016 at 01:53:44 UTC, Chris M. wrote:
> How about using "imports" instead of "import"? Simple enough change, and it still makes sense
>
> bool equal(R1, R2)
> imports (std.range)
> if (isInputRange!R1 && isInputRange!R2)
> { ... }

On Tuesday, 13 December 2016 at 23:03:39 UTC, Timon Gehr wrote:
> I'd prefer syntax like (import foo.bar).baz and (import foo).bar.baz. (I.e., the syntax of import expressions would closely mirror that of import declarations, and would be unambiguous.)
>
> 2. The behaviour of aliases to import expressions should be defined explicitly.
>
> I.e.
>
> alias short = import very.long.module_name;
>
> void foo(int i)(short.T a){ ... }
>
> does this import the module if foo is not instantiated?

I am most in favor of making the function signature either `imports` or `@imports`, or doing this:

struct Buffer(R) if (import std.range:isInputRange!R) { ... }

I also think actually being able to write `alias short = import very.long.module_name;` would be great, if only so that the contents of a module can be imported into their own user-defined namespace rather than the global scope.


December 15, 2016
On 14/12/2016 11:33 AM, Andrei Alexandrescu wrote:
> Destroy.
>
> https://github.com/dlang/DIPs/pull/51/files
>
>
> Andrei

Others have brought up similar syntax to this:

import(my.mod).Type!argsT(7)

import(Identifier).Identifier

It shouldn't be confused with string imports or the like and would be more akin to a selective import.

Pros:
 - Is an expression
 - Relatively clear and in line with string imports as an expression
Cons:
 - Another language feature to learn (but if I was designing a new language, this would totally be in it)
 - More text that goes into template constraints
 - Personally I find if I need an import like this in one constraint, I want it in a lot more places
 - Much longer lines!

   ```D
void func(T)(T x)
if (import(std.traits).isBasicType!T || import(std.traits).isFloatingPoint!T) {

}
   ```
December 14, 2016
On Wednesday, 14 December 2016 at 09:01:30 UTC, Joseph Rushton Wakeling wrote:
> On Wednesday, 14 December 2016 at 07:17:57 UTC, Jacob Carlborg wrote:
>> On 2016-12-14 03:23, Andrei Alexandrescu wrote:
>>> On 12/13/16 9:22 PM, Hatem Oraby wrote:
>>
>>>> with(import std.range)
>>>> bool equal(R1, R2) if (isInputRange!R1 && isInputRange!R2)
>>>> { ... }
>>>
>>> I considered this, then figured with is superfluous. -- Andrei
>>
>> It could allow to have a better control of the scope which the import affects, i.e.:
>>
>> with(import std.range)
>> {
>>   void foo(T) if (isInputRange!T)
>>   void bar(T) if (isInputRange!T)
>> }
>
> Trouble is, there's no real difference between doing that, vs. creating a standalone module containing `foo` and `bar` with `import std.range;` as a top-level import.


That was my impression when reading this DIP. I'm very glad to see that decoupling made its way up in the growing list of things to do, my only concern is that this syntax sounds like a workaround for giant modules.

Phobos is cited as a motivation for this enhancement. Dare I say that we have a problem of modules in phobos being too monolithic, and they should be split into more packages, like std.range and std.algorithms did ?
December 14, 2016
On 14.12.2016 10:01, Joseph Rushton Wakeling wrote:
> On Wednesday, 14 December 2016 at 07:17:57 UTC, Jacob Carlborg wrote:
>> On 2016-12-14 03:23, Andrei Alexandrescu wrote:
>>> On 12/13/16 9:22 PM, Hatem Oraby wrote:
>>
>>>> with(import std.range)
>>>> bool equal(R1, R2) if (isInputRange!R1 && isInputRange!R2)
>>>> { ... }
>>>
>>> I considered this, then figured with is superfluous. -- Andrei
>>
>> It could allow to have a better control of the scope which the import
>> affects, i.e.:
>>
>> with(import std.range)
>> {
>>   void foo(T) if (isInputRange!T)
>>   void bar(T) if (isInputRange!T)
>> }
>
> Trouble is, there's no real difference between doing that, vs. creating
> a standalone module containing `foo` and `bar` with `import std.range;`
> as a top-level import.
> ...

This point is independent of syntax.


> ...
> It's a shame, because unlike Andrei I don't feel use of `with` is in
> principle superfluous: it has a value in clarifying intention, while
> allowing the use of traditional `import something` syntax.  But
> special-casing of where `with` does and doesn't create a scope seems ...
> less good.

'static with'?
December 14, 2016
On Wednesday, 14 December 2016 at 12:01:40 UTC, Mathias Lang wrote:
> That was my impression when reading this DIP. I'm very glad to see that decoupling made its way up in the growing list of things to do, my only concern is that this syntax sounds like a workaround for giant modules.
>
> Phobos is cited as a motivation for this enhancement. Dare I say that we have a problem of modules in phobos being too monolithic, and they should be split into more packages, like std.range and std.algorithms did ?

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.

Note, `std.range` and `std.algorithm` could still be much more modularized than they currently are.
December 14, 2016
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.

finally, some DIP that addresses something i really think about almost every day.
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

Why not leave it as it is and only change the compiler to
perform inputs _within_ a function before evaluating the declaration, so that the symbols imported can be used in the declaration?

e.g.

fun(Range x) if(isInputRange!x)
{
   import std.range;
   auto a = x.front();
}

this is especially more clean if a function needs several imports and maybe some of them in the declaration but not all of them. This would otherwise split the imports to two different points, some within the (already much too long) declaration and some within the function. I consider this ugly.
December 14, 2016
14.12.2016 16:26, Dominikus Dittes Scherkl пишет:
> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>> Destroy.
>>
>> https://github.com/dlang/DIPs/pull/51/files
>
> Why not leave it as it is and only change the compiler to
> perform inputs _within_ a function before evaluating the declaration, so
> that the symbols imported can be used in the declaration?
>
> e.g.
>
> fun(Range x) if(isInputRange!x)
> {
>    import std.range;
>    auto a = x.front();
> }
>
> this is especially more clean if a function needs several imports and
> maybe some of them in the declaration but not all of them. This would
> otherwise split the imports to two different points, some within the
> (already much too long) declaration and some within the function. I
> consider this ugly.

I think this is really smart way to solve the problem.
December 14, 2016
On 2016-12-14 14:26, Dominikus Dittes Scherkl via Digitalmars-d wrote:
> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>> Destroy.
>>
>> https://github.com/dlang/DIPs/pull/51/files
>
> Why not leave it as it is and only change the compiler to
> perform inputs _within_ a function before evaluating the declaration,
> so that the symbols imported can be used in the declaration?
>
> e.g.
>
> fun(Range x) if(isInputRange!x)
> {
>    import std.range;
>    auto a = x.front();
> }
>
> this is especially more clean if a function needs several imports and maybe some of them in the declaration but not all of them. This would otherwise split the imports to two different points, some within the (already much too long) declaration and some within the function. I consider this ugly.

I like that, +1