On Friday, 22 July 2011 at 22:06:20 UTC, Andrei Alexandrescu wrote:
A chat in IRC revealed a couple of possible improvements to the development scenario in which the interface file (.di) is managed manually and separately from the implementation file (.d).

After discussing a few ideas with Walter, the following language improvement came about. Consider a very simple scenario in which we have files a.d, a.di, and client.d, all situated in the same directory, with the following contents:

// a.di
class A { private int x; int foo(); }

// a.d
import a;
int A.foo() { return x + 1; }

// client.d
import a;
void main() { (new A).foo(); }

To compile:

dmd -c a.d
dmd -c client.d
dmd client.o a.o

Currently, in order for a program with separately-implemented methods to work properly, there must be TWO different files for the same class, and the .di file and the .d file MUST specify the same exact field layout. Ironically, the .d file is forbidden from including the .di file, which makes any checks and balances impossible. Any change in the layout (e.g. swapping, inserting, or removing fields) is undetectable and has undefined behavior.

I see this as a source of problems going forward, and I propose the following changes to the language:

1. The compiler shall accept method definitions outside a class.

2. A method cannot be implemented unless it was declared with the same signature in the class definition.

Walter is reluctantly on board with a change in this direction, with the note that he'd just recommend interfaces for this kind of separation. My stance in this matter is that we shouldn't constrain without necessity the ability of programmers to organize the physical design of their large projects.

Please discuss here. I should mention that Walter has his hands too full to embark on this, so implementation should be approached by one of our other dmd contributors (after of course there's a shared view on the design).


Andrei

One of the main selling points of the module system is to prevent exactly what you are proposing, so I think there must be a better solution.

The biggest disappointment I have with modules, is that you cannot define an interface inside of them, and must instead resort to a .di file.

Manually maintaining a .di file is a bad idea for what should be obvious reasons, and the auto generation of the .di is a failure because you cannot tell the compiler how to generate the .di file from inside the module.

For a solution, what I'd like to see is manual control over what will go into an automatically generated .di placed directly inside the D module.

For example, allow the programmer to specify the separation of interface from implementation directly inside the module through an improvement to how modules are defined, that is to say allow the programmer to specify what is a part of the interface and what is a part of the implementation directly inside the module. The compiler can then auto generate the necessary .di interface files from that information, the obvious benefit being that you'll get interface and implementation separation without the separation of where the control point is, eg it's all done inside the module where it should be done and nowhere else, and do it without a duplication of definitions. This can possibly be done without duplication through the attribute system.

There should be a way for the compiler to determine if previously auto generated interface files are the same or differ to prevent overwriting and forcing unnecessary recompilation. If the .di files are stored in specific locations away from wher the compiler is dumping them, then you could add an "include" switch to tell the compiler where to look for previously generated .di and compare them.

Sure it's a bit of effort to implement, but it seems like a far more useful solution that is safe, scalable, and easy to maintain.

--rt

PS: While we're on the topic of interfaces (or lack thereof), another problem point I have with D is that while you can define an interface for classes, you cannot do the same thing with structs. I don't understand why structs cannot have interfaces.

Reply via email to