Wednesday, 4 October 2006

Delphi for .NET namespaces misunderstood?


There seems to be a big confusion about Delphi for .NET namespaces. I guess this is because there was a big change between Delphi 8 and Delphi 2005.

In Delphi 8, each unit was its own namespace. In Delphi 2005, several units can be placed in the same namespace, by prefixing the unit name with the namespace name. You can even add to an existing namespace in an assembly not written in Delphi for .NET.

I often see the argument that namespaces in Delphi for .NET are non-standard. But since you can create a namespace consisting of several units, in several assemblies, there is in fact no big difference for other .NET languages. To the "outside" world, i.e. to non-Delphi code, they are as standard as they should be.

IOW, if you have units Rudy.Velthuis.Labels, Rudy.Velthuis.EditBoxes, and Rudy.Velthuis.Memos they make up the namespace Rudy.Velthuis, and can be used as such from any non- Delphi .NET language. (FWIW, if your namespace is only meant to contain VCL.NET classes, I see no reason not to use the VCL terminology, i.e. prefix types with T, etc. If your assembly is meant to be used by other languages, then follow the .NET guidelines on naming.)

What is different is that Delphi for .NET internally has the advantage that you don't include an entire namespace, filling up the scope with a lot of unnecessary identifiers, but only the units you need. This is IMO a big advantage. If you only need Labels, but not EditBoxes or Memos, you only put Rudy.Velthuis.Labels in your uses clause. I'll explain why this is IMO a Good Thing™

Any good C++ programmer will frown upon the practice of including entire namespaces into the scope. A good C++ programmer will not use

using namespace std;

but will simply qualify each identifier from that namespace with the explicit std:: prefix. For the same reason, Modula 2 users can import entire modules, but are encouraged to only import the identifiers they need. Delphi for .NET's scope resolution is not that fine grained, but at least it offers units, instead of the inclusion of entire namespaces. Of course this only works with Delphi-written namespaces.

The fact that namespaces are disconnected from physical file names is perhaps not a problem for a compiler (well, it actually is a small problem, since it makes it have to look up and remember — store — a lot more identifiers, which makes it slower), but it is a problem for the humans who have to use them. I am glad that Delphi keeps the connection between compilation unit and logical unit.


So, to recap:

  • Delphi namespaces are extensible, like in other .NET languages. Several units can make up a namespace, and units can be added to one. They are perhaps non-standard internally, but to the outside .NET world, they are no different than a VB or C# namespace.
  • Delphi namespaces are usable by other languages as one namespace, no matter how many units it contains.
  • Internally, when Delphi uses Delphi-written namespaces, Delphi has the added advantage that you don't have to include entire namespaces at once, but have a finer grained scoping mechanism.
  • Delphi units are IMO easier to use than namespaces consisting of several source files and spread over several assemblies.
Rudy Velthuis