digitalmars.D.learn - coding practices: include whole module or only the needed function
- AsmMan (17/17) Oct 06 2014 Which practice do you use: if you need only one or two functions
- bearophile (5/6) Oct 06 2014 I use this in D to know what I have imported and where is was
- H. S. Teoh via Digitalmars-d-learn (71/96) Oct 06 2014 Agreed. Recently, I realized more and more that local imports are the
- ketmar via Digitalmars-d-learn (11/22) Oct 06 2014 On Mon, 06 Oct 2014 21:24:54 +0000
- Gary Willoughby (3/21) Oct 07 2014 Be mindful of this classic bug:
- monarch_dodra (4/33) Oct 07 2014 Yeah. In the current state of affairs, please NEVER do selective
- bachmeier (2/3) Oct 07 2014 Can you expand or provide a link to the issue?
- ketmar via Digitalmars-d-learn (6/9) Oct 07 2014 On Tue, 07 Oct 2014 17:24:40 +0000
- monarch_dodra (8/19) Oct 07 2014 That's only relative to having selective imports.
- ketmar via Digitalmars-d-learn (4/20) Oct 07 2014 On Tue, 07 Oct 2014 19:38:52 +0000
Which practice do you use: if you need only one or two functions from a module: import myModule : func, func2; or (import whole module, assuming no function name conflits of course) import myModule; any words why one over the other are welcome. I like the first one why it explicitly show why I'm importing such a module and I think (personally) it make code more easy to read/understand/maitain. Also it's very useful inside functions (local imports) where we can "overload" the function like in: int f(int arg) { import foo : f; return f(somethingElse, arg); } I used it recently.
Oct 06 2014
AsmMan:import myModule : func, func2;I use this in D to know what I have imported and where is was imported from. Bye, bearophile
Oct 06 2014
On Mon, Oct 06, 2014 at 09:24:54PM +0000, AsmMan via Digitalmars-d-learn wrote:Which practice do you use: if you need only one or two functions from a module: import myModule : func, func2; or (import whole module, assuming no function name conflits of course) import myModule; any words why one over the other are welcome. I like the first one why it explicitly show why I'm importing such a module and I think (personally) it make code more easy to read/understand/maitain.Agreed. Recently, I realized more and more that local imports are the way to go if you want maintainable code, specifically, easily- refactorable code. My old C/C++ habit was to put all imports at the top of the file, but the problem with that is, when you need to break a source file into several smaller files, it's a pain to figure out which imports are used by which pieces of code. It's either that, or copy all the imports everywhere, which is wasteful when one of the new files doesn't actually need most of the imports. Explicitly naming imported symbols is also important, especially given the recent bugs related to introducing unwanted symbol conflicts into a scope. It also tells you exactly what symbols a particular piece of code depends on; for example, mymodule.d may import std.algorithm, but it's not clear exactly what in std.algorithm is actually used, and where. Specifically importing std.algorithm : find in func1() and std.algorithm : nextPermutation in the respective scopes that need it, makes the code more maintainable -- readers can quickly find out where 'find' and 'nextPermutation' come from without needing to search the docs (or memorize function names). Then when you need to move func1() and func2() new files, you know that newfile1.d only depends on std.algorithm.find, and newfile2.d only depends on std.algorithm.nextPermutation. So next time you rewrite the code in func1() and you realize that find() is no longer needed, you can delete the import statement without worrying that it will break other parts of the code. Having said that, though, the *disadvantage* of using scoped explicit imports is that if you use a lot of symbols from a particular module, or use the same symbol in many scattered places, then your import statements could become rather unwieldy and repetitive: module mymodule; void func1(...) { import std.algorithm : find, canFind, nextPermutation, remove, /* a huge long list here */; import std.range : isForwardRange; import std.array : front, empty, popFront; ... } void func2(...) { import std.algorithm : canFind, remove, cartesianProduct, /* another huge long list here, repeating many items from previous list */; import std.range : isInputRange; import std.array : front, empty, popFront; ... } So depending on circumstances, sometimes I'd just get lazy and just use a generic import instead. Of course, the example above is extreme... normally, you don't need to use 20 functions from std.algorithm inside a single function; usually just a small handful is enough. So the above situation should be rather rare. I also find that in practice, it's my own modules (rather than Phobos modules) that tend to have symbols that get used repeatedly; in that case I just use a generic import for that. The one exception is std.range, which tends to be needed everywhere if you write range-based code a lot. Usually I just stick `import std.range` at the top of the file in that case.Also it's very useful inside functions (local imports) where we can "overload" the function like in: int f(int arg) { import foo : f; return f(somethingElse, arg); } I used it recently.I'm not sure this is a good idea! It makes the code harder to understand, and if it's a team project, you can bet that one day, somebody will come and introduce a bug because he/she refactored the code but failed to notice that the two 'f's refer to two different things. I'd much rather use the renaming feature of imports: int f(int arg) { import foo : fooF = f; return fooF(somethingElse, arg); } T -- It only takes one twig to burn down a forest.
Oct 06 2014
On Mon, 06 Oct 2014 21:24:54 +0000 AsmMan via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:Which practice do you use: if you need only one or two functions=20 from a module: =20 import myModule : func, func2; =20 or (import whole module, assuming no function name conflits of=20 course) =20 import myModule; =20 any words why one over the other are welcome.in C days i was writting something like this: #include "something.h" // i need foo() and bar() in D such comments can be turned to direct instructions to the compiler. ;-) i tend to import "std.stdio" and "std.string" as a whole at the top of the module (sometimes some other "std." also), and doing local imports with explicit function enumeration when i need something from other modules. local imports rocks! ;-)
Oct 06 2014
On Monday, 6 October 2014 at 21:24:56 UTC, AsmMan wrote:Which practice do you use: if you need only one or two functions from a module: import myModule : func, func2; or (import whole module, assuming no function name conflits of course) import myModule; any words why one over the other are welcome. I like the first one why it explicitly show why I'm importing such a module and I think (personally) it make code more easy to read/understand/maitain. Also it's very useful inside functions (local imports) where we can "overload" the function like in: int f(int arg) { import foo : f; return f(somethingElse, arg); } I used it recently.Be mindful of this classic bug: https://issues.dlang.org/show_bug.cgi?id=314
Oct 07 2014
On Tuesday, 7 October 2014 at 07:33:24 UTC, Gary Willoughby wrote:On Monday, 6 October 2014 at 21:24:56 UTC, AsmMan wrote:Yeah. In the current state of affairs, please NEVER do selective imports in global scope. As a general rule, avoid imports in global scope anyways.Which practice do you use: if you need only one or two functions from a module: import myModule : func, func2; or (import whole module, assuming no function name conflits of course) import myModule; any words why one over the other are welcome. I like the first one why it explicitly show why I'm importing such a module and I think (personally) it make code more easy to read/understand/maitain. Also it's very useful inside functions (local imports) where we can "overload" the function like in: int f(int arg) { import foo : f; return f(somethingElse, arg); } I used it recently.Be mindful of this classic bug: https://issues.dlang.org/show_bug.cgi?id=314
Oct 07 2014
On Tuesday, 7 October 2014 at 08:37:59 UTC, monarch_dodra wrote:As a general rule, avoid imports in global scope anyways.Can you expand or provide a link to the issue?
Oct 07 2014
On Tue, 07 Oct 2014 17:24:40 +0000 bachmeier via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Tuesday, 7 October 2014 at 08:37:59 UTC, monarch_dodra wrote:ahem... https://issues.dlang.org/show_bug.cgi?id=3D313 https://issues.dlang.org/show_bug.cgi?id=3D314As a general rule, avoid imports in global scope anyways.Can you expand or provide a link to the issue?
Oct 07 2014
On Tuesday, 7 October 2014 at 17:29:45 UTC, ketmar via Digitalmars-d-learn wrote:On Tue, 07 Oct 2014 17:24:40 +0000 bachmeier via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:That's only relative to having selective imports. The idea of avoiding global imports is mostly to avoid polluting your own namespace, or to keep better track of who needs what. For example, if 1 function requires "std.foo", and then you later remove that function. With global imports, chances are you'll forget to remove it.On Tuesday, 7 October 2014 at 08:37:59 UTC, monarch_dodra wrote:ahem... https://issues.dlang.org/show_bug.cgi?id=313 https://issues.dlang.org/show_bug.cgi?id=314As a general rule, avoid imports in global scope anyways.Can you expand or provide a link to the issue?
Oct 07 2014
On Tue, 07 Oct 2014 19:38:52 +0000 monarch_dodra via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> wrote:On Tuesday, 7 October 2014 at 17:29:45 UTC, ketmar via=20 Digitalmars-d-learn wrote:ah, i see. sorry, i misread the question.On Tue, 07 Oct 2014 17:24:40 +0000 bachmeier via Digitalmars-d-learn=20 <digitalmars-d-learn puremagic.com> wrote:=20 That's only relative to having selective imports.On Tuesday, 7 October 2014 at 08:37:59 UTC, monarch_dodra=20 wrote:ahem... https://issues.dlang.org/show_bug.cgi?id=3D313 https://issues.dlang.org/show_bug.cgi?id=3D314As a general rule, avoid imports in global scope anyways.Can you expand or provide a link to the issue?
Oct 07 2014