Friday, May 7, 2004

Files, Units and namespaces.. oh my!

Arbitrary and structural... these are words I would use describe the relationship between how C# contends with files and how Delphi (nay, Turbo/Borland Pascal) contends with them. As I thought more about this it became more clear about how this subtle difference in how Delphi and C# view a physical source file caused some of the misunderstandings, assumptions, and outright disappointments regarding Delphi's handling of namespaces. I may be completely out in left field here... or I may just be stating the obvious... and that may be the issue... duh! that's obvious!

In C#, the notion of a physical source file is almost purely arbitrary and abstract. To the compiler, there are no file boundaries. They carry no structural information to the compiler. You have to tell the compiler about every source file you intend to build into the assembly. That list of files also must be referentially consistent, or every type reference must be resolvable either by the list of source files or by external explicit assembly references. You see, that's a key difference between Delphi and C#'s view of files, structure. In Delphi, a physical file is a language construct in and of itself. It is the boundaries of the actual file that define the "namespace." This is why Delphi can keep .dcu/.dcuil files in order to decrease compile and link times. It can easily tell if a .dcu/.dcuil (which are essentially a raw dump of the compiler's internal symbol tables) is out of date by checking both file dates and symbol versions. It is also this same file-based structure that gives serves to seemingly limit the programmer's ability to define exactly how a set of components or classes appear when they are exported from an assembly.

What about Java? Java is actually closer to the Delphi way than the C# way when dealing with files. To Java, the physical file is also a language construct. You can't have more than one class in a .java or ultimately a .class file, except inner classes, of course. To Java, the folder hierarchy is also a language construct. It serves as the definition of a namespace. Java then goes and throws in another twist... the imports clause can contain the '*' character to tell the compiler that you want to reference all classes from a given namespace (or folder hierarchy) without explicitly specifying every class you intend to reference. This allows you to add classes into a specific namespace and have those new classes appear without updating the dependent source files' imports clauses.

So, what does this all lead up to? Nothing really. You don't even have to think this is particularly insightful. This was just a random thought... You can also see that this is going to be a very tough nut to crack. Delphi's notion of files=units=structure is fundamental to the overall character of the Delphi language. Maybe we should begin to look at other languages' playbooks for ways of dealing with namespaces.