March 01, 2009
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 had absolutely no idea that this could be used to generate symbol names that are illegal in D.

I don't think he's generating illegal symbol names. He's just sick of having to specify the whole function in a string when all he wants to change from instantiation to instantiation is the name...
March 02, 2009

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 had absolutely no idea that this could be used to generate symbol names that are illegal in D.
> 
> I don't think he's generating illegal symbol names. He's just sick of having to specify the whole function in a string when all he wants to change from instantiation to instantiation is the name...

/cookie fvbommel

  -- Daniel
March 03, 2009
On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep <daniel.keep.lists@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~`);
?

--bb
March 03, 2009

Bill Baxter wrote:
> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep <daniel.keep.lists@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.  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
March 03, 2009
On Tue, 03 Mar 2009 20:05:28 +1100, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>
>
>Bill Baxter wrote:
>> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep <daniel.keep.lists@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
March 03, 2009

Max Samukha wrote:
> On Tue, 03 Mar 2009 20:05:28 +1100, Daniel Keep <daniel.keep.lists@gmail.com> wrote:
> 
>>
>> Bill Baxter wrote:
>>> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep <daniel.keep.lists@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
March 03, 2009
On Tue, 03 Mar 2009 21:34:51 +1100, Daniel Keep <daniel.keep.lists@gmail.com> wrote:

>
>
>Max Samukha wrote:
>> On Tue, 03 Mar 2009 20:05:28 +1100, Daniel Keep <daniel.keep.lists@gmail.com> wrote:
>> 
>>>
>>> Bill Baxter wrote:
>>>> On Mon, Mar 2, 2009 at 11:55 AM, Daniel Keep <daniel.keep.lists@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.

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")() {}





March 06, 2009
Sean Kelly wrote:

>>>> Could also be that dmd is now alright, but libphobos.a isn't.
>>>> But as long as those two (MDT+SDK) are applied, it should be.
>>> Darnit... using 10.4 pthreads might be difficult.  Posix support was a
>>> tad weak on OSX until 10.5.  We'd have to version the library code on OS
>>> version, which would be a tad weird since Apple doesn't really support
>>> old versions of its OS anyway.
>> The pthread symbol is there, just not in the UNIX2003 variant.
>> So at this point it's just a linker issue, even if more behind.
> 
> Phew!  Better that than disabling features.

Rebuilding Phobos with MDT+SDK* makes it work on Mac OS X 10.4.

At least for DMD 1.04x and the basic things, which puts it on
par with the other compilers (GDC and LDC) and is OK with me...

Haven't done D2 for any of them yet, so that might be trickier.

--anders

* http://www.algonet.se/~afb/d/dmd-osx.diff (copied from dmd)
March 08, 2009
Anders F Björklund Wrote:
> Rebuilding Phobos with MDT+SDK* makes it work on Mac OS X 10.4.
> 
> At least for DMD 1.04x and the basic things, which puts it on par with the other compilers (GDC and LDC) and is OK with me...
> 
> Haven't done D2 for any of them yet, so that might be trickier.
> 
> --anders
> 
> * http://www.algonet.se/~afb/d/dmd-osx.diff (copied from dmd)

I just wanted to report that, since the DMD compiler itself does run on Tiger, I decided to try to use it with the latest Tango SVN, and it works great.  So far I've used DMD+Tango to build 2 fairly large projects on Tiger: wxD and gtkD

Next ›   Last »
1 2 3 4 5 6 7 8 9 10
Top | Discussion index | About this forum | D home