Just one more thing...
Daniel Keep
daniel.keep.lists at gmail.com
Tue Mar 3 02:34:51 PST 2009
Max Samukha wrote:
> On Tue, 03 Mar 2009 20:05:28 +1100, Daniel Keep
> <daniel.keep.lists at gmail.com> wrote:
>
>>
>> Bill Baxter wrote:
>>> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep
>>> <daniel.keep.lists at gmail.com> wrote:
>>>> Frits van Bommel wrote:
>>>>> Sean Kelly wrote:
>>>>>> Daniel Keep wrote:
>>>>>>> extern(C) void __identifier("blah$UNIX2003")(int);
>>>>>> That would be awesome.
>>>>>>
>>>>>>> A beneficial side-effect is that I can finally get rid of all those
>>>>>>> mixins that are just doing this:
>>>>>>>
>>>>>>> mixin(`void `~name_of_fn~`(int a)
>>>>>>> {
>>>>>>> // ... rest of function ...
>>>>>>> }`);
>>> I'm sure you've thought of this, so why can you not do
>>> mixin(`void `~name_of_fn~`(int a) { implementation_of_function(a); }`);
>>> or
>>> mixin(`alias implementation_of_function `~name_of_fn~`);
>> Simple enough to break:
>>
>> mixin(Property("foo", int));
>> mixin(Property("bar", float));
>>
>> You can't use alias. You have to have some way of generating unique
>> symbol names in a context you don't have any control over.
>
> As of 1.039, it seems to be possible to generate unique symbols in a
> reasonable way (not well tested):
>
> template UniqueAlias(string member, string idName, int id = 0)
> {
> static if (is(typeof(mixin("this." ~ idName ~ ToString!(id)))))
> mixin UniqueAlias!(member, idName, id + 1);
> else
> mixin("alias " ~ member ~ " " ~ idName ~ ToString!(id) ~ ";");
> }
>
> unittest
> {
> class A
> {
> int x;
> }
>
> class B : A
> {
> int y;
> void foo() {}
>
> template Bar() {}
>
> mixin UniqueAlias!("x", "m");
> mixin UniqueAlias!("y", "m");
> mixin UniqueAlias!("x", "m");
> mixin UniqueAlias!("foo", "m");
> mixin UniqueAlias!("Bar", "m");
> }
>
> auto s = new B;
> s.m0 = 1;
> s.m1 = 2;
> assert(s.x == 1);
> assert(s.y == 2);
> assert(s.m2 == 1);
> s.m3();
> alias B.m4!() bar;
> }
>
>> There are also little issues with this like how the name of the function, when
>> debugging, won't be what you expect it to be.
>>
>> No, you can't use templates because you can't mixin functions with
>> non-public protection with templates.
>>
>> -- Daniel
Yes, this is definitely an improvement...
char[] Foo(char[] name)
{
const char[] uid = createUniqueAlias(name);
return
`private void `~uid~`() { blah; }`
~ `private alias `~uid~` `~name~`;`;
}
class Bar
{
mixin(Foo("baz"));
}
Wait, no; that won't work. createUniqueAlias won't have access to the
enclosing scope. I'll have to do this:
char[] Foo(char[] name)
{
return `
mixin CreateUniqueAlias!("uid");
mixin("private void "~uid~"() { blah; }");
mixin("private alias "~uid~" `~name`;");
`;
}
class Bar
{
mixin(Foo("baz"));
}
Now I get TWO string-escaped mixins AND a meaninglessly named function
mixed into my instantiating code's scope! Plus, since I need to refer
to the unique name, I have to store it somewhere... and now THAT can
collide with other symbols!
I'm not saying it's not a neat trick; I've used the exact same thing a
few times. But it's not a solution to *this* problem.
-- Daniel
More information about the Digitalmars-d-announce
mailing list