3 ms·
It seems to me one of the worst problems explicit imports help solve is forward compatibility of code with respect to the modules and the standard library. And
by jraph 5y ago
It seems to me one of the worst problems explicit imports help solve is forward compatibility of code with respect to the modules and the standard library. And this problem seems worth solving.
If you require user code to explicitly import functions from modules, you can safely add a function to a module or to the standard library without risking to break someone's code.
Importing the module is not sufficient: really, the functions (or any other imported objects) themselves need to be named. (or, the function needs to be qualified with the name of the module; actually, Python seems to do a reasonable job at this)
As a text editor user, it also helps me discover where such or such function is defined. The alternatives are:
- using an IDE that will consume a lot of CPU cycles and memory to resolve the functions
- grepping, with the risk of finding another function with the same name so I would also need to check if the type signature matches.
I'll gladly spend the time to write my import statement to solve all these issues. It does not bother me. It's not where I spend my time when I program.
It's okay if IDEs hide those import statements or produce them automatically (and it does not mean it's the wrong approach). The point is: code should not break (compilation or runtime) if a module or the standard library evolves and add stuff that could have otherwise clashed. The work being done automatically and the result being hidden by default does not mean it can be done the same way in the future and therefore should be avoided; that's because the environment can change, so it has to be done at the time the code is written, manually or automatically.
- travisd 5y agoInterestingly, I suspect Facebook employs the largest auto-loaded codebase in the world and I suspect this is made easier by the fact that everything is controlled under one roof. There is some namespacing (à la PHP namespaces) for standard library stuff, but most naming just takes the form <TeamName><NormalClassName> to avoid any conflicts.
- phoe-krk 5y agoCommon Lisp hacker here, with a real-world case of this: > It seems to me one of the worst problems explicit imports help solve is forward compatibility of code with respect to the modules and the standard library. And this problem seems worth solving. This is exactly the problem in a lot of legacy Common Lisp code in which packages :USE other packages. :USE means that all symbols from package A become accessible in package B. It also means that a widely :USEd package cannot add a new symbol without possibly breaking a lot of code that depends on it. In the optimistic case, nothing will happen; in the realistic case, you will get package conflicts if the symbol that is newly exported from A is also exported by another package C that is :USEd; in the worst case, the :USEing package successfully grabs that symbol overwrites its meaning with something else, which means that the functions or variables or classes or whatever else named by that symbol suddenly become something else and everyone else that :USEs package A suddenly needs to deal with an overwritten definition, and chaos ensues. One CL solution is to never :USE other people's packages and explicitly import single symbols; another solution is to use local nicknames which means that it's possible to "import org.random.foo as f" and refer to symbols via F:BAR.
- kazinator 5y ago> USE means that all symbols from package A become accessible in package B. All exported symbols from package A become accessible in package B. Also, symbols that package A itself uses from another package are not visible by using package A. You can create an intermediate package to isolate yourself: (defpackage foo-2019 (:use foo) (:export this that other thing)) Now you can ":use foo-2019" and get only those four symbols from foo. The :export actually imports those symbols into foo-2019, and then marks them for export. The :use foo makes all of foo's exported symbols symbols visible in foo-2019, and this allows the :export clause to refer to them.
- phoe-krk 5y agoRight, sorry - should have written, "all symbols exported from package A become accessilble in package B".
- thaumasiotes 5y ago> Importing the module is not sufficient: really, the functions (or any other imported objects) themselves need to be named. (or, the function needs to be qualified with the name of the module; actually, Python seems to do a reasonable job at this) Well, in Python you can do it well or poorly at your own discretion. Good: from module import fun ... fun() import module as m ... m.fun() Bad: from module import * ... fun()
- jraph 5y agoIndeed, import * should be avoided.
- em-bee 5y agoas i wrote in my other comment here: https://news.ycombinator.com/item?id=30268565 https://news.ycombinator.com/item?id=30268565 if modules are always addressed by their full path then adding new functions to a module is not a problem.
- jraph 5y agoSure. However, this makes for verbose and wide code, which is not necessarily desirable. It may (arguably) reduce readability. Your brain has to parse and check that each full path is the same, which increase the effort you need to make to properly read the code. I guess it is a matter of taste.
- em-bee 5y agowell, i guess i haven't seen much code where modules were used so frequently that the verbosity became an issue. in the few cases where you have one or two verbose function calls that are called many times you can always assign them to some short variable and solve the problem that way. i don't see the path checking issue. module paths form an easily recognizable pattern that doesn't increase my effort to read the code. you'd have to have some very similar named modules for that to be a problem.
- alaaalawi 5y agoAlso check Oberon the language and its module system. and was used to create Oberon the system. all procedures/functions are called like this: M.F (Module name - it can be abbreviated but not removed, and F procedure/functions.)