www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - scoped imports

reply Timothee Cour <thelastmammoth gmail.com> writes:
Is there a way to achieve this:

----
module foo;

{
import bar;
void fun1(){bar.barfun();}
void fun2(bar.BarType a){}
}

// now bar is not in scope anymore.
void fun3(){}
----

This would reduce name clashes conflicts, ease refactorings and in general
make code a bit cleaner.

Related question:

Why isn't the following allowed:
----
void fun(){
// code without version=A
  version=A;
// code with version=A
  vesion(none):
//code versioned out
}
----
I understand the grammar doesn't allow it, but what's the rationale, and
can it be fixed?
Aug 17 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Timothee Cour:

 Is there a way to achieve this:

 ----
 module foo;

 {
 import bar;
 void fun1(){bar.barfun();}
 void fun2(bar.BarType a){}
 }

 // now bar is not in scope anymore.
Using a struct as namespace: struct Foo { import std.stdio; static void bar(int x) { x.writeln; } } alias bar = Foo.bar; void main() { bar(10); // writeln(20); // std.stdio out of scope } Bye, bearophile
Aug 17 2013
parent Timothee Cour <thelastmammoth gmail.com> writes:
thanks.
That's a bit clunky though, so it's unlikely to be used. Not sure what it
would take to make the grammar allow it.


On Sat, Aug 17, 2013 at 4:23 PM, bearophile <bearophileHUGS lycos.com>wrote:

 Timothee Cour:


  Is there a way to achieve this:
 ----
 module foo;

 {
 import bar;
 void fun1(){bar.barfun();}
 void fun2(bar.BarType a){}
 }

 // now bar is not in scope anymore.
Using a struct as namespace: struct Foo { import std.stdio; static void bar(int x) { x.writeln; } } alias bar = Foo.bar; void main() { bar(10); // writeln(20); // std.stdio out of scope } Bye, bearophile
Aug 17 2013
prev sibling parent reply "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Saturday, 17 August 2013 at 22:30:14 UTC, Timothee Cour wrote:
 Is there a way to achieve this:

 ----
 module foo;

 {
 import bar;
 void fun1(){bar.barfun();}
 void fun2(bar.BarType a){}
 }

 // now bar is not in scope anymore.
 void fun3(){}
 ----

 This would reduce name clashes conflicts, ease refactorings and 
 in general
 make code a bit cleaner.
Why not import bar _inside_ fun1 and fun2 ... ? void fun1() { import bar; barFun(); } ... should work, no?
Aug 17 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
that's not DRY: in my use case, a group of functions use certain imports,
it would be annoying and not DRY to do that. What I suggest (allowing {}
grouping at module scope) seems simple and intuitive; any reason it can't
be done?


On Sat, Aug 17, 2013 at 6:16 PM, Joseph Rushton Wakeling <
joseph.wakeling webdrake.net> wrote:

 On Saturday, 17 August 2013 at 22:30:14 UTC, Timothee Cour wrote:

 Is there a way to achieve this:

 ----
 module foo;

 {
 import bar;
 void fun1(){bar.barfun();}
 void fun2(bar.BarType a){}
 }

 // now bar is not in scope anymore.
 void fun3(){}
 ----

 This would reduce name clashes conflicts, ease refactorings and in general
 make code a bit cleaner.
Why not import bar _inside_ fun1 and fun2 ... ? void fun1() { import bar; barFun(); } ... should work, no?
Aug 17 2013
parent reply "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Sunday, 18 August 2013 at 01:33:51 UTC, Timothee Cour wrote:
 that's not DRY: in my use case, a group of functions use 
 certain imports,
 it would be annoying and not DRY to do that. What I suggest 
 (allowing {}
 grouping at module scope) seems simple and intuitive; any 
 reason it can't be done?
How do you ensure that the imports are limited to your {} scope, but your functions are not, without a finnicky special case for how scopes work?
Aug 18 2013
parent reply Timothee Cour <thelastmammoth gmail.com> writes:
On Sun, Aug 18, 2013 at 2:31 AM, Joseph Rushton Wakeling <
joseph.wakeling webdrake.net> wrote:

 On Sunday, 18 August 2013 at 01:33:51 UTC, Timothee Cour wrote:

 that's not DRY: in my use case, a group of functions use certain imports,
 it would be annoying and not DRY to do that. What I suggest (allowing {}
 grouping at module scope) seems simple and intuitive; any reason it can't
 be done?
How do you ensure that the imports are limited to your {} scope, but your functions are not, without a finnicky special case for how scopes work?
granted, that's not ideal. How about the other points I mentioned? void fun(){ version=A; version(none): }
Aug 18 2013
parent reply "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Sunday, 18 August 2013 at 09:52:29 UTC, Timothee Cour wrote:
 On Sun, Aug 18, 2013 at 2:31 AM, Joseph Rushton Wakeling <
 joseph.wakeling webdrake.net> wrote:

 On Sunday, 18 August 2013 at 01:33:51 UTC, Timothee Cour wrote:
granted, that's not ideal. How about the other points I mentioned? void fun(){ version=A; version(none): }
Not sure I understand what you're trying to achieve there. But as an alternative to function-local import, why not split your module into a package, with submodules mymodule.bardependent and mymodule.nonbardependent ... ?
Aug 18 2013
next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 18 August 2013 at 14:52:04 UTC, Joseph Rushton 
Wakeling wrote:
 On Sunday, 18 August 2013 at 09:52:29 UTC, Timothee Cour wrote:
 On Sun, Aug 18, 2013 at 2:31 AM, Joseph Rushton Wakeling <
 joseph.wakeling webdrake.net> wrote:

 On Sunday, 18 August 2013 at 01:33:51 UTC, Timothee Cour 
 wrote:
granted, that's not ideal. How about the other points I mentioned? void fun(){ version=A; version(none): }
Not sure I understand what you're trying to achieve there. But as an alternative to function-local import, why not split your module into a package, with submodules mymodule.bardependent and mymodule.nonbardependent ... ?
Related: is it possible to pack several modules/submodules in a single file? Or do you necessarily have to split them up?
Aug 18 2013
prev sibling parent reply Timothee Cour <thelastmammoth gmail.com> writes:
On Sun, Aug 18, 2013 at 7:52 AM, Joseph Rushton Wakeling <
joseph.wakeling webdrake.net> wrote:

 On Sunday, 18 August 2013 at 09:52:29 UTC, Timothee Cour wrote:

 On Sun, Aug 18, 2013 at 2:31 AM, Joseph Rushton Wakeling <
 joseph.wakeling webdrake.net> wrote:

  On Sunday, 18 August 2013 at 01:33:51 UTC, Timothee Cour wrote:

 granted, that's not ideal. How about the other points I mentioned?
 void fun(){
 version=A;
 version(none):
 }
Not sure I understand what you're trying to achieve there.
goal1: avoid polluting global module name space: void fun(){ version=A; //now the code below in fun() scope has version(A) set } goal2: void fun(){ version(none): //all the code below this IN THIS FUNCTION becomes versioned out //(avoids requiring extra {} scope }
 But as an alternative to function-local import, why not split your module
 into a package, with submodules mymodule.bardependent and
 mymodule.nonbardependent ... ?
Aug 18 2013
parent reply "Joseph Rushton Wakeling" <joseph.wakeling webdrake.net> writes:
On Monday, 19 August 2013 at 01:16:44 UTC, Timothee Cour wrote:
 goal1: avoid polluting global module name space:
 void fun(){
 version=A;
 //now the code below in fun() scope has version(A) set
 }

 goal2:
 void fun(){
 version(none):
 //all the code below this IN THIS FUNCTION becomes versioned out
 //(avoids requiring extra {} scope
 }
I honestly think that you are spending far too much mental effort in pursuit of complex, finnicky solutions for issues that can be dealt with much better by other means. If you're getting namespace clashes because one set of functions is dependent on foo.stuff and others are dependent on bar.stuff, surely the simplest way to avoid it is to place them in different modules -- which can then be grouped into a package if needed. What's wrong with this approach?
Aug 18 2013
parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Monday, August 19, 2013 04:36:37 Joseph Rushton Wakeling wrote:
 On Monday, 19 August 2013 at 01:16:44 UTC, Timothee Cour wrote:
 goal1: avoid polluting global module name space:
 void fun(){
 version=A;
 //now the code below in fun() scope has version(A) set
 }
 
 goal2:
 void fun(){
 version(none):
 //all the code below this IN THIS FUNCTION becomes versioned out
 //(avoids requiring extra {} scope
 }
I honestly think that you are spending far too much mental effort in pursuit of complex, finnicky solutions for issues that can be dealt with much better by other means. If you're getting namespace clashes because one set of functions is dependent on foo.stuff and others are dependent on bar.stuff, surely the simplest way to avoid it is to place them in different modules -- which can then be grouped into a package if needed. What's wrong with this approach?
I'd also chime in that version should generally be used for system stuff (like Posix or X86_64), and it's usually a bad idea to be setting version identifiers anywhere other than the command line. Version identifiers just aren't designed for that, particularly as setting them in a module can't affect other modules, seriously limiting their applicability if they're not set on the command line. If you have local stuff that you want to turn on or off, it's probabyl better to use enums, variables, is expressions, or something similar inside of static ifs rather than using version blocks. It's also much easier to control the scope of variables if want to affect the static ifs that way. - Jonathan M Davis
Aug 18 2013