Thread overview
method generation by name
Jul 23, 2007
BCS
Jul 23, 2007
Robert Fraser
Jul 23, 2007
BCS
Jul 24, 2007
Kirk McDonald
Jul 24, 2007
BCS
Jul 24, 2007
Daniel Keep
July 23, 2007
What is the best way to generate a method with a given name (as specified by a const char[]) without having to build the whole thing as a string?

I was hoping this would work:

|template foo(R, char[] name, A...)
|{
|  R mixin(name)(A a)
|  {
|    return d(a);
|  }
|}
|
|mixin foo!(int, "hello", int);
|
|void main()
|{
|  int i = hello(1);
|}

the best I have come up with is a bit hackish and has a few "issues".

|template foo(R, char[] name, A...)
|{
|  R somthing(A a){return R.init;}
|  mixin("alias somthing "~name~";");
|}

If a clean solution for this were made and class level static foreach were to be implemented then auto implementation of an interface would be doable.


July 23, 2007
BCS Wrote:

> What is the best way to generate a method with a given name (as specified by a const char[]) without having to build the whole thing as a string?
> 
> I was hoping this would work:
> 
> |template foo(R, char[] name, A...)
> |{
> |  R mixin(name)(A a)
> |  {
> |    return d(a);
> |  }
> |}
> |
> |mixin foo!(int, "hello", int);
> |
> |void main()
> |{
> |  int i = hello(1);
> |}
> 
> the best I have come up with is a bit hackish and has a few "issues".
> 
> |template foo(R, char[] name, A...)
> |{
> |  R somthing(A a){return R.init;}
> |  mixin("alias somthing "~name~";");
> |}
> 
> If a clean solution for this were made and class level static foreach were to be implemented then auto implementation of an interface would be doable.
> 
> 

I think you might have to use your way until macros come along. What's so wrong with the alias way, though?
July 23, 2007
Reply to Robert,

> I think you might have to use your way until macros come along. What's
> so wrong with the alias way, though?
> 

mixin foo!(int, "hello", int);
mixin foo!(int, "world", int);

now their are two somthings. And that just feels wrong. This can be worked around but, that also has some issues.


July 24, 2007
BCS wrote:
> What is the best way to generate a method with a given name (as specified by a const char[]) without having to build the whole thing as a string?
> 
> I was hoping this would work:
> 
> |template foo(R, char[] name, A...)
> |{
> |  R mixin(name)(A a)
> |  {
> |    return d(a);
> |  }
> |}
> |
> |mixin foo!(int, "hello", int);
> |
> |void main()
> |{
> |  int i = hello(1);
> |}
> 
> the best I have come up with is a bit hackish and has a few "issues".
> 
> |template foo(R, char[] name, A...)
> |{
> |  R somthing(A a){return R.init;}
> |  mixin("alias somthing "~name~";");
> |}
> 
> If a clean solution for this were made and class level static foreach were to be implemented then auto implementation of an interface would be doable.
> 
> 

Building the whole thing as a string is probably the cleanest solution:

template make_func(char[] name) {
    mixin("void "~name~"() {}");
}

mixin make_func!("foo");

void main() {
    foo();
}

You can get rid of some of the ugliness of this approach by factoring out the function's implementation into another function, and calling the actual implementation inside the string.

void actual_impl() {}

template make_func(char[] name) {
    mixin("void "~name~"() {
        actual_impl();
    }");
}

mixin make_func!("foo");

void main() {
    foo();
}

Whether the function call overhead is worse than stuffing it all inside the string is of course up to you.

It is my strident hope that macros -- whenever we get them -- will make this particular trick obsolete.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org
July 24, 2007
Reply to Kirk,

> Building the whole thing as a string is probably the cleanest
> solution:
> 
> template make_func(char[] name) {
> mixin("void "~name~"() {}");
> }
> mixin make_func!("foo");
> 
> void main() {
> foo();
> }
>
> You can get rid of some of the ugliness of this approach by factoring
> out the function's implementation into another function, and calling
> the actual implementation inside the string.
>

that works (well in my case) but still seems hackish 

> Whether the function call overhead is worse than stuffing it all
> inside the string is of course up to you.
> 

In the case I'm thinking of that overhead is a drop in sea.


July 24, 2007
The other problem with the alias trick is that you can't alias a private member.  Which means that something like this doesn't work:

class Foo
{
    private char[] toStringImpl() { ... }
    version( Tango )
        alias toStringImpl toUtf8;
    else
        alias toStringImpl toString;
}

Which, of course, extends to string mixins.

	-- Daniel