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