digitalmars.D - Name lookups in D
- Dibyendu Majumdar (9/9) Nov 15 2020 This fails:
- Paul Backus (7/16) Nov 15 2020 Yes, the fully-qualified name of a module is not in scope unless
- Steven Schveighoffer (22/39) Nov 16 2020 This isn't true. you can import a module and still use the FQN:
- Dibyendu Majumdar (4/25) Nov 16 2020 It didn't make sense to me - thank you for confirming.
- Walter Bright (2/3) Nov 20 2020 Please post to bugzilla.
- Dibyendu Majumdar (3/6) Nov 21 2020 https://issues.dlang.org/show_bug.cgi?id=21413
- kdevel (15/17) Dec 10 2020 Is this expected?
- Adam D. Ruppe (11/12) Dec 10 2020 Yes, and this is kinda why I don't like using selective imports.
- kdevel (19/24) Dec 13 2020 Just 'implemented' the following bug:
- Steven Schveighoffer (7/37) Dec 14 2020 This is expected behavior. B does not have a member named "text", and so...
- kdevel (11/40) Dec 14 2020 On Monday, 14 December 2020 at 16:21:56 UTC, Steven Schveighoffer
- Steven Schveighoffer (19/38) Dec 14 2020 I understand. There is sometimes confusion when a ufcs "member" is
- kdevel (8/15) Dec 14 2020 Until AI takes over this is clearly the case. I just wonder if
- aberba (3/21) Dec 11 2020 This behaviour makes sense to me...you've explicitly exposed only
This fails: module a.b.m; int hello() { return 42; } extern (C) void main() { assert (a.b.m.hello() == 42); } Is it supposed to?
Nov 15 2020
On Sunday, 15 November 2020 at 22:20:12 UTC, Dibyendu Majumdar wrote:This fails: module a.b.m; int hello() { return 42; } extern (C) void main() { assert (a.b.m.hello() == 42); } Is it supposed to?Yes, the fully-qualified name of a module is not in scope unless you `static import` it. There is one exception: you are always allowed to use a fully-qualified name on the right-hand side of an alias declaration. See <https://dlang.org/spec/declaration.html#alias>.
Nov 15 2020
On 11/15/20 5:38 PM, Paul Backus wrote:On Sunday, 15 November 2020 at 22:20:12 UTC, Dibyendu Majumdar wrote:This isn't true. you can import a module and still use the FQN: import std.stdio; std.stdio.writeln("bar"); // OK Note, if the module name is a single identifier, you can use it. This seems like a weird limitation based on the fact that the package isn't defined. It was introduced when the imports were fixed, but I'm not sure this was intentional. If I put the above code in, and use the wayback compiler machine at run.dlang.io: Up to 2.070.2: Success and no output 2.071.2 to 2.078.1: Success with output: onlineapp.d(7): Deprecation: package a.b is not accessible here 2.079.1 to 2.083.1: Success with output: onlineapp.d(7): Deprecation: package `a.b` is not accessible here 2.084.1 to 2.086.1: Failure with output: onlineapp.d(7): Error: package `a.b` is not accessible here Since 2.087.1: Failure with output: onlineapp.d(7): Error: undefined identifier `b` in package `a`, perhaps add `static import a.b;` IMO, you should be able to access the package you are defined in. -SteveThis fails: module a.b.m; int hello() { return 42; } extern (C) void main() { assert (a.b.m.hello() == 42); } Is it supposed to?Yes, the fully-qualified name of a module is not in scope unless you `static import` it.
Nov 16 2020
On Monday, 16 November 2020 at 13:07:21 UTC, Steven Schveighoffer wrote:On 11/15/20 5:38 PM, Paul Backus wrote:It didn't make sense to me - thank you for confirming. RegardsOn Sunday, 15 November 2020 at 22:20:12 UTC, Dibyendu Majumdar wrote:This seems like a weird limitation based on the fact that the package isn't defined. IMO, you should be able to access the package you are defined in.This fails: module a.b.m; int hello() { return 42; } extern (C) void main() { assert (a.b.m.hello() == 42); } Is it supposed to?
Nov 16 2020
On 11/16/2020 5:07 AM, Steven Schveighoffer wrote:[...]Please post to bugzilla.
Nov 20 2020
On Saturday, 21 November 2020 at 02:02:51 UTC, Walter Bright wrote:On 11/16/2020 5:07 AM, Steven Schveighoffer wrote:https://issues.dlang.org/show_bug.cgi?id=21413[...]Please post to bugzilla.
Nov 21 2020
On Monday, 16 November 2020 at 13:07:21 UTC, Steven Schveighoffer wrote:import std.stdio; std.stdio.writeln("bar"); // OKIs this expected? void main () { { import std.stdio; std.stdio.writeln ("test"); // okay } { import std.stdio : writeln; std.stdio.writeln ("test"); // Error: undefined identifier std } }
Dec 10 2020
On Friday, 11 December 2020 at 01:34:13 UTC, kdevel wrote:Is this expected?Yes, and this is kinda why I don't like using selective imports. With a normal import, the module name is the only thing actually added to the scope. Everything in that module is found by walking the import chains after not finding it locally (unless you use `static import` which means it does not add it to the chain). With a selective import, the only thing added is the specific name you did. The module name is NOT in scope and there is no chain established. Selective imports are more like making an alias than other imports.
Dec 10 2020
On Friday, 11 December 2020 at 01:38:44 UTC, Adam D. Ruppe wrote: [...]With a normal import, the module name is the only thing actually added to the scope. Everything in that module is found by walking the import chains after not finding it locally (unless you use `static import` which means it does not add it to the chain).Just 'implemented' the following bug: ~~~ import std.conv; class B { } class D : B { string text; } void main () { B b = new D; string s = b.text; } ~~~ Due to UFCS std.conv.text grabs the object. Only a `static import` or a selective import would reveal the problem during compile time.
Dec 13 2020
On 12/13/20 4:54 PM, kdevel wrote:On Friday, 11 December 2020 at 01:38:44 UTC, Adam D. Ruppe wrote: [...]This is expected behavior. B does not have a member named "text", and so it looks for a UFCS function to call and finds one. Note that a static import means you have to use the FQN to call text (but text is perfectly fine via UFCS). However, a selective import would still call text as expected. -SteveWith a normal import, the module name is the only thing actually added to the scope. Everything in that module is found by walking the import chains after not finding it locally (unless you use `static import` which means it does not add it to the chain).Just 'implemented' the following bug: ~~~ import std.conv; class B { } class D : B { string text; } void main () { B b = new D; string s = b.text; } ~~~ Due to UFCS std.conv.text grabs the object. Only a `static import` or a selective import would reveal the problem during compile time.
Dec 14 2020
On Monday, 14 December 2020 at 16:21:56 UTC, Steven Schveighoffer wrote: [...]Sure. In the original code the missing downcast was not that easily discernible.Just 'implemented' the following bug: ~~~ import std.conv; class B { } class D : B { string text; } void main () { B b = new D; string s = b.text; } ~~~ Due to UFCS std.conv.text grabs the object. Only a `static import` or a selective import would reveal the problem during compile time.This is expected behavior.B does not have a member named "text", and so it looks for a UFCS function to call and finds one. Note that a static import means you have to use the FQN to call text (but text is perfectly fine via UFCS). However, a selective import would still call text as expected.The original code accessed only std.conv.to. A selective import of `to` would have complained and helped to spot the error: q.d(13): Error: no property text for type q.B, perhaps import std.conv; is needed? BTW: Most of the time dmd's guess is accurate.
Dec 14 2020
On 12/14/20 12:59 PM, kdevel wrote:On Monday, 14 December 2020 at 16:21:56 UTC, Steven Schveighoffer wrote:I understand. There is sometimes confusion when a ufcs "member" is found. I've seen a lot of weird things like this. But the compiler can only tell what you want from the code you write, it can't look at the intentions behind it. Especially when you make a mistake. I've had countless times where I reach for something.to!somethingelse and I forgot to import std.conv, but I've happened to import std.datetime (which has a similar ufcs `to` function). And the error message is always confusing. I don't think this is fixable. You just have to live with it. It's unfortunate that it compiles, and doesn't give an error. "Best effort" functions like text that *always* compile can be hard to diagnose when you call them by accident.This is expected behavior.Sure. In the original code the missing downcast was not that easily discernible.OK, I thought you meant a selective import of std.conv.text.B does not have a member named "text", and so it looks for a UFCS function to call and finds one. Note that a static import means you have to use the FQN to call text (but text is perfectly fine via UFCS). However, a selective import would still call text as expected.The original code accessed only std.conv.to. A selective import of `to` would have complained and helped to spot the error:q.d(13): Error: no property text for type q.B, perhaps import std.conv; is needed? BTW: Most of the time dmd's guess is accurate.Those suggestions are hard-coded into the compiler, and I sometimes wish they were more comprehensive. But I don't see any future in which the compiler is going to suggest "maybe you meant to downcast to type D". It just can't see what you were thinking. -Steve
Dec 14 2020
On Monday, 14 December 2020 at 18:54:58 UTC, Steven Schveighoffer wrote:But the compiler can only tell what you want from the code you write, it can't look at the intentions behind it. Especially when you make a mistake.Until AI takes over this is clearly the case. I just wonder if selective imports are worth the additional typing. They obviously prevent the namespace pollution with greedy function templates like text.I've had countless times where I reach for something.to!somethingelse and I forgot to import std.conv, but I've happened to import std.datetime (which has a similar ufcs `to` function).Thanks for this warning ;-)
Dec 14 2020
On Friday, 11 December 2020 at 01:34:13 UTC, kdevel wrote:On Monday, 16 November 2020 at 13:07:21 UTC, Steven Schveighoffer wrote:This behaviour makes sense to me...you've explicitly exposed only that symbol.import std.stdio; std.stdio.writeln("bar"); // OKIs this expected? void main () { { import std.stdio; std.stdio.writeln ("test"); // okay } { import std.stdio : writeln; std.stdio.writeln ("test"); // Error: undefined identifier std } }
Dec 11 2020