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 :-)