www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - lazy import, an alternative to DIP 1005

reply Jonathan Marler <johnnymarler gmail.com> writes:
DIP 1005 proposes a solution to prevent loading in modules that 
don't need to be loaded, thereby decreasing the overall compile 
time. Here's an example taken from the DIP:

with (import std.stdio) void process(File input) ;
with (import std.range) struct Buffered(Range) if 
(isInputRange!Range)
{
     ...
}

I've come up with another way to solve this problem by using a 
modified version of import, call it a "lazy import".  A lazy 
import works like a "static import" in that all references to it 
must be fully qualified, but it also delays loading the module 
until absolutely necessary.  Since all the symbols will be fully 
qualified the semantic analyzer will know when it's time to load 
the module. The previous example could be done like this:

lazy import std.stdio;
lazy import std.range;

void process(std.stdio.File input) ;
struct Buffered(Range) if (std.range.isInputRange!Range)
{
     ...
}

Note that instead of introducing the "lazy" modifier here, we 
could just modify static imports to be lazy which would mean no 
new syntax and every benefits from the feature without changing 
their code, that is, if they are using static imports :)

aliasing can also be helpful in this instance

alias stdio = std.stdio;
alias range = std.range;

void process(stdio.File input) ;
struct Buffered(Range) if (range.isInputRange!Range)
{
     ...
}

Note that this usage is only meant for large library code like 
phobos, where this type of optimization can have a big 
performance impact when importing modules from the library.  You 
wouldn't use the verbose syntax from either of the examples in a 
normal application.

What do you think, better or worse than DIP 1005?  I think it's 
simpler, but not sure if it's better overall.
Sep 15 2017
next sibling parent Jonathan Marler <johnnymarler gmail.com> writes:
On Friday, 15 September 2017 at 14:45:01 UTC, Jonathan Marler 
wrote:
 ...
Wanted to add that I believe we could also make "selective imports" lazy, either be default or possibly by adding a modifier like "lazy" if non-lazy imports are still useful. lazy import std.stdio : File; lazy import std.range : isInputRange; void process(File input) ; struct Buffered(Range) if (isInputRange!Range) { ... } It works because the semantic analyzer knows that the "File" symbol is referring to something in module std.stdio, so it can delay importing std.stdio until it needs to resolve the File symbol. If this was implemented, not sure if there is a benefit to turning lazy imports on/off, if not, then we could just forgo the new "lazy" modifier and just make all "qualified imports" lazy. Note this can't work with normal imports because in that case you need to import the module just to know what symbols it contains. This idea only works with "static imports" and "selective imports".
Sep 15 2017
prev sibling next sibling parent reply jmh530 <john.michael.hall gmail.com> writes:
On Friday, 15 September 2017 at 14:45:01 UTC, Jonathan Marler 
wrote:
 Note that instead of introducing the "lazy" modifier here, we 
 could just modify static imports to be lazy which would mean no 
 new syntax and every benefits from the feature without changing 
 their code, that is, if they are using static imports :)
That DIP already has a section titled "Alternative: Lazy Imports" that discusses this idea, also in context of static imports.
Sep 15 2017
parent Jonathan Marler <johnnymarler gmail.com> writes:
On Friday, 15 September 2017 at 15:45:56 UTC, jmh530 wrote:
 On Friday, 15 September 2017 at 14:45:01 UTC, Jonathan Marler 
 wrote:
 Note that instead of introducing the "lazy" modifier here, we 
 could just modify static imports to be lazy which would mean 
 no new syntax and every benefits from the feature without 
 changing their code, that is, if they are using static imports 
 :)
That DIP already has a section titled "Alternative: Lazy Imports" that discusses this idea, also in context of static imports.
Lol, that's exactly what I was suggesting :) Thanks for pointing that out.
Sep 15 2017
prev sibling parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, September 15, 2017 14:45:01 Jonathan Marler via Digitalmars-d 
wrote:
 What do you think, better or worse than DIP 1005?  I think it's
 simpler, but not sure if it's better overall.
Walter has talked before about wanting to make _all_ imports lazy, which should obviate the need for DIP 1005 entirely - at least as far as compilation speed goes. The benefit that you do not get is the documenting of dependencies that DIP 1005 gives you. But personally, I don't think that that's even vaguely worth complicating function signatures even further - especially if we have lazy imports. I would _much_ rather have lazy imports implemented rather than DIP 1005. Function signatures arguably have too much on them in D as it is. - Jonathan M Davis
Sep 17 2017