On Tue, 03 Mar 2009 21:34:51 +1100, Daniel Keep <[email protected]> wrote:
> > >Max Samukha wrote: >> On Tue, 03 Mar 2009 20:05:28 +1100, Daniel Keep >> <[email protected]> wrote: >> >>> >>> Bill Baxter wrote: >>>> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep >>>> <[email protected]> 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. Yes, the mixin that checks for uniqueness needs to have access to the scope where it is instantiated. So it has to be mixed in directly or as part of another template mixin > 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 I didn't say it's a solution to this problem. I was saying it is possible to generate unique symbol names. Your problem could be solved like this: template Property(string name, T) { private T _prop; private T prop() { return _prop; } private T prop(T v) { _prop = v; return v; } mixin ("alias prop " ~ name ~ ";"); } class A { mixin Property!("foo", int); } class B : A { mixin Property!("bar", float); mixin Property!("baz", int); } void main() { auto b = new B; b.foo = 1; b.bar = 2.0; b.baz = 3; assert (b.foo == 1); assert (b.bar == 2.0); assert (b.baz == 3); } But such properties cannot implement interfaces. The spec says nothing about whether aliases should be able to implement interface functions, so I'm not sure if it's a compiler bug. Ok, I'm all for the ident() thing. Or probably 'mixin' can be reused? What ambiguities may arise? void mixin("foo")() {}
