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

What's the main goal with this proposal? Is it to introduce DCDs into the language or is it to clean up some warts of the local import pattern, i.e.:

int doSomething(T)(T t) //std.range is lazily imported but
{                       //can't be used in the signature
    import std.range;
    //...
}

struct Test(R) //Ditto
{
    import std.algorithm;
    //etc...
}

I'm assuming it's the former, or there wouldn't be any talk about introducing any new syntax. Imports would just be made completely lazy and we wouldn't have to change the language at all otherwise. So other than the fact that you can move the declaration anywhere without breaking it due to missing imports, are the advantages that DCDs provide really worth it enough to introduce yet another clause that can be put on any declaration? Especially when we have another solution (lazy imports) that does exactly what you want but excludes the DCD aspect?
December 14, 2016
On 12/14/16 4:38 PM, Timon Gehr wrote:
> On 15.12.2016 00:17, Andrej Mitrovic wrote:
>>
>> ubyte[] readSomeBytes ( )
>> {
>>     return read(1024);
>> }
>>
>> It's a non-trivial exercise for the reader to understand where the
>> `read` symbol is coming from.
>
> pragma(msg,fullyQualifiedName!read);

Or, for the IDE-addict, hover or control-click on `read`.
December 15, 2016
On Thursday, 15 December 2016 at 03:26:24 UTC, Meta wrote:
> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>> Destroy.
>>
>> https://github.com/dlang/DIPs/pull/51/files
>>
>>
>> Andrei
>
> What's the main goal with this proposal? Is it to introduce DCDs into the language or is it to clean up some warts of the local import pattern, i.e.:
>
> int doSomething(T)(T t) //std.range is lazily imported but
> {                       //can't be used in the signature
>     import std.range;
>     //...
> }
>
> struct Test(R) //Ditto
> {
>     import std.algorithm;
>     //etc...
> }
>
> I'm assuming it's the former, or there wouldn't be any talk about introducing any new syntax. Imports would just be made completely lazy and we wouldn't have to change the language at all otherwise. So other than the fact that you can move the declaration anywhere without breaking it due to missing imports, are the advantages that DCDs provide really worth it enough to introduce yet another clause that can be put on any declaration? Especially when we have another solution (lazy imports) that does exactly what you want but excludes the DCD aspect?

I think there is a case to be made to use the import in the symbol's signature, which is currently not possible. Not sure it pays for itself to add a feature in the language just for this.

The tooling case is moot IMO. The languages keeps being fubared with obtuse complexities, which makes tooling harder to write, and then this is used an an excuse to fubar it even more. This isn't leading to a good place.

Now there are some ways I see this happen leveraging the 'with' creating a "with import" construct.

void foo(R)(R r) if (isInputRange!R) with import std.range {
    // ...
}

The good thing here is that the import syntax doesn't need to be altered in any way. You can still do "with import foo.bar : buzz".

December 15, 2016
[about leaving the syntax as it is, only extend the import to include the previous (declaration) line]

On Wednesday, 14 December 2016 at 21:21:39 UTC, Jonathan M Davis wrote:
> It also doesn't work with function prototypes. With the proposed syntax, you can do
>
>     int foo(SysTime st) import(std.datetime);
>
> but if the compiler has to look into the function body to get at the import, then a prototype like this would be out of luck.

You are right. I think this is the only shortcoming.
But how does that work with imports within the function anyway?
In this case you can't even today determine the dependencies of a function from it's prototype.

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. I think we don't loose much if now we have even symbols within a .di-file which are not declared there.
The only good thing about prototypes is: they can be auto-generated. We only need to modify this generation by adding all function-local includes to the top of the .di-file.
This would also improve the usefulness of such files by having a whole list of dependencies of a library - but this has nothing to do with this change! This is necessary independently, because local imports are very common today.


December 15, 2016
On 12/14/2016 10:26 PM, Meta wrote:
> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>> Destroy.
>>
>> https://github.com/dlang/DIPs/pull/51/files
>>
>>
>> Andrei
>
> What's the main goal with this proposal?

If the document does not clarify that, please let me know of specifics. Thanks. -- Andrei
December 15, 2016
On Thursday, 15 December 2016 at 13:49:26 UTC, Andrei Alexandrescu wrote:
> On 12/14/2016 10:26 PM, Meta wrote:
>> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>>> Destroy.
>>>
>>> https://github.com/dlang/DIPs/pull/51/files
>>>
>>>
>>> Andrei
>>
>> What's the main goal with this proposal?
>
> If the document does not clarify that, please let me know of specifics. Thanks. -- Andrei

Well of course it is about DCDs, but I am talking more about the underlying motivation. The listed benefits of DCDs from the DIP:

1. Specifies dependencies at declaration level, not at module level. This allows reasoning about the dependency cost of declarations in separation instead of aggregated at module level.

2. Dependency-Carrying Declarations are easier to move around, making for simpler and faster refactorings.

3. Dependency-Carrying Declarations allow scalable template libraries... Distributing a template library in the form of Dependency-Carrying Declarations creates a scalable, pay-as-you-go setup.

It seems to me that making all imports lazy accomplishes 3, which is the real prize. 1 and 2 are nice to have, but it doesn't seem to me that the added complexity of the inline import feature is worth it when the biggest bang for our buck is not 1 or 2, but 3.

So my question is, what do you want? Is your primary goal to introduce DCDs into the language to allow for easier refactoring and having it made more clear which imports a declaration uses, or is it to make imports "pay as you go" such that a user only pays for what they actually use and it's more or less transparent to them? You argue in the DIP that DCDs give us all 3 so we don't have to choose, but as I said previously, DCDs will not give us the biggest ROI compared to the cost of the feature.
December 15, 2016
On 12/15/2016 09:31 AM, Meta wrote:
> On Thursday, 15 December 2016 at 13:49:26 UTC, Andrei Alexandrescu wrote:
>> On 12/14/2016 10:26 PM, Meta wrote:
>>> On Tuesday, 13 December 2016 at 22:33:24 UTC, Andrei Alexandrescu wrote:
>>>> Destroy.
>>>>
>>>> https://github.com/dlang/DIPs/pull/51/files
>>>>
>>>>
>>>> Andrei
>>>
>>> What's the main goal with this proposal?
>>
>> If the document does not clarify that, please let me know of
>> specifics. Thanks. -- Andrei
>
> Well of course it is about DCDs, but I am talking more about the
> underlying motivation. The listed benefits of DCDs from the DIP:
>
> 1. Specifies dependencies at declaration level, not at module level.
> This allows reasoning about the dependency cost of declarations in
> separation instead of aggregated at module level.
>
> 2. Dependency-Carrying Declarations are easier to move around, making
> for simpler and faster refactorings.
>
> 3. Dependency-Carrying Declarations allow scalable template libraries...
> Distributing a template library in the form of Dependency-Carrying
> Declarations creates a scalable, pay-as-you-go setup.
>
> It seems to me that making all imports lazy accomplishes 3, which is the
> real prize. 1 and 2 are nice to have, but it doesn't seem to me that the
> added complexity of the inline import feature is worth it when the
> biggest bang for our buck is not 1 or 2, but 3.
>
> So my question is, what do you want? Is your primary goal to introduce
> DCDs into the language to allow for easier refactoring and having it
> made more clear which imports a declaration uses, or is it to make
> imports "pay as you go" such that a user only pays for what they
> actually use and it's more or less transparent to them? You argue in the
> DIP that DCDs give us all 3 so we don't have to choose, but as I said
> previously, DCDs will not give us the biggest ROI compared to the cost
> of the feature.

Thanks for sharing your opinion. Mine (and the argument made by DIP1005) is that on balance packing dependencies together with declarations is worth the language addition. The document does specify the advantages and disadvantages of lazy imports, as follows:

===
* Full lazy `import`s. Assume all `import`s are lazy without any change in the language. That would allow an idiom by which libraries use fully qualified names everywhere, and the `import`s would be effected only when names are looked up. This would allow scalability but not the dependency-carrying aspect.
===

If that is misrepresenting things, please let me know so I can improve the DIP.


Andrei

December 15, 2016
On 12/15/2016 6:53 AM, Andrei Alexandrescu wrote:
> The document does specify the advantages and disadvantages of lazy
> imports, as follows:
>
> ===
> * Full lazy `import`s. Assume all `import`s are lazy without any change in the
> language. That would allow an idiom by which libraries use fully qualified names
> everywhere, and the `import`s would be effected only when names are looked up.
> This would allow scalability but not the dependency-carrying aspect.
> ===

That would be a massive breaking change.

December 15, 2016
On 12/14/2016 5:26 AM, Dominikus Dittes Scherkl 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();
> }

That would make it problematic to have function declarations.
December 15, 2016
On 12/15/2016 11:11 AM, Walter Bright wrote:
> On 12/15/2016 6:53 AM, Andrei Alexandrescu wrote:
>> The document does specify the advantages and disadvantages of lazy
>> imports, as follows:
>>
>> ===
>> * Full lazy `import`s. Assume all `import`s are lazy without any
>> change in the
>> language. That would allow an idiom by which libraries use fully
>> qualified names
>> everywhere, and the `import`s would be effected only when names are
>> looked up.
>> This would allow scalability but not the dependency-carrying aspect.
>> ===
>
> That would be a massive breaking change.

This may be a misunderstanding. The idiom would be opt-in so existing behavior will be preserved (albeit it won't benefit of the improvements).

Andrei

2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18