new DIP47: Outlining member functions of aggregates

Simen Kjaeraas simen.kjaras at gmail.com
Sun Sep 8 11:12:04 PDT 2013


On 2013-09-07, 19:00, Walter Bright wrote:

> 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

I like the idea, but I feel the DIP is missing some info:

- What happens to UDAs? Do I need to declare them both places?
- Why no nested classes/structs?
- How do outlined ctors/dtors look?
- How does it look in practice? Is this how it works:

// foo.d:
module foo;
class Foo {
    int bar();
}

//foo_impl.d:
module foo;
import foo;
int Foo.bar() {
     return 3;
}

- Do the module names have to be the same?
- Do I have to import the 'header' module in the implementation modules?
- If the module names don't have to be the same:
     Can I implement the functions in any package? Sub-package? Only
         the same package?


Also, I disagree with these points:

- Parameter names should match. I can accept nameless parameters in the
    declaration, but otherwise they should match. Anything else is an
    invitation for things to go out of sync.
- Default parameter values - either disallow them or enforce that they
    are the same in both places.
- Implementation in a module different from the declaration. .di files
    provide all the good stuff here, without sending you on a wild goose
    chase through all your files for that one function your resident
    junior programmer hid away inside the implementation of a completely
    different class.


Lastly, I want more examples - is this the same for structs and classes?
Interfaces? Can I spread the function definitions over several modules?

All in all, I would currently vote against.


As an aside, I do like the idea of having a nice list of member
functions that is statically compared to those actually implemented.
This could however be done in different ways. My favorite would be
something along these lines:

class Foo {
     interface {
          float bar(int n) const;
          Foo clone();
          static int qux(); // Compile-time error on this line: declared
                            //  function with no implementation.
     }
     float bar(int n) const {
         return 0.0;
     }
     Foo clone() {
         return this;
     }
     static int baz() { // Compile-time error on this line: undeclared
                        //  function with implementation.
         return 2;
     }
}

For the sake of fueling discussion, I have created a DIP with this  
suggestion:
http://wiki.dlang.org/DIP48

-- 
   Simen


More information about the Digitalmars-d mailing list