August 03, 2012
On Friday, 3 August 2012 at 22:47:52 UTC, David Nadlinger wrote:
> On Friday, 3 August 2012 at 22:23:23 UTC, Era Scarecrow wrote:
>> Seems like an ugly hack though (to get this done). Why not have another method of fullpathStringof or something similar? Then again if this is one of the few cases that could benefit from it, then maybe we should make it ugly so no one else will use it.
>
> This can't work in general. What should such a function return? The fully qualified name, I.e. including packages and modules? What is if the referred to entity is a nested function/local variable? What is if it is defined in a module which is not imported in the place where the string is mixed in?

 I would think, the exact 'text' of the way the variable was called, in my example it would be "inum.i", and since it would be at the local level (where the mixin was called) it should have access to everything that it did at that time.

> Regarding Philippe Sigaud's stuff: He has done a lot of great work, but exactly this use of strings is why some of his template constructions are not usable in the real world. Again, using .stringof in conjunction with string mixins is almost never a good idea. Please trust me on this, I've done quite a bit of metaprogramming-heavy projects, and there are always ways around this, which are often more elegant as well.

 I have limited experience making and using templates, so I'll have to believe you; But it still seems like there should be a much better way than an uber-ugly work around. One of the reasons I want to use an alias vs a string, is so I can use the constraints the way they are suppose to be.
August 03, 2012
On Friday, 3 August 2012 at 22:50:54 UTC, David Nadlinger wrote:
> On Friday, 3 August 2012 at 22:44:28 UTC, Andrej Mitrovic wrote:
>> In fact, this should really be put into Phobos so everyone can benefit rather than implementing this internally as a private template of bitmanip.
>
> No, it shouldn't be. There are almost no legit use cases for it, and having it in the library encourages abuse of string mixins/stringof in cases like this one.

 Then doesn't it seem like we're missing a potentially important piece of the puzzle for mixins and templates? very likely my modified template will include you including the same variable twice, but if someone gets lazy then it may not work.

 mixin(bitfieldsOn!("SomeVariable", SomeVariable, /*stuff*/));
 // or
 mixin(bitfieldsOn!("SomeVariable", variable type, /*stuff*/));

 But if it comes to it, what if they use auto or point to something else just to make it shut up? Constraints will let it pass but the code will pop up with errors that may not be reasonably readable.

 long l;
 float fl;
 mixin(bitfieldsOn!("fl", l, /*stuff*/)); //by name, typo or lazy
 //or
 mixin(bitfieldsOn!("fl", auto, /*stuff*/)); //explicit type, lazy or lying

 Now the checks pass but the compile code works wrong.

 True I can add asserts as part of the output code, but as mentioned hopefully the constraints could do that work, plus adding extra checks as part of a mixin seems a little...  excessive.

 Let's assume we use 'localStringof' or 'callingStringof' and that it returns the string of how the variable is called/referenced; Give me some examples how it would be abused or used wrongly? Aliased variables are pretty much perfect forwarded in templates (Unless my understanding is off) so they would carry that information forward.
August 04, 2012
Le 4 août 2012 00:50, "David Nadlinger" <see@klickverbot.at> a écrit :
>
> On Friday, 3 August 2012 at 22:23:23 UTC, Era Scarecrow wrote:
>>
>>  Seems like an ugly hack though (to get this done). Why not have another
method of fullpathStringof or something similar? Then again if this is one of the few cases that could benefit from it, then maybe we should make it ugly so no one else will use it.
>
>
> This can't work in general. What should such a function return? The fully
qualified name, i.e. including packages and modules? What is if the referred to entity is a nested function/local variable? What is if it is defined in a module which is not imported in the place where the string is mixed in?
>
> Regarding Philippe Sigaud's stuff: He has done a lot of great work, but
exactly this use of strings is why some of his template constructions are not usable in the real world. Again, using .stringof in conjunction with string mixins is almost never a good idea.

FWIW, I agree with David that using .stringof is a last resort and can lead to nasty bugs. .stringof has a sometime incoherent behavior (I remember it showing the entire code inside a delegate literal)

But then, the code shown upstream do *not* use .stringof.

It uses __traits(parent, ) and __traits(qualifier, ), which are much more
'modern' and well-behaved.

For std.reflection that Andrei proposed 2 weeks ago, I feel the internal code will contain many __traits() calls. Nothing to be done about it. __traits is *the* way compile-time introspection is done in D.


August 04, 2012
On Saturday, August 04, 2012 09:57:36 Philippe Sigaud wrote:
> For std.reflection that Andrei proposed 2 weeks ago, I feel the internal code will contain many __traits() calls. Nothing to be done about it. __traits is *the* way compile-time introspection is done in D.

That and std.traits. Between those two and the power of is expressions, that's where the ability to do compile-time introspection comes from.

- Jonathan M Davis
August 04, 2012
"Era Scarecrow" <rtcvb32@yahoo.com>

>  Then doesn't it seem like we're missing a potentially important piece of
the puzzle for mixins and templates? very likely my modified template will include you including the same variable twice, but if someone gets lazy then it may not work.
>
>  mixin(bitfieldsOn!("SomeVariable", SomeVariable, /*stuff*/));
>  // or
>  mixin(bitfieldsOn!("SomeVariable", variable type, /*stuff*/));

Hmm. You can ask for just the name as a string (so, qualified or not, as the user wish) and include a test for the type of the passed name.

inside bitfieldsOn:

    mixin("
static if is(typeof("~name~"))
        alias typeof(" ~ name ~ ") NameType;
    else
        static assert(false, `bad name given to bitfieldsOn:"~name~".`);
")

Untested, I'm on a pad right now.


August 04, 2012
On Saturday, 4 August 2012 at 08:06:31 UTC, Jonathan M Davis wrote:
> On Saturday, August 04, 2012 09:57:36 Philippe Sigaud wrote:
>> For std.reflection that Andrei proposed 2 weeks ago, I feel the internal
>> code will contain many __traits() calls. Nothing to be done about it.
>> __traits is *the* way compile-time introspection is done in D.
>
> That and std.traits. Between those two and the power of is expressions, that's
> where the ability to do compile-time introspection comes from.

There is nothing wrong about __traits, just about .stringof resp. __traits(identifier) in conjunction with string mixins.

David
August 04, 2012
On Saturday, 4 August 2012 at 07:57:46 UTC, Philippe Sigaud wrote:
> FWIW, I agree with David that using .stringof is a last resort and can lead to nasty bugs. .stringof has a sometime incoherent behavior (I remember it showing the entire code inside a delegate literal)

>
> But then, the code shown upstream do *not* use .stringof.
>
> It uses __traits(parent, ) and __traits(qualifier, ), which are much more 'modern' and well-behaved.

> For std.reflection that Andrei proposed 2 weeks ago, I feel the internal code will contain many __traits() calls. Nothing to be done about it. __traits is *the* way compile-time introspection is done in D.

 If traits will work, then that's what we go with. I've already got a workaround for what I need, a template creating a mixin, that you use a mixin on to make the bitfields; not pretty, but it will do the job; at least until a better option shows itself, preferably in a template in std.traits I can use and not go lower-level than I have to.

 Sorry if I've taken up unnecessary time.
August 04, 2012
On Saturday, 4 August 2012 at 07:57:46 UTC, Philippe Sigaud wrote:
> It uses __traits(parent, ) and __traits(qualifier, ), which are much more
> 'modern' and well-behaved.

An example of what I mean: Try this with your CurryTemplate from dranges:

---
import dranges.templates;

template Foo(A, B) {
    pragma(msg, A.stringof, " ", B.stringof);
}

alias CurryTemplate!Foo FooCurried;
alias FooCurried!int FooInt;
alias FooInt!string Test;
---

David
August 04, 2012
On Sat, Aug 4, 2012 at 10:25 AM, David Nadlinger <see@klickverbot.at> wrote:

> An example of what I mean: Try this with your CurryTemplate from dranges:
>
> ---
> import dranges.templates;
>
> template Foo(A, B) {
>     pragma(msg, A.stringof, " ", B.stringof);
> }
>
> alias CurryTemplate!Foo FooCurried;
> alias FooCurried!int FooInt;
> alias FooInt!string Test;

Oh, I completely forgot this. Nice code, if I may say so myself :)

But yes, having identifiers going back and forth between modules is
difficult. I didn't realize this in 2009, while most of dranges was
written.
Now, since I regularly need to have a template work on local
identifiers, I tend to use mixins much more than in dtemplates.
August 04, 2012
On Saturday, 4 August 2012 at 11:29:36 UTC, Philippe Sigaud wrote:
> Oh, I completely forgot this. Nice code, if I may say so myself :)

Huh? It's broken, precisely because of the use of __traits(identifier, …) in combination with string mixins. The example doesn't compile.

David