So I have this recurring pattern, it's really starting to annoy me.
It stems from the fact that a function prototype and the definition can not appear in the same file in D (as it can in C/C++)
Eg,

void func(int x); // <-- declaration of function, informs type and associated names, args, ...

//later
void func(int x) // <-- may be generated with magic (and may use the prototype declaration for type information as declared by the prototype above)
{
  ... do stuff
}

I really need this. Why is it illegal? Is there chance of having this supported? What are the problems?

My problem is essentially to do with supporting both static or dynamic linkage optionally, but it also shows up in situations where I want to perform comprehensive magic code generation, but want clear-readable user declarations.
The simplest case:
  I have an extern that I may want to statically or dynamically link.
    In the case of static linkage, one just produces a prototype, and it links, no problem.
    In the case of dynamic linkage, one must produce a stub for the function, a function pointer to call through, and perhaps some code to hook-up the function pointer at init.

I have a fairly comprehensive binding solution which automates the work in the case of dynamic linkage, but the problem is the way the user defines the functions that exist in the D code.
I'd like it if the users would just write the prototypes, they'd be easily readable, simple to create by cutting and pasting straight from C code. And when statically linking, it would just work, the module hook-up mixin does nothing in this configuration.
In the case of dynamic linkage, a single hook-up mixin in the file somewhere could scan the module for these prototypes and generate the stubs, function pointers, and the boot-up code that would connect them (while validating their signatures against the extern import table, etc).

This approach isn't supported though. What I do instead:

mixin( ImportFunction!( "functionName", int function( int arg1, float arg2, ref in SomeStruct arg3 ), "pure nothrow" ) );
mixin( ImportFunction!( "functionName2", int function() ) );
mixin( ImportFunction!( "functionName3", int function( int x, int y ), "nothrow" ) );
etc etc

These templates produce, from the information provided, either a prototype for static linkage, or the { stub, func pointer, initialisation info } for dynamic linkage.

I really don't like doing it this way for a number of reasons:
  *** This results in hundreds of mixins, which quickly lead to intolerable compile times (to the point where D is losing it's appeal as a viable choice for our needs). If done my preferred way, I could do the magic with a single mixin at the bottom of the file.
  * It's barely readable.
  * Much more annoying to write and maintain when the counterpart API changes, and is more error-prone.
  * IDE features don't work properly; syntax highlighting, hover info, go-to-definition, etc.

I also have numerous more advanced cases of the same problem, and becomes even more unsightly when used in structs to emulate dynamic linkage to static methods of C++ classes.

The solution is seemingly trivial; allow function prototypes and definitions to exist in the same file, like in C/C++.


Go on, tear me apart... :)