digitalmars.D - filtered imports
- Jonathan Marler (31/31) Sep 13 2018 "Selective imports" limit the symbols imported from a module by
- rikki cattermole (11/50) Sep 13 2018 import std.stdio;
- Neia Neutuladh (7/13) Sep 13 2018 And if you don't want to write long qualified import names, just
- Jonathan Marler (37/89) Sep 13 2018 Ah, I see. Poor example on my part. I didn't realize that local
- Vladimir Panteleev (14/15) Sep 13 2018 I've ran into this a few times:
- jmh530 (3/8) Sep 13 2018 That's a nice trick!
- Jonathan Marler (4/19) Sep 13 2018 That's pretty slick. I guess I'm all out of use cases then. I
"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) -----------------------------------------------------
Sep 13 2018
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"); }
Sep 13 2018
On Thursday, 13 September 2018 at 11:58:40 UTC, rikki cattermole wrote:import std.stdio; import std.file; void chdir(R)(R path) { writeln("changing dir to ", path); std.file.chdir(path); }And if you don't want to write long qualified import names, just rename it: import sf = std.file; sf.chdir("foo"); chdir("foo");
Sep 13 2018
On Thursday, 13 September 2018 at 11:58:40 UTC, rikki cattermole wrote:On 13/09/2018 11:54 PM, Jonathan Marler wrote: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."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"); }
Sep 13 2018
On Thursday, 13 September 2018 at 16:23:21 UTC, Jonathan Marler wrote:The immediate example is to resolve symbol conflicts.I've ran into this a few times: import std.stdio; import std.file; void main(string[] args) { auto text = readText(args[1]); write("The contents of the file is: ", text); } However, it is solved with an alias: alias write = std.stdio.write; (or using selective imports or fully-qualified identifiers for either module of course).
Sep 13 2018
On Thursday, 13 September 2018 at 17:54:03 UTC, Vladimir Panteleev wrote:[snip] However, it is solved with an alias: alias write = std.stdio.write; (or using selective imports or fully-qualified identifiers for either module of course).That's a nice trick!
Sep 13 2018
On Thursday, 13 September 2018 at 17:54:03 UTC, Vladimir Panteleev wrote:On Thursday, 13 September 2018 at 16:23:21 UTC, Jonathan Marler wrote:That's pretty slick. I guess I'm all out of use cases then. I did learn a new trick though :)The immediate example is to resolve symbol conflicts.I've ran into this a few times: import std.stdio; import std.file; void main(string[] args) { auto text = readText(args[1]); write("The contents of the file is: ", text); } However, it is solved with an alias: alias write = std.stdio.write; (or using selective imports or fully-qualified identifiers for either module of course).
Sep 13 2018