Wednesday, April 21, 2004

Different broken rant

Ok, this really isn't a rant, per se... It is also a history lesson. Julian Bucknall posted this rant about Delphi's "poor" support of namespaces. First of all I agree with Julian on principal, however I'd like to also remind our esteemed viewers of the lineage and heritage that is Delphi, and more specifcally Turbo Pascal. When Turbo Pascal 4 was introduced over a decade and a half ago, it turned the Turbo Pascal world on its ear. It introduced the concept of a "unit." Well, guess what people, a "unit" is a namespace. The unit allowed one to break up their project into mutiple logical modules that could then be re-used in several projects and also isolate type names under a common umbrella. This way you could have a type called TFoo in unit A and have a completely different type called TFoo in Unit B. You could now use both unit A and unit B without a conflict. If you wanted to make sure you were accessing TFoo from Unit A, you simply wrote A.TFoo. Hmmm... this is suspiciously looking like a namespace to me. One of the fantastic features of the "unit" arrangement was the built-in compiler make logic. Since a unit identifier matched a filename, you didn't have to tell the compiler about every single little source file in your project. All you had to do was to tell the compiler in what directories to search and it figured out the rest. You passed one filename to the compiler and away it went and out popped your .EXE.

Now fast forward to today. Now that we've gone down the path of "enlightenment," and we're all a little "smarter," it seems to be a vogue thing these days to look at the new shiny objects as being all good and everything before it is now all bad. What we fail to seemingly acknowledge is that there are very few giants out there these days... there are just a lot of people very good at standing on shoulders.

Now suppose were were to "fix" this namespace "problem" so that things worked and looked like, say C#, VB.NET, or even Managed C++. Would you, as a Delphi/Pascal programmer, accept the fact that the one feature you take for granted (and I know you do), the integrated build/make logic of the compiler suddenly disappeared? What if you had to specify every single file you want compiled or linked into your application, even Borland.Vcl.Classes? Before you answer that, consider this... the uses clause. When you "use" something, is that a unit or a namespace? In Delphi for .NET it is both. Suppose you have Unit A; that you want to appear as namespace Foo. Do you type uses A; or uses Foo;? What's that? Foo you say? OK. Now the compiler "sees" Foo... whoops, uh where does it find the .dcuil or more importantly, the .pas file? There is no Foo.pas because you called it A.pas because it is unit A;

Now before you stop by the gas station and fuel up your flame-thrower and start lobbing napalm at me, I am only posting this to highlight both the history behind why things are they way they are now and some of the design hurdles we must jump in order to "fix" this issue. This is a lot more complicated than simply adding some directive that modifies how a unit appears to others. We must make sure we don't totally break the integrated build/make logic of the compiler since that is one of the foundational pillars of the compiler. I can assure you that we are intensely looking into providing a solution that will satisfy all these requirements. There has been a lot of skeet shooting taking place as Danny and I lob ideas out into the firing range. So far we've been able to hit everyone of those "clay pigeons" and blast them to bits. I'm confident that there is a steel pigeon in the box that will be impervious to our shelling.

Finally, I do certainly take offense at broad sweeping statements that Delphi's use of namespaces is totally broken. It is simply that it is different. At no point does Delphi's treatment of "unit"="namespace" violate any CLI or CLS rules. It there is some violation, then please point it out to myself and Danny and a good dose of crow will be ordered.

Different <> broken.