May 18, 2013 Re: [dmd-beta] dmd 2.063 beta 3 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rainer Schuetze | On Saturday, May 18, 2013 22:30:30 Rainer Schuetze wrote: > I think the new behaviour is consistent with symbol lookup rules, but I'm not so sure about import rules. The actual case that triggered the issue was with the base class in a different file. Usually non-public imports in a module don't have an effect on another module that imports the module. In this case it has. I would argue that the import would need to be _protected_ in order for derived classes to be affected by it if they're not in the same file. Having a private import affect something outside of the file that it's in violates the access rules. Technically, I don't think that the idea of a protected import exists at the moment, but I think that it's going to have to be added if we're going to have imports follow the symbol lookup rules rather than simply having them restrict themselves to the scope that they're in lexically, which is honestly how I thought that they worked - the fact that they'd have any impact on derived types surprised me considerably. But also, if you start following symbol lookup rules for whether local imports are visible or not, then you'd have to worry about public imports in a class affecting things in weird ways too. It seems _much_ cleaner to me to just restrict local imports to lexical scope, and I don't see how that would be inconsistent or surprising given that they're import statements, not symbols. > Actually, I can live with it, but I cannot see a reasonable use case for the new behaviour. My rule of thumb would be to not use local import in classes. Otherwise all imported symbols are treated as static members with respect to lookup, hiding global functions or variables in derived classes. Yeah. if importing at class scope affects anything outside of that lexical scope (including derived classes), I would then strongly argue that using class-level imports is bad practice and that if you need the import that much, it should be a top-level import. It's just going to cause function hijacking problems to have class-level imports. Function-level imports at least encapsulate things nicely. The class-level ones seem to be doing the opposite. - Jonathan M Davis _______________________________________________ dmd-beta mailing list dmd-beta@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-beta |
May 18, 2013 Re: [dmd-beta] dmd 2.063 beta 3 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sat, 18 May 2013 15:20:58 -0700 Jonathan M Davis <jmdavisProg@gmx.com> wrote: > On Saturday, May 18, 2013 22:30:30 Rainer Schuetze wrote: > > I think the new behaviour is consistent with symbol lookup rules, but I'm not so sure about import rules. The actual case that triggered the issue was with the base class in a different file. Usually non-public imports in a module don't have an effect on another module that imports the module. In this case it has. > > I would argue that the import would need to be _protected_ in order for derived classes to be affected by it if they're not in the same file. Having a private import affect something outside of the file that it's in violates the access rules. > I think that's a reasonable way of looking at it. Private imports inside a class should naturally *be* private. > > It > seems _much_ cleaner to me to just restrict local imports to lexical > scope, and I don't see how that would be inconsistent or surprising > given that they're import statements, not symbols. > I also have always thought of imports as being a "lexical scope" thing. (FWIW). > > I would then strongly > argue that using class-level imports is bad practice and that if you > need the import that much, it should be a top-level import. I think that would be a common sentiment. At least, I know I'd be doing the same. *Even without* the risk of function hijacking, it just seems very messy: Private imports should never have any affect outside the current module (Or for that matter, the current lexical scope.) Like you, I can live with it as well (provided there's no chance of hijacking), but the current 2.063 beta's behavior definitely does not win on the "simplicity" and "consistency" fronts. _______________________________________________ dmd-beta mailing list dmd-beta@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-beta |
May 19, 2013 Re: [dmd-beta] dmd 2.063 beta 3 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic Attachments:
| This behavior is intended change.
From 2.063, UFCS name lookup finds *most inner* imported name.
module test;
void map(alias func, T)(T){} // dummy
void main() {
import std.algorithm;
auto r = [1,2,3].map!(a=>a*2); // hit std.algorithm.map instead of
test.map
}
As already Walter says, the precedence is now changed as same as normal name lookup rule.
Kenji Hara
2013/5/19 Andrej Mitrovic <andrej.mitrovich@gmail.com>
> On 5/18/13, Walter Bright <walter@digitalmars.com> wrote:
> > I don't agree. A base class's scope must override the top level module scope.
> >
> > Also, a base class can always override what a derived class does. This is not hijacking.
>
> Don't you see that this change in behavior is going to surprise a lot of people? It's intuitive to me that this is going to cause trouble down the road. A base class could be in another file, in another library, and if the library writer decides to introduce a scoped import, suddenly the user's code might end up calling the wrong function (if the type signatures are the same the user will have *no idea* what happened). This is the definition of function hijacking.
>
> If it is a feature, it is not properly documented, and I can't tell which pull request changed the behavior so I don't know whether to put it in the changelog or not.
>
> Kenji, maybe you know?
> _______________________________________________
> dmd-beta mailing list
> dmd-beta@puremagic.com
> http://lists.puremagic.com/mailman/listinfo/dmd-beta
>
|
May 19, 2013 Re: [dmd-beta] dmd 2.063 beta 3 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rainer Schuetze Attachments:
| 2013/5/19 Rainer Schuetze <r.sagitario@gmx.de>
> On 18.05.2013 21:51, Walter Bright wrote:
>>
>> I agree that it is changing behavior, and should be properly documented. However, I also believe it is correct behavior and fixed a bug.
>>
>> It's *always* true that when you change a base class, you affect the derived classes.
>>
>
> I think the new behaviour is consistent with symbol lookup rules, but I'm not so sure about import rules. The actual case that triggered the issue was with the base class in a different file. Usually non-public imports in a module don't have an effect on another module that imports the module. In this case it has.
>
> Actually, I can live with it, but I cannot see a reasonable use case for the new behaviour. My rule of thumb would be to not use local import in classes. Otherwise all imported symbols are treated as static members with respect to lookup, hiding global functions or variables in derived classes.
Hmm, in module level, import declaration will add name lookup path _in private_.
module a;
import std.algorithm; // default is private
module b;
import a;
void main() {
[1,2,3].map!(a=>a); // Error: no property 'map' for type 'int[]'
}
But with current master, import declaration in base class member adds name
lookup path _in public_.
I had not recognize this behavior.
class A {
import std.algorithm; // default is public!?
}
class B : A {
void test() {
auto r = [1,2,3].map!(a=>a); // succeeds to compile
}
}
void main() {
auto r = B.map!(a=>a)([1,2,3]); // also succeeds to compile
}
I think this is inconsistent, and class case should be fixed.
Kenji Hara
|
May 19, 2013 Re: [dmd-beta] dmd 2.063 beta 3 | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kenji Hara | On 5/19/13, Kenji Hara <k.hara.pg@gmail.com> wrote: > This behavior is intended change. > > From 2.063, UFCS name lookup finds *most inner* imported name. > > module test; > void map(alias func, T)(T){} // dummy > void main() { > import std.algorithm; > auto r = [1,2,3].map!(a=>a*2); // hit std.algorithm.map instead of > test.map > } Right, that's a cool feature. I'll add this specific feature to the changelog, and await what to do about class imports. _______________________________________________ dmd-beta mailing list dmd-beta@puremagic.com http://lists.puremagic.com/mailman/listinfo/dmd-beta |
Copyright © 1999-2021 by the D Language Foundation