filtered imports

Jonathan Marler johnnymarler at gmail.com
Thu Sep 13 16:23:21 UTC 2018


On Thursday, 13 September 2018 at 11:58:40 UTC, rikki cattermole 
wrote:
> On 13/09/2018 11:54 PM, Jonathan Marler wrote:
>> "Selective imports" limit the symbols imported from a module 
>> by providing a list of all the symbols to include:
>> 
>> import std.stdio : writeln, writefln;
>> 
>> The complement of this would be a "Filtered import", meaning, 
>> import all the symbols except the ones in the provided list. I 
>> imagine the syntax would look something like:
>> 
>> import std.stdio ~ writeln, writefln;
>> 
>> 
>> To provide a use case for this, say you have a module that 
>> uses a fair amount of symbols from `std.file` but you want to 
>> make sure that all calls to `chdir` are logged.  Using a 
>> filtered import would allow you to exclude `chdir` from being 
>> available globally so you could create a wrapper that all code 
>> is forced to go through.
>> 
>> import std.stdio;
>> import std.file ~ chdir;
>> 
>> void chdir(R)(R path)
>> {
>>      writefln("chdir '%s'", path);
>>      from!"std.file".chdir(path);
>> }
>> 
>> It's an interesting variation on D's current repertoire of 
>> import semantics. Possibly worth consideration as an addition 
>> to the language.
>> 
>> Grammar Changes:
>> -----------------------------------------------------
>> ImportBindings:                    (existing rule)
>>      Import : ImportBindList        (existing rule)
>>      Import ~ ImportExcludeList     (new rule)
>> 
>> ImportExcludeList:                 (new rule)
>>      Identifier, ImportExcludeList  (new rule)
>> -----------------------------------------------------
>
> import std.stdio;
> import std.file;
>
> void chdir(R)(R path) {
> 	writeln("changing dir to ", path);
>     std.file.chdir(path);
> }
>
>
> void main()
> {
>     chdir("/tmp");
> }

Ah, I see.  Poor example on my part.  I didn't realize that local 
symbols ALWAYS take precedence over imported ones.  I thought 
that the compiler would "fall back" to an imported symbol if the 
local one didn't work, but it appears that's not the case.

Some more thoughts. Selective imports and filtered imports are 
complements to each other, you can still have all the 
functionality you want with just one of them, but one will 
usually fit better in each case.  Namely, if you want a small 
number of symbols from a module, selective imports are the way to 
go, but if you want to include all except a small number of 
symbols from a module, then filtered imports would be nice.

So a use case would only work better with filtered imports if it 
was a scenario where we want to include all except a few symbols 
from an imported module.  Given that, the next question is, in 
what cases do we want to prevent symbols from being imported from 
a module?  The immediate example is to resolve symbol conflicts.

// assume both modules provide the symbol baz
import foo;
import bar;

baz(); // symbol conflict

// change `import foo;` to `import foo ~ baz;`

And to reiterate, we could also resolve this conflict with 
selective imports (or even static or named imports in this case) 
so you would only consider this useful in cases where we are 
using a good amount of symbols from foo as to make it cumbersome 
to have to selectively import all the symbols or qualify them all 
in source, i.e.

import foo : a, b, c, d, e, f, g, h, i, j, k, ...;
// vs
import foo ~ baz;

Anyway, those are my thoughts on it.  Again I think it's 
something to consider. I'm not sure if it has enough uses to 
justify an addition to the language (that bar is pretty high 
now-a-days). So it's up to us D programmers to think about 
whether these semantics would work well in our own projects.



More information about the Digitalmars-d mailing list