Bug 3819 – [module system] Tiding up the imports

Status
RESOLVED
Resolution
WONTFIX
Severity
enhancement
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
Windows
Creation time
2010-02-18T10:24:00Z
Last change time
2015-06-09T01:27:40Z
Assigned to
nobody
Creator
bearophile_hugs

Comments

Comment #0 by bearophile_hugs — 2010-02-18T10:24:06Z
import std.stdio; void main() { std.stdio.writefn(1); writefln(2); // (A) } This program has to raise a compilation error at the line (A), because this line: import std.stdio; Has to import only the 'std.stdio' name in the current namespace. To import (discouraged practice) all names from a module a specific syntax may be invented, like: import std.stdio.*; void main() { writefln(1); std.stdio.writefn(2); // (B) } That imports all the names but not the module name itself, so the line (B) has to raise an error.
Comment #1 by shro8822 — 2010-02-18T11:59:21Z
I think this would be bad idea and vote that it be closed. --- Rational: There already exist way to use import where the fully qualified name is still needed (IIRC static imports) so that covers the one case. There already exists a way to use import to a selected subset of symbols from a module. The most common case is the "import everything" case. With the modification, in the normal case, it becomes impossible to, in the same module, use fully qualified names and to not use them. --- I don't see any advantage to it (either in functionality, consistency, conciseness or anything else I care about). Unless I'm missing something, I think the proposal would detract from the language.
Comment #2 by bearophile_hugs — 2010-02-18T12:20:48Z
Answer to BCS: I think this is the most important bug I've filed among the first 15 ones. The standard way to import must be the one that's tidy, that is not importing all names randomly into the namespace. If you have functions, they can use global values coming from a module, and you don't know from what module they come from. If you really really want to import all the names in a namespece I've shown you a very easy syntax to do that: import std.stdio.*; It's just 2 chars longer than the current syntax you use: import std.stdio; So you don't wear your fingers out if you want to use that all times. >There already exist way to use import where the fully qualified name is still needed (IIRC static imports) so that covers the one case.< That's the wrong default. >With the modification, in the normal case, it becomes impossible to, in the same module, use fully qualified names and to not use them.< And this (if I understand you correctly) is good. Because newbies (and all people coming from Python) people will understand this tidier behaviour faster.
Comment #3 by bearophile_hugs — 2010-02-23T18:33:22Z
I can show you some funny examples, this is a reduced bug that comes from real code (not written by me) (this codes currently compiles, but it's not good): import std.c.stdio; enum int BUFFSIZE = 2048; long[BUFSIZ] foo; void main() {} The basics of systems theory tells that to improve the reliability of an engineering system you have to put discipline in how its subsystems interact to each other. Reducing unwanted interactions among subsytems improves reliability a lot. D module system is not tidy, there can be unwanted interactions that lead to bugs. The module system of Python doesn't share this vulnerability, it's designed in a logically tidy way. Overload sets introduced in D can't fix the situation, they are just a patch on a situation on a module system design that is logically unsound.
Comment #4 by shro8822 — 2010-02-23T20:32:15Z
I don't think that shows as a problem in the import system. While your proposal would fix the problem in that case, there are plenty of other versions of the same bug that wouldn't get fixed. For this case, it would be like expecting Toyota drivers to fix there sticky gas pedals by driving around with flat tires. Yes it would fix the problem but it's not a good idea.
Comment #5 by bearophile_hugs — 2010-02-24T02:51:59Z
Maybe I was not clear enough: in a complex system if you want to avoid many bugs you have to reduce the interface area between subsystems, to reduce the number of unwanted interactions between them. When possible you want to know the interactions among them, to allow only the useful ones. So it's good to have a way to list in explicit way what interactions they share. Importing all names randomly from a module as default behaviour leads to a mess.
Comment #6 by shro8822 — 2010-02-24T13:17:01Z
(In reply to comment #5) > Maybe I was not clear enough: No you were clear enough. I just don't think that your proposal is the correct solution (and I'm not sure that the problem even needs to be solved). Clearly, there are better and worse solutions to the problem (if dmd aborts for all code it would reject all bugs) and I think that your solution is slightly worse than doing nothing. I think that because it will get in the way of the programmer and I expect that ,in practice, it will not solve the problem because people will just use "import foo.*;" by default. > So it's good to > have a way to list in explicit way what interactions they share. We have that right now. > Importing all names randomly from a module as default behaviour leads to a > mess. If importing all names from a module imports *random* names, than the problem is not the import system, but what is in the module. I'll maintain that in a well designed library, if you need one thing from a module, you will need many/most of the things in it.
Comment #7 by bearophile_hugs — 2010-02-24T14:36:06Z
>I think that because it will get in the way of the programmer and I expect that ,in practice, it will not solve the problem because people will just use "import foo.*;" by default.< In Python that's doesn't happen, people usually import just the module name, or some names from the module. The import all is discouraged. And when people what to use the unqualified import syntax, adding two chars ".*" is not going to cost them much. >We have that right now.< We don't have it, there's a whole page about mitigating this problem: http://www.digitalmars.com/d/2.0/hijack.html And Overload Sets have being introduced as a patch on this problem. >If importing all names from a module imports *random* names, than the problem is not the import system, but what is in the module.< By "random names" I didn't mean they are truly random, I mean that you don't know what you are importing. >I'll maintain that in a well designed library, if you need one thing from a module, you will need many/most of the things in it.< In Phobos there are modules with 20-30 names of functions and other stuff. User defined modules can have even more. D is not Java, you are supposed to put related classes inside a single module. So about 100% of the times I don't use all things that are present in those modules.
Comment #8 by dsimcha — 2010-02-24T14:47:47Z
I think the point everyone is missing here is that, unlike most other languages, D doesn't allow hijacking, **period**. The best practices that apply to languages that allow hijacking simply don't apply to D. While in other languages it may lead to subtle bugs and be considered sloppy programming, in D I see nothing wrong with just saying "ah fsck it I want to save a little typing" and import 5,000 names into the current namespace, because it's **not going to lead to any subtle bugs**. It will either compile and work fine or it won't compile and will tell you where the ambiguity is. This is why I really, really, really, **really** wish there was a std.all. (In reply to comment #7) > >I think that because it will get in the way of the programmer and I expect that ,in practice, it will not solve the problem because people will just use "import foo.*;" by default.< > > In Python that's doesn't happen, people usually import just the module name, or > some names from the module. The import all is discouraged. > And when people what to use the unqualified import syntax, adding two chars > ".*" is not going to cost them much. > > > >We have that right now.< > > We don't have it, there's a whole page about mitigating this problem: > http://www.digitalmars.com/d/2.0/hijack.html > And Overload Sets have being introduced as a patch on this problem. > > > >If importing all names from a module imports *random* names, than the problem > is not the import system, but what is in the module.< > > By "random names" I didn't mean they are truly random, I mean that you don't > know what you are importing. > > > >I'll maintain that in a well designed library, if you need one thing from a module, you will need many/most of the things in it.< > > In Phobos there are modules with 20-30 names of functions and other stuff. User > defined modules can have even more. D is not Java, you are supposed to put > related classes inside a single module. So about 100% of the times I don't use > all things that are present in those modules.
Comment #9 by shro8822 — 2010-02-24T16:30:08Z
(In reply to comment #7) >>I think that because it will get in the way of the programmer and >> I expect that ,in practice, it will not solve the problem because >> people will just use "import foo.*;" by default. > > In Python that's doesn't happen, people usually import just the module name, > or some names from the module. The import all is discouraged. I don't have any solid evidence, but I strongly suspect that the above would not happen for D. It seems to me that the cost benefit balance falls in favor of just importing everything. I suspect that it's similar to how in dynamic languages there is a much stronger argument for TDD because, IIRC, python is a dynamic language and D is not. > And when people what to use the unqualified import syntax, adding two chars > ".*" is not going to cost them much. Not my point. In fact the ease of adding it supports my point. >>We have that right now. > > We don't have it, there's a whole page about mitigating this problem: > http://www.digitalmars.com/d/2.0/hijack.html > And Overload Sets have being introduced as a patch on this problem. > Let me be more precise: we have selective imports right now. > >> If importing all names from a module imports *random* names, than >> the problem is not the import system, but what is in the module. > > By "random names" I didn't mean they are truly random, I mean that you don't > know what you are importing. > I still maintain my point, if you needs something out of a module than importing every name in a module shouldn't import random names (using your definition) unless the module is poorly designed. > >>I'll maintain that in a well designed library, if you need one thing from a >> module, you will need many/most of the things in it. > > In Phobos there are modules with 20-30 names of functions and other stuff. > User defined modules can have even more. 20-30 names? Is it that low? I thought you were talking about hundreds of names. Now I'm not even sure why you are bothering. > D is not Java, you are supposed to > put related classes inside a single module. So about 100% of the times I > don't use all things that are present in those modules. Most of the time using Phobos, I want to have most of or none of a module available (even if I don't use some of it).
Comment #10 by code — 2012-02-14T05:46:10Z
Too late, too much code.
Comment #11 by bugzilla — 2012-02-14T12:16:57Z
I agree. D has excellent support for anti-hijacking, which I feel serves the purpose well. As for this case: import std.c.stdio; enum int BUFFSIZE = 2048; long[BUFSIZ] foo; void main() {} That's a general problem with typos, not specifically with imports. I don't see any hope for any computer language to fix this. All computer languages rely on different names being completely distinct, even if they differ by only one character. There's no solution for it. You could perhaps write a lint program that looked for names in scope that differed by only one character in the middle of the identifier and issued warnings, but I can't see that as being part of the language. In any case, 1. mucking with how imports work is the wrong solution to typos 2. this would break every D program in existence Wontfix.