www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1509] New: Need a way to create namespaces inside modules

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1509

           Summary: Need a way to create namespaces inside modules
           Product: D
           Version: 1.021
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: wbaxter gmail.com


There's currently no good way to organize a set of functionality under a common
namespace within a module.

In C++ one can use the 'namespace' keyword for this.  If you ever look at Boost
code, for instance, you'll see they use 'namespace detail' all over the source
to group functionality that is an implementation detail.

I'd like to see such a namespace grouping capability added to D.

That's the ehnancement request, now read on for one proposal for how to provide
that functionality.

D already has a namespace creation mechanism, namely modules.
For instance, if I want to group some imports or functions together under one
namespace called 'detail', in current D I can do that by making a file called
'detail.d' that contains the public imports I want it to have, and any extra
functions I want to give it.  Then I 'static import detail;' from mymodule.d,
and voila, I have access to all that stuff via 'detail.*'.

This has several drawbacks, however. 
1) it's simply cumbersome to have to make a separate file just to get a new
namespace.
2) it is likely that this module will not be imported (and maybe *shouldn't* be
imported) by any module besides "mymodule.d".  But that restriction can't be
enforced. 
3) For the case of implementation detail modules, 'detail.d' will very likely
need access to private members of mymodule.d, which it can't have.  Also
vice-versa, mymodule.d may need access to privates of detail.d, which it can't
have.
4) You can't realistically just name the module 'detail' because other modules
may want to have a namespace called 'detail' too.  So to avoid module naming
conflicts it would actually have to be called something unique like
"foo.bar.mymodule_detail"

But the module mechanism basically does what is needed, so I don't think it's
necessary to add any new keywords, we just need to allow a new use of the
'module' keyword to define an "inner module".

Basic example:

------
module mymodule;
private module Detail {
   import std.stdio;
   import std.string;
   import std.regex;
   void foo() { writefln("I'm an implementation detail"); }
}
...
void public_func() {
   Detail.writefln("hi there");
}
------


Another possibility would be to have "named protection blocks". 

E.g.

private Detail {
  ...
}

public Core {
  ...
}


-- 
Sep 16 2007
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1509


wbaxter gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement
            Version|1.021                       |2.004





Forgot to label this "enhancement".
And maybe V2.0 is more appropriate.


-- 
Sep 16 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1509






Here's a workaround from Daniel Keep on the NG:

"""
The way I usually work around this is like so:

template Namespace_()
{
  // Stuff in the namespace.
}

mixin Namespace_ Namespace;

Kinda hacky, but it works  :) 

        -- Daniel
"""

This is certainly better than creating a separate file, but still an awfully
bizarre and roundabout way to create a new namespace.


-- 
Sep 16 2007
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1509






Walter brought up that a struct with all static methods is also a workaround.

The main functional deficiency with both these workarounds (aside from
aesthetic concerns over how kludgy it looks) is that neither solution permits
imports into that nested scope.

But allowing imports in nested scopes like structs and functions is another
enhancement that would certainly be welcome.


-- 
Sep 18 2007
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1509


dawg dawgfoto.de changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |dawg dawgfoto.de



Importing into functions, templates and structs do work now.
The cleanest way to fake a namespace is to alias a template.

----
cat > test.d << CODE
template MyNameSpace_()
{
  import std.stdio;

  void foo()
  {
      writeln("MyNameSpace.foo");
  }
}
alias MyNameSpace_!() MyNameSpace;

void main()
{
    MyNameSpace.foo();
}
CODE

dmd -run test.d
----

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 14 2012