new DIP47: Outlining member functions of aggregates

Michel Fortin michel.fortin at michelf.ca
Sun Sep 8 05:02:56 PDT 2013


On 2013-09-07 17:00:05 +0000, Walter Bright <newshound2 at digitalmars.com> said:

> Outlining of member functions is the practice of placing the 
> declaration of a member function in the struct/class/union, and placing 
> the definition of it at global scope in the module or even in another 
> module.
> 
> http://wiki.dlang.org/DIP47

About placing the definition in another module, you say that the 
definition when outlined in another module would have private access to 
the private members of the module of declaration. Does that mean that 
the definition has access to the private members of two modules at the 
same time, the one it is declared in and the one it is defined in? That 
seems strange to me.

I find it strange that pure/const/immutable/shared/nothrow need to 
match, yet static does not. Beside this being the way it works in C++ 
(presumably because static at global scope has another meaning 
inherited from C), I see no reason for this. In C++ I often find myself 
wondering whether a function has access to the member variables and I 
have to find the definition in the header file, which is inconvenient. 
Static being part of the definition seems to only make sense.

About parameter names, I think it'd be better if they were forced to 
match. Mismatches are a code smell to me: if you reverse the meaning of 
two parameters with the same type while refactoring, you must be sure 
the public interface and the implementation still agree. I guess you 
could allow the declaration to omit the parameter names in which case 
the definition could add a name, but don't allow *different* names, 
it's pointless and it can easily hide a bug.

I think it's fine that default values for parameters don't have to be 
repeated, but it'd be nice if they *could* because it enables 
copy-pasting of the declarations. The compiler would of course have to 
check that both expressions are identical.

I'd like to make a suggestion. If one goal is effectively to allow the 
implementation of a function to live in a separate file from its 
declaration, then we already have a mechanism for that: .di files. So 
I'd like to suggest this: allow a .d file to "import" its corresponding 
.di file. Then the .d file should only contain the missing definitions 
for what's declared in the hand-crafted .di file. That'd remove the 
dubious semantics of making the definition part of another module and 
would also allow outlining of global functions. And it also matches 
better the C++ model of header/implementation files.

Also, I'd allow outlining only for this specific case where a .di file 
is imported by a .d file. This way you know for sure when you see a 
declaration without the definition in a .di file that this declaration 
is in the corresponding .d file and not anywhere else, making it easier 
to hunt it down.

Example:

	// test.di
	module test;

	class A {
		void foo(int a, int b);
	}

	// test.d
	import module test; // import declarations from the .di file

	void A.foo(int a, int b) {
		// member function definition
	}

-- 
Michel Fortin
michel.fortin at michelf.ca
http://michelf.ca



More information about the Digitalmars-d mailing list