Specifying C++ symbols in C++ namespaces

Walter Bright newshound2 at digitalmars.com
Sun Apr 6 15:03:25 PDT 2014


On 4/6/2014 2:00 PM, monarch_dodra wrote:
> On Sunday, 6 April 2014 at 20:17:09 UTC, Walter Bright wrote:
>> D has closed scopes, and members can be "added" to external classes just fine,
>> using CTFE.
>
> You mean UFCS?

Yes, my mistake.


> As in, for example, "front" for arrays? It doesn't work as well
> as advertised though. The issue is that the added members are only visible if
> the *called* code knows to import the *caller* code.

That's a feature of a modular system, not a bug. D does not have a global name 
space, on purpose.

> This breaks as soon as you
> leave your own internal ecosystem.
>
> //----
> import a;
> 
> struct S //Some object
> {
> }
>
> //Extend to make it a range.
> bool empty(S);
> int front(S);
> void popFront(S);
>
> //Try it.
> void main()
> {
>      S s;
>      foreach(e; s) //Error: invalid foreach aggregate s
>          writeln(s);
>      s.array(); //Error: template std.range.take cannot...
>      a.foo(s); //Error: no property 'popFront' for type 'S'
> }
> //----
> module a;
>
> void foo(T)(T t)
> {
>      t.popFront();
> }
> //----
> Well that horribly fails.

That's based on a misunderstanding of how scoped lookup works in D, and how to 
use it properly. In the particular instance above, there is simply no reason to 
not put front() as a member of S, since they are in the same module.


> Because when calling a template, you are only importing the passed argument, but
> not his ecosystem with it. The only way in D to "really" extend an existing
> object, is to wrap it into a new object. And even then, the wrapping is limited,
> because you can't orthogonally wrap (eg the wrapping linearly stacks, whereas
> UCFS *could* add two completely independent functionalities). Not to mention
> issues with code bloat...

You're right in that if you try to do things the C++ way in D, things won't work 
out so well. D can do all these things, but they are done in a different way - a 
way that is much more robust.

The fault in the C++ method of extending namespaces is that two independently 
developed modules had better not extend the same namespace with the same names. 
You will not necessarily get a compiler error from violating this - code may 
just wind up calling the wrong overload. I.e. it does not scale.


> C++'s namespaces have their flaws, but they *are* scalable in a way D's modules
> aren't, thanks to Koenig Lookup.

I've never seen anyone defend Koenig lookup as anything but a hack before :-)


More information about the Digitalmars-d mailing list