Re: Cannot access template name from within template

2016-10-03 Thread Jacob Carlborg via Digitalmars-d

On 2016-10-04 04:22, Michael Coulombe wrote:


You can also just do something like this, to search the upper/global scope:

alias A = SomethingCool!(.MyStruct);


Doesn't work for nested templates.

--
/Jacob Carlborg


Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 4 October 2016 at 14:40, Jonathan M Davis via Digitalmars-d
 wrote:
> [...]
> For that matter, even testing whether something is a variable is
> surprisingly difficult.

True story! I've written that one before... I spent ages trying to get it right!
When people say D is highly complex, these are the reasons. There are
a lot of edges, and some arbitrary corners where things just don't
work.
*mutter mutter* storage class *mutter mutter*


Re: Challenge

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Tuesday, October 04, 2016 14:24:59 Manu via Digitalmars-d wrote:
> On 4 October 2016 at 12:30, Jonathan M Davis via Digitalmars-d
>
>  wrote:
> > On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote:
> >> I'm feeling John's solution is a little bit simpler. But nice work,
> >> thanks!
> >
> > So, it is. LOL. I'd actually glanced over that post while I was in the
> > middle of getting my version to work, and I read it too quickly, because I
> > understood that it had just solved the property problem and that it didn't
> > work for all cases. I'll have to update my PR. Though his code does make
> > the mistake of doing
> >
> > mixin(`alias mem = T.` ~ member ~ `;`);
> >
> > rather than doing something like
> >
> > alias mem = AliasSeq!(__traits(getMember, T, member))[0];
> >
> > which means that there are some cases where it won't work properly. The
> > core logic is simpler though, which is definitely a plus.
>
> Make that change in your PR :)

I already updated it and was actually able to make it slightly simpler than
John's example (as far as I can tell, FunctionTypeOf is only needed in the
case where the address is taken).

> I think the PR is important. It's not obvious how to do this, and it's
> very useful. I was astonished it's not already there.

Yeah. I ran into a need for something similar recently, but my
implementation at the time wasn't as thorough, since it just used offsetof
to do the check (though in my case, I think that was enough). Getting it
completely right is surprisingly difficult.

I was also surprised that while we have quite a few __traits for functions,
they're severely lacking for variables (e.g. I was looking for the variable
equivalent of __traits(isStaticFunction, ...), and there is no such beast).
For that matter, even testing whether something is a variable is
surprisingly difficult.

- Jonathan M Davis



Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 4 October 2016 at 12:30, Jonathan M Davis via Digitalmars-d
 wrote:
> On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote:
>> I'm feeling John's solution is a little bit simpler. But nice work, thanks!
>
> So, it is. LOL. I'd actually glanced over that post while I was in the
> middle of getting my version to work, and I read it too quickly, because I
> understood that it had just solved the property problem and that it didn't
> work for all cases. I'll have to update my PR. Though his code does make the
> mistake of doing
>
> mixin(`alias mem = T.` ~ member ~ `;`);
>
> rather than doing something like
>
> alias mem = AliasSeq!(__traits(getMember, T, member))[0];
>
> which means that there are some cases where it won't work properly. The core
> logic is simpler though, which is definitely a plus.

Make that change in your PR :)
I think the PR is important. It's not obvious how to do this, and it's
very useful. I was astonished it's not already there.


Re: Challenge

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Tuesday, October 04, 2016 11:13:36 Manu via Digitalmars-d wrote:
> I'm feeling John's solution is a little bit simpler. But nice work, thanks!

So, it is. LOL. I'd actually glanced over that post while I was in the
middle of getting my version to work, and I read it too quickly, because I
understood that it had just solved the property problem and that it didn't
work for all cases. I'll have to update my PR. Though his code does make the
mistake of doing

mixin(`alias mem = T.` ~ member ~ `;`);

rather than doing something like

alias mem = AliasSeq!(__traits(getMember, T, member))[0];

which means that there are some cases where it won't work properly. The core
logic is simpler though, which is definitely a plus.

- Jonathan M Davis



Re: Cannot access template name from within template

2016-10-03 Thread Michael Coulombe via Digitalmars-d
On Tuesday, 4 October 2016 at 00:40:08 UTC, Andrei Alexandrescu 
wrote:

On 10/03/2016 06:32 PM, Stefan Koch wrote:
On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu 
wrote:

Consider:

template SomethingCool(alias X) { alias Y = X!int; }

struct MyStruct(T) {
alias A = SomethingCool!MyStruct;
}

Inside MyStruct though, a mention of the symbol MyStruct 
alone is
actually the current instantiation - i.e. a type, not a 
template.


Any known workaround?


Thanks,

Andrei


try defining an alias to template name outside of the template 
and use

that.
No guarantees.


Using std.traits.TemplateOf!MyStruct works like a charm. -- 
Andrei


You can also just do something like this, to search the 
upper/global scope:


alias A = SomethingCool!(.MyStruct);


Re: debugging mixins

2016-10-03 Thread Stefan Koch via Digitalmars-d

On Tuesday, 4 October 2016 at 01:20:01 UTC, Manu wrote:
On 4 October 2016 at 04:21, Stefan Koch via Digitalmars-d 
 wrote:
On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler 
wrote:




Yes, having the mixins expanded without the surrounding code 
would make it difficult to debug in some cases.  Maybe 
generating the entire source with the expanded mixins is 
another option?


mycode.d
obj/mycode_processed.d


That was my intention.


Maybe this idea could also be expanded to template 
instantiation?


 Oh yes. it is not that more much work :)


What case of template instantiation where there are no mixins 
involved
would this make significantly simpler to debug? (I don't know 
this is

a critical debugability problem as it is...)
Do you mean just substituting 'T' with actual types? resolving 
static

if's? Hard to know what it should do...

Actually, one case that often bites me is static-foreach 
unrolling.

That's borderline impossible to debug.
foreach(m; __traits(allMembers,T)) is the classic impossible to 
debug case.


static ifs are resolved when the compiler sees the 
template-instance in semantic3.
And that makes a huge difference in some cases where a template 
is generated by a string-mixin for example.


is not that big of a deal to print out unrolled static foreach.
(as in I can implement in the compiler within 2 days)



Re: debugging mixins

2016-10-03 Thread Manu via Digitalmars-d
On 4 October 2016 at 04:21, Stefan Koch via Digitalmars-d
 wrote:
> On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote:
>
>>
>> Yes, having the mixins expanded without the surrounding code would make it
>> difficult to debug in some cases.  Maybe generating the entire source with
>> the expanded mixins is another option?
>>
>> mycode.d
>> obj/mycode_processed.d
>
> That was my intention.
>>
>> Maybe this idea could also be expanded to template instantiation?
>
>  Oh yes. it is not that more much work :)

What case of template instantiation where there are no mixins involved
would this make significantly simpler to debug? (I don't know this is
a critical debugability problem as it is...)
Do you mean just substituting 'T' with actual types? resolving static
if's? Hard to know what it should do...

Actually, one case that often bites me is static-foreach unrolling.
That's borderline impossible to debug.
foreach(m; __traits(allMembers,T)) is the classic impossible to debug case.


Re: inout delegate

2016-10-03 Thread Manu via Digitalmars-d
On 4 October 2016 at 10:50, Timon Gehr via Digitalmars-d
 wrote:
> On 03.10.2016 05:06, Manu via Digitalmars-d wrote:
>>
>> Okay, well my current project is blocked on this. I can't progress.
>> https://issues.dlang.org/show_bug.cgi?id=16572
>
>
> Probably you can work around the issue using unsafe type casts.

Mmm, I'll see how much work it is to detect the case to do such a cast...


Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 4 October 2016 at 05:01, Jonathan M Davis via Digitalmars-d
 wrote:
> On Monday, October 03, 2016 11:13:52 Jonathan M Davis via Digitalmars-d wrote:
>> template isStaticMember(T, string member)
>> {
>> static if (!__traits(hasMember, T, member))
>> enum bool isStaticMember = false;
>> else
>> {
>> import std.meta : AliasSeq;
>> import std.traits : FunctionTypeOf;
>> alias sym = AliasSeq!(__traits(getMember, T, member))[0];
>>
>> static if (__traits(isStaticFunction, sym))
>> enum bool isStaticMember = true;
>> else static if (is(FunctionTypeOf!sym == function) &&
>> is(FunctionTypeOf!(typeof(&sym)) == function))
>> {
>> enum bool isStaticMember = false;
>> }
>> else
>> {
>> enum bool isStaticMember = !__traits(compiles, sym.offsetof) &&
>>__traits(compiles, &sym);
>> }
>> }
>> }
>
> Well, since I took the time to write it, I created a PR for it:
>
> https://github.com/dlang/phobos/pull/4834
>
> So, if anyone sees problems with my implementation, go poke holes in it.
>
> - Jonathan M Davis
>

I'm feeling John's solution is a little bit simpler. But nice work, thanks!


Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 4 October 2016 at 00:25, John Colvin via Digitalmars-d
 wrote:
> On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote:
>>
>> Fill in the blank...
>> I'm having a really hard time with this. I've made it work with a
>> mountain of code, and I want to see what others come up with...
>
>
> template isStaticMember(T, string member)
> {
> mixin(`alias mem = T.` ~ member ~ `;`);
> import std.traits : FunctionTypeOf;
> static if (is(FunctionTypeOf!mem == function) &&
> is(FunctionTypeOf!(typeof(&mem)) == function))
> enum bool isStaticMember = __traits(isStaticFunction, mem);
> else
> enum bool isStaticMember = is(typeof(&mem));
> }
>
> Basically, using FunctionTypeOf catches @property functions (which just
> typeof wouldn't), but it also catches member variables with function types,
> so we need the second FunctionTypeOf to see if it's still a function when
> you take its address (true for member functions, including @property
> functions, not true for member variables with function types).
>
> Everything else is just "can you take the address of this".

Very nice. This is the quality of solution I was looking for! 3 Significant LOC.
I knew a simple solution must exist. I didn't think of FunctionTypeOf.


Re: inout delegate

2016-10-03 Thread Timon Gehr via Digitalmars-d

On 03.10.2016 05:06, Manu via Digitalmars-d wrote:

Okay, well my current project is blocked on this. I can't progress.
https://issues.dlang.org/show_bug.cgi?id=16572


Probably you can work around the issue using unsafe type casts.


Re: Cannot access template name from within template

2016-10-03 Thread Andrei Alexandrescu via Digitalmars-d

On 10/03/2016 06:32 PM, Stefan Koch wrote:

On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu wrote:

Consider:

template SomethingCool(alias X) { alias Y = X!int; }

struct MyStruct(T) {
alias A = SomethingCool!MyStruct;
}

Inside MyStruct though, a mention of the symbol MyStruct alone is
actually the current instantiation - i.e. a type, not a template.

Any known workaround?


Thanks,

Andrei


try defining an alias to template name outside of the template and use
that.
No guarantees.


Using std.traits.TemplateOf!MyStruct works like a charm. -- Andrei


Re: Cannot access template name from within template

2016-10-03 Thread Stefan Koch via Digitalmars-d
On Monday, 3 October 2016 at 22:28:46 UTC, Andrei Alexandrescu 
wrote:

Consider:

template SomethingCool(alias X) { alias Y = X!int; }

struct MyStruct(T) {
alias A = SomethingCool!MyStruct;
}

Inside MyStruct though, a mention of the symbol MyStruct alone 
is actually the current instantiation - i.e. a type, not a 
template.


Any known workaround?


Thanks,

Andrei


try defining an alias to template name outside of the template 
and use that.

No guarantees.


Cannot access template name from within template

2016-10-03 Thread Andrei Alexandrescu via Digitalmars-d

Consider:

template SomethingCool(alias X) { alias Y = X!int; }

struct MyStruct(T) {
alias A = SomethingCool!MyStruct;
}

Inside MyStruct though, a mention of the symbol MyStruct alone is 
actually the current instantiation - i.e. a type, not a template.


Any known workaround?


Thanks,

Andrei


Re: Challenge

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Monday, October 03, 2016 11:13:52 Jonathan M Davis via Digitalmars-d wrote:
> template isStaticMember(T, string member)
> {
> static if (!__traits(hasMember, T, member))
> enum bool isStaticMember = false;
> else
> {
> import std.meta : AliasSeq;
> import std.traits : FunctionTypeOf;
> alias sym = AliasSeq!(__traits(getMember, T, member))[0];
>
> static if (__traits(isStaticFunction, sym))
> enum bool isStaticMember = true;
> else static if (is(FunctionTypeOf!sym == function) &&
> is(FunctionTypeOf!(typeof(&sym)) == function))
> {
> enum bool isStaticMember = false;
> }
> else
> {
> enum bool isStaticMember = !__traits(compiles, sym.offsetof) &&
>__traits(compiles, &sym);
> }
> }
> }

Well, since I took the time to write it, I created a PR for it:

https://github.com/dlang/phobos/pull/4834

So, if anyone sees problems with my implementation, go poke holes in it.

- Jonathan M Davis



Re: debugging mixins

2016-10-03 Thread Stefan Koch via Digitalmars-d

On Monday, 3 October 2016 at 15:23:40 UTC, Jonathan Marler wrote:



Yes, having the mixins expanded without the surrounding code 
would make it difficult to debug in some cases.  Maybe 
generating the entire source with the expanded mixins is 
another option?


mycode.d
obj/mycode_processed.d

That was my intention.
Maybe this idea could also be expanded to template 
instantiation?

 Oh yes. it is not that more much work :)



Re: Challenge

2016-10-03 Thread Ali Çehreli via Digitalmars-d

On 10/03/2016 07:41 AM, Seb wrote:

On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote:

Fill in the blank...
I'm having a really hard time with this. I've made it work with a
mountain of code, and I want to see what others come up with...

If you succeed, put it in std.traits!

Recommend, use latest DMD nightly. I find differences with latest
nightly vs release.


See also:

http://stackoverflow.com/questions/39430684/check-if-class-member-is-static


Appeared on dlang forum as well: :)

  http://forum.dlang.org/post/nni8lp$1ihk$1...@digitalmars.com

Ali



Re: Challenge

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Monday, October 03, 2016 08:38:22 Jonathan M Davis via Digitalmars-d wrote:
> On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote:
> > Fill in the blank...
> > I'm having a really hard time with this. I've made it work with a
> > mountain of code, and I want to see what others come up with...
>
> It's certainly possible that this misses something, but it passes all of
> your test cases:
>
> template isStaticMember(T, string member)
> {
> static if(!__traits(hasMember, T, member))
> enum bool isStaticMember = false;
> else
> {
> import std.meta : AliasSeq;
> import std.traits : FunctionTypeOf;
> alias sym = AliasSeq!(__traits(getMember, T, member))[0];
> static if(__traits(isStaticFunction, sym))
> enum bool isStaticMember = true;
> else static if(is(FunctionTypeOf!sym == function) &&
>is(FunctionTypeOf!(typeof(&sym)) == function))
> {
> enum bool isStaticMember = false;
> }
> else
> {
> enum bool isStaticMember = !__traits(compiles, sym.offsetof) &&
>!is(sym == enum) &&
>!is(sym == class) &&
>!is(sym == struct) &&
>__traits(compiles, &sym);
> }
> }
> }

Actually, it can be reduced even further:

template isStaticMember(T, string member)
{
static if (!__traits(hasMember, T, member))
enum bool isStaticMember = false;
else
{
import std.meta : AliasSeq;
import std.traits : FunctionTypeOf;
alias sym = AliasSeq!(__traits(getMember, T, member))[0];

static if (__traits(isStaticFunction, sym))
enum bool isStaticMember = true;
else static if (is(FunctionTypeOf!sym == function) &&
is(FunctionTypeOf!(typeof(&sym)) == function))
{
enum bool isStaticMember = false;
}
else
{
enum bool isStaticMember = !__traits(compiles, sym.offsetof) &&
   __traits(compiles, &sym);
}
}
}

Checking for the address makes it unnecessary to check for enums, classes,
or structs.

- Jonathan M Davis



Re: Pattern-matching qualifiers with is() expressions

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Monday, October 03, 2016 12:40:45 Andrei Alexandrescu via Digitalmars-d 
wrote:
> Am I doing something wrong? This is a fairly basic match, I'm surprised
> this hasn't surfaced yet:
>
> https://issues.dlang.org/show_bug.cgi?id=16581

My guess is that it hasn't been fined primarily because that version of an
is expression probably isn't used all that often. And if the problem is
qualifier-specific, then in order to hit the bug, someone would have to not
only use that specific version of an is expression, but they'd have to be
testing qualifiers with it as well. And I'd guess that that just isn't very
common. Not to mention, even if some code did hit it, depending on what the
it did, the bug might go unnoticed.

- Jonathan M Davis



Pattern-matching qualifiers with is() expressions

2016-10-03 Thread Andrei Alexandrescu via Digitalmars-d
Am I doing something wrong? This is a fairly basic match, I'm surprised 
this hasn't surfaced yet:


https://issues.dlang.org/show_bug.cgi?id=16581


Andrei


Re: ndslice: feature deprecation voting / discussion

2016-10-03 Thread Relja Ljubobratovic via Digitalmars-d

On Sunday, 2 October 2016 at 16:36:14 UTC, jmh530 wrote:

Wouldn't it be more flexible to allow both ways?

If D can handle the case without brackets without any issue, 
why force it?


In Matlab, writing ones(2, 2) produces a 2x2 matrix of ones.
In numpy, I would write np.ones((2, 2))

I find it annoying that in numpy I have to constantly remember 
to put in the second set of parentheses. This idea is basically 
forcing the same issue into ndslice. I think it's a bad idea.


I feel the same way. +1 here



Re: Challenge

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote:
> Fill in the blank...
> I'm having a really hard time with this. I've made it work with a
> mountain of code, and I want to see what others come up with...

It's certainly possible that this misses something, but it passes all of
your test cases:

template isStaticMember(T, string member)
{
static if(!__traits(hasMember, T, member))
enum bool isStaticMember = false;
else
{
import std.meta : AliasSeq;
import std.traits : FunctionTypeOf;
alias sym = AliasSeq!(__traits(getMember, T, member))[0];
static if(__traits(isStaticFunction, sym))
enum bool isStaticMember = true;
else static if(is(FunctionTypeOf!sym == function) &&
   is(FunctionTypeOf!(typeof(&sym)) == function))
{
enum bool isStaticMember = false;
}
else
{
enum bool isStaticMember = !__traits(compiles, sym.offsetof) &&
   !is(sym == enum) &&
   !is(sym == class) &&
   !is(sym == struct) &&
   __traits(compiles, &sym);
}
}
}

- Jonathan M Davis



Re: Challenge

2016-10-03 Thread Jonathan M Davis via Digitalmars-d
On Monday, October 03, 2016 23:19:19 Manu via Digitalmars-d wrote:
> Fill in the blank...
> I'm having a really hard time with this. I've made it work with a
> mountain of code, and I want to see what others come up with...
>
> If you succeed, put it in std.traits!
>
> Recommend, use latest DMD nightly. I find differences with latest
> nightly vs release.
>
> 
> --- template isStaticMember(T, string member)
> {
>   enum bool isStaticMember = [code goes here];
> }
>
>
> struct S
> {
>   enum X = 10;
>   enum Y
>   {
> i = 10
>   }
>   struct S {}
>   class C {}
>
>   static int x = 0;
>   __gshared int y = 0;
>   static void f() {}
>   static void f2() pure nothrow @nogc @safe {}
>
>   shared void g() {}
>
>   static void function() fp;
>   __gshared void function() gfp;
>   void function() fpm;
>
>   void m() {}
>   final void m2() const pure nothrow @nogc @safe {}
>
>   inout(int) iom() inout { return 10; }
>   static inout(int) iosf(inout int x) { return x; }
>
>   @property int p() { return 10; }
>   static @property int sp() { return 10; }
> }
>
> class C
> {
>   enum X = 10;
>   enum Y
>   {
> i = 10
>   }
>   struct S {}
>   class C {}
>
>   static int x = 0;
>   __gshared int y = 0;
>   static void f() {}
>   static void f2() pure nothrow @nogc @safe {}
>
>   shared void g() {}
>
>   static void function() fp;
>   __gshared void function() gfp;
>   void function() fpm;
>
>   void m() {}
>   final void m2() const pure nothrow @nogc @safe {}
>
>   inout(int) iom() inout { return 10; }
>   static inout(int) iosf(inout int x) { return x; }
>
>   @property int p() { return 10; }
>   static @property int sp() { return 10; }
> }
>
> static assert(!isStaticMember!(S, "X"), "!");
> static assert(!isStaticMember!(S, "Y"), "!");
> static assert(!isStaticMember!(S, "Y.i"), "!");
> static assert(!isStaticMember!(S, "S"), "!");
> static assert(!isStaticMember!(S, "C"), "!");
> static assert( isStaticMember!(S, "x"), "!");
> static assert( isStaticMember!(S, "y"), "!");
> static assert( isStaticMember!(S, "f"), "!");
> static assert( isStaticMember!(S, "f2"), "!");
> static assert(!isStaticMember!(S, "g"), "!");
> static assert( isStaticMember!(S, "fp"), "!");
> static assert( isStaticMember!(S, "gfp"), "!");
> static assert(!isStaticMember!(S, "fpm"), "!");
> static assert(!isStaticMember!(S, "m"), "!");
> static assert(!isStaticMember!(S, "m2"), "!");
> static assert(!isStaticMember!(S, "iom"), "!");
> static assert( isStaticMember!(S, "iosm"), "!");
> static assert(!isStaticMember!(S, "p"), "!");
> static assert( isStaticMember!(S, "sp"), "!");
>
> static assert(!isStaticMember!(C, "X"), "!");
> static assert(!isStaticMember!(C, "Y"), "!");
> static assert(!isStaticMember!(C, "Y.i"), "!");
> static assert(!isStaticMember!(C, "S"), "!");
> static assert(!isStaticMember!(C, "C"), "!");
> static assert( isStaticMember!(C, "x"), "!");
> static assert( isStaticMember!(C, "y"), "!");
> static assert( isStaticMember!(C, "f"), "!");
> static assert( isStaticMember!(C, "f2"), "!");
> static assert(!isStaticMember!(C, "g"), "!");
> static assert( isStaticMember!(C, "fp"), "!");
> static assert( isStaticMember!(C, "gfp"), "!");
> static assert(!isStaticMember!(C, "fpm"), "!");
> static assert(!isStaticMember!(C, "m"), "!");
> static assert(!isStaticMember!(C, "m2"), "!");
> static assert(!isStaticMember!(C, "iom"), "!");
> static assert( isStaticMember!(C, "iosm"), "!");
> static assert(!isStaticMember!(C, "p"), "!");
> static assert( isStaticMember!(C, "sp"), "!");

I would point out that iosm is missing from both the struct and the class,
so it can't be true for isStaticMember. I assume that you meant for it to be
iosf, which _is_ declared?

- Jonathan M Davis



Re: debugging mixins

2016-10-03 Thread Jonathan Marler via Digitalmars-d

On Sunday, 2 October 2016 at 03:36:31 UTC, Manu wrote:

This comes up a lot.
As far as I know, it's not solved. What shall we do?

I feel like a simple solution would be to have the compiler 
emit a _mixin.d file populated with all the mixin 
expansions beside the .obj files, and have the debuginfo refer 
to that fabricated source file?


It might look a little bit weird jumping into code where the 
surrounding scope is not visible (unless that were copied over 
too?), but it's better than what we have now.


Are there any other commonly proposed solutions?


Yes, having the mixins expanded without the surrounding code 
would make it difficult to debug in some cases.  Maybe generating 
the entire source with the expanded mixins is another option?


mycode.d
obj/mycode_processed.d

Maybe this idea could also be expanded to template instantiation?


Re: Challenge

2016-10-03 Thread Seb via Digitalmars-d

On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote:

Fill in the blank...
I'm having a really hard time with this. I've made it work with 
a

mountain of code, and I want to see what others come up with...

If you succeed, put it in std.traits!

Recommend, use latest DMD nightly. I find differences with 
latest nightly vs release.


See also:

http://stackoverflow.com/questions/39430684/check-if-class-member-is-static


Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 3 October 2016 at 23:48, Manu  wrote:
> On 3 October 2016 at 23:41, Manu  wrote:
>> I'm finding this rather annoying:
>>
>> struct S
>> {
>>   static @property int p() { return 10; }
>> }
>>
>> pragma(msg, typeof(&S.p)); // prints: int function() @property
>> pragma(msg, is(typeof(&S.p) == function)); // prints: false
>>
>> It looks like a function... but I can't identify it as a function!
>
> I guess that should read: is(typeof(&S.p) == R function(A), R, A...)) ??


Here's a leg-up:

template isStaticMember(T, string member)
{
  mixin("alias M = T." ~ member ~ ";");
  static if(__traits(compiles, &M))
  {
static if(!is(typeof(M) == function))
{
  static if(is(typeof(&M) == R function(A), R, A...))
  {
import std.traits : functionAttributes, FunctionAttribute;
enum isStaticMember = (functionAttributes!M &
FunctionAttribute.property) && /* distinguish static/non-static
@property somehow */ */;
  }
  else
enum isStaticMember = true;
}
else
{
  enum isStaticMember = __traits(isStaticFunction, M);
}
  }
  else
enum isStaticMember = false;
}


Re: Challenge

2016-10-03 Thread John Colvin via Digitalmars-d

On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote:

Fill in the blank...
I'm having a really hard time with this. I've made it work with 
a

mountain of code, and I want to see what others come up with...


template isStaticMember(T, string member)
{
mixin(`alias mem = T.` ~ member ~ `;`);
import std.traits : FunctionTypeOf;
static if (is(FunctionTypeOf!mem == function) && 
is(FunctionTypeOf!(typeof(&mem)) == function))
enum bool isStaticMember = __traits(isStaticFunction, 
mem);

else
enum bool isStaticMember = is(typeof(&mem));
}

Basically, using FunctionTypeOf catches @property functions 
(which just typeof wouldn't), but it also catches member 
variables with function types, so we need the second 
FunctionTypeOf to see if it's still a function when you take its 
address (true for member functions, including @property 
functions, not true for member variables with function types).


Everything else is just "can you take the address of this".


Re: Challenge

2016-10-03 Thread Temtaime via Digitalmars-d

On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote:

Fill in the blank...
I'm having a really hard time with this. I've made it work with 
a

mountain of code, and I want to see what others come up with...

[...]


Dere's a typo

static assert( isStaticMember!(S, "iosm"), "!");

Should be iosf

Easy:

template isStaticMember(T, string member)
{
static if(__traits(compiles, &__traits(getMember, T, member)))
{
		static if(is(FunctionTypeOf!(__traits(getMember, T, member)) == 
function))

{
			enum isStaticMember = isFunctionPointer!(__traits(getMember, 
T, member)) || isDelegate!(__traits(getMember, T, member)) || 
__traits(isStaticFunction, __traits(getMember, T, member));

}
else
{
			enum isStaticMember = true;//!is(typeof(__traits(getMember, T, 
member).offsetof));

}
}
else
{
enum isStaticMember = false;
}
}


Re: Challenge

2016-10-03 Thread Kagamin via Digitalmars-d

On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote:

I'm finding this rather annoying:

struct S
{
  static @property int p() { return 10; }
}

pragma(msg, typeof(&S.p)); // prints: int function() @property
pragma(msg, is(typeof(&S.p) == function)); // prints: false

It looks like a function... but I can't identify it as a 
function!


https://dlang.org/phobos/std_traits.html#isSomeFunction ?


Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 3 October 2016 at 23:50, John Colvin via Digitalmars-d
 wrote:
> On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote:
>>
>> I'm finding this rather annoying:
>>
>> struct S
>> {
>>   static @property int p() { return 10; }
>> }
>>
>> pragma(msg, typeof(&S.p)); // prints: int function() @property
>> pragma(msg, is(typeof(&S.p) == function)); // prints: false
>>
>> It looks like a function... but I can't identify it as a function!
>
>
> The problem is that function pointers in "is" expressions don't match
> "function" or "delegate".
>
> static assert (is(void delegate() == delegate)); //passes
> static assert (is(void function() == function)); //fails
> static assert (is(void function() == delegate)); //fails
>
> Bug report?

Nar, I just forgot about this well-known edge. 'function' means
something different in is(); it means a proper-function, *not* a
function pointer. if(X == R function(A), R, A...) will test for
function pointers.
It's still hard though, @property's are hard to detect, and I am
really struggling to distinguish between static and non-static
properties without testing for assignments, which is terrible.


Re: Challenge

2016-10-03 Thread Dicebot via Digitalmars-d

On Monday, 3 October 2016 at 13:50:26 UTC, John Colvin wrote:
The problem is that function pointers in "is" expressions don't 
match "function" or "delegate".


static assert (is(void delegate() == delegate)); //passes
static assert (is(void function() == function)); //fails
static assert (is(void function() == delegate)); //fails

Bug report?


Note that there is at least some code that relies on current 
behavior to distinguish delegate/function fields from method 
declarations in aggregates.


Re: Challenge

2016-10-03 Thread Dicebot via Digitalmars-d

On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote:

I'm finding this rather annoying:

struct S
{
  static @property int p() { return 10; }
}

pragma(msg, typeof(&S.p)); // prints: int function() @property
pragma(msg, is(typeof(&S.p) == function)); // prints: false

It looks like a function... but I can't identify it as a 
function!



It works if both:

a) you remove @property
b) you don't convert it to function pointer

struct S
{
   static int p() { return 10; }
}

pragma(msg, is(typeof(S.p) == function); // true

Sadly `is(X == function)` is very obscure and confusing because 
it doesn't do what one may expect it to do. In current form it 
can only be used if something is a function declaration, 
everything else is `false`. It is not even possible to manually 
express a type which will pass `is(T == function)`, you can only 
get `true` by applying `typeof` to existing function declaration.


And @property screws it because the only current effect of 
property is exactly changing result of `typeof(propertyFoo)` from 
function type to result type.


Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
On 3 October 2016 at 23:41, Manu  wrote:
> I'm finding this rather annoying:
>
> struct S
> {
>   static @property int p() { return 10; }
> }
>
> pragma(msg, typeof(&S.p)); // prints: int function() @property
> pragma(msg, is(typeof(&S.p) == function)); // prints: false
>
> It looks like a function... but I can't identify it as a function!

I guess that should read: is(typeof(&S.p) == R function(A), R, A...)) ??


Re: Challenge

2016-10-03 Thread John Colvin via Digitalmars-d

On Monday, 3 October 2016 at 13:41:13 UTC, Manu wrote:

I'm finding this rather annoying:

struct S
{
  static @property int p() { return 10; }
}

pragma(msg, typeof(&S.p)); // prints: int function() @property
pragma(msg, is(typeof(&S.p) == function)); // prints: false

It looks like a function... but I can't identify it as a 
function!


The problem is that function pointers in "is" expressions don't 
match "function" or "delegate".


static assert (is(void delegate() == delegate)); //passes
static assert (is(void function() == function)); //fails
static assert (is(void function() == delegate)); //fails

Bug report?


Re: Challenge

2016-10-03 Thread Andrea Fontana via Digitalmars-d

On Monday, 3 October 2016 at 13:19:19 UTC, Manu wrote:

Fill in the blank...
I'm having a really hard time with this. I've made it work with 
a

mountain of code, and I want to see what others come up with...

If you succeed, put it in std.traits!


Pretty easy:
template isStaticMember(T, string member)
{
  enum bool isStaticMember =
	!(member=="X" || member=="Y" || member=="Y.i"  || member=="S"  
|| member=="C" ||
	member=="g"  || member=="fpm" || member=="m" || member=="m2" || 
member=="iom"  || member=="p");

}

Ok, I'm joking.




Re: Challenge

2016-10-03 Thread Manu via Digitalmars-d
I'm finding this rather annoying:

struct S
{
  static @property int p() { return 10; }
}

pragma(msg, typeof(&S.p)); // prints: int function() @property
pragma(msg, is(typeof(&S.p) == function)); // prints: false

It looks like a function... but I can't identify it as a function!


Challenge

2016-10-03 Thread Manu via Digitalmars-d
Fill in the blank...
I'm having a really hard time with this. I've made it work with a
mountain of code, and I want to see what others come up with...

If you succeed, put it in std.traits!

Recommend, use latest DMD nightly. I find differences with latest
nightly vs release.

---
template isStaticMember(T, string member)
{
  enum bool isStaticMember = [code goes here];
}


struct S
{
  enum X = 10;
  enum Y
  {
i = 10
  }
  struct S {}
  class C {}

  static int x = 0;
  __gshared int y = 0;
  static void f() {}
  static void f2() pure nothrow @nogc @safe {}

  shared void g() {}

  static void function() fp;
  __gshared void function() gfp;
  void function() fpm;

  void m() {}
  final void m2() const pure nothrow @nogc @safe {}

  inout(int) iom() inout { return 10; }
  static inout(int) iosf(inout int x) { return x; }

  @property int p() { return 10; }
  static @property int sp() { return 10; }
}

class C
{
  enum X = 10;
  enum Y
  {
i = 10
  }
  struct S {}
  class C {}

  static int x = 0;
  __gshared int y = 0;
  static void f() {}
  static void f2() pure nothrow @nogc @safe {}

  shared void g() {}

  static void function() fp;
  __gshared void function() gfp;
  void function() fpm;

  void m() {}
  final void m2() const pure nothrow @nogc @safe {}

  inout(int) iom() inout { return 10; }
  static inout(int) iosf(inout int x) { return x; }

  @property int p() { return 10; }
  static @property int sp() { return 10; }
}

static assert(!isStaticMember!(S, "X"), "!");
static assert(!isStaticMember!(S, "Y"), "!");
static assert(!isStaticMember!(S, "Y.i"), "!");
static assert(!isStaticMember!(S, "S"), "!");
static assert(!isStaticMember!(S, "C"), "!");
static assert( isStaticMember!(S, "x"), "!");
static assert( isStaticMember!(S, "y"), "!");
static assert( isStaticMember!(S, "f"), "!");
static assert( isStaticMember!(S, "f2"), "!");
static assert(!isStaticMember!(S, "g"), "!");
static assert( isStaticMember!(S, "fp"), "!");
static assert( isStaticMember!(S, "gfp"), "!");
static assert(!isStaticMember!(S, "fpm"), "!");
static assert(!isStaticMember!(S, "m"), "!");
static assert(!isStaticMember!(S, "m2"), "!");
static assert(!isStaticMember!(S, "iom"), "!");
static assert( isStaticMember!(S, "iosm"), "!");
static assert(!isStaticMember!(S, "p"), "!");
static assert( isStaticMember!(S, "sp"), "!");

static assert(!isStaticMember!(C, "X"), "!");
static assert(!isStaticMember!(C, "Y"), "!");
static assert(!isStaticMember!(C, "Y.i"), "!");
static assert(!isStaticMember!(C, "S"), "!");
static assert(!isStaticMember!(C, "C"), "!");
static assert( isStaticMember!(C, "x"), "!");
static assert( isStaticMember!(C, "y"), "!");
static assert( isStaticMember!(C, "f"), "!");
static assert( isStaticMember!(C, "f2"), "!");
static assert(!isStaticMember!(C, "g"), "!");
static assert( isStaticMember!(C, "fp"), "!");
static assert( isStaticMember!(C, "gfp"), "!");
static assert(!isStaticMember!(C, "fpm"), "!");
static assert(!isStaticMember!(C, "m"), "!");
static assert(!isStaticMember!(C, "m2"), "!");
static assert(!isStaticMember!(C, "iom"), "!");
static assert( isStaticMember!(C, "iosm"), "!");
static assert(!isStaticMember!(C, "p"), "!");
static assert( isStaticMember!(C, "sp"), "!");


Re: debugging mixins

2016-10-03 Thread Andrei Alexandrescu via Digitalmars-d

On 10/03/2016 07:42 AM, Stefan Koch wrote:

On Sunday, 2 October 2016 at 12:27:23 UTC, Andrei Alexandrescu wrote:


Yes, Stefan it would be terrific if you could keep an eye on it while
working on the engine. A file with properly handed dependencies could
serve as instantiation cache and save a ton of re-instantiation waste.
Thanks! -- Andrei


instantiation ?
Do you mean mixin-expansion ?
or are you talking about mixins created in templates ?


Mixin expansions.


Although Caching mixin expansions hits on the same problem as chaching
template-instances, it is more difficult since a mixin can appear anywhere.
and one has to worry about a much wider scope.

I'll see what I can come up with, for now the debugging is priority.
@Ethan can you share code illustrating your usecase.
(My head is inside compiler internals and building test-code is a rather
unpleasant context switch)


Understood, then keep this on the back burner and forge ahead with the 
warm cache. Thanks! -- Andrei


Re: ndslice: feature deprecation voting / discussion

2016-10-03 Thread Andrei Alexandrescu via Digitalmars-d

On 10/02/2016 11:01 PM, Manu via Digitalmars-d wrote:

Ah, the 'sufficiently high-quality compiler' unicorn. It's been a
legend in C++ for at least 20 years that I've been looking...


For this particular matter it's somewhat of a solved problem in C++. Is 
it your perception as well that template bloat in C++ seems to have 
discussed a lot more in the past than in recent times? -- Andrei


Re: debugging mixins

2016-10-03 Thread Ethan Watson via Digitalmars-d

On Monday, 3 October 2016 at 11:42:25 UTC, Stefan Koch wrote:

@Ethan can you share code illustrating your usecase.
(My head is inside compiler internals and building test-code is 
a rather unpleasant context switch)


You should be able to do everything with the example code you 
have. My intention there is to compile everything in the 
acorelibrary module in to a library and statically link against 
that. As such, you'll want to do the .di generation on those 
files. The behaviour right now is that all the Binderoo mixins 
will not expand.


Re: debugging mixins

2016-10-03 Thread Stefan Koch via Digitalmars-d
On Sunday, 2 October 2016 at 12:27:23 UTC, Andrei Alexandrescu 
wrote:


Yes, Stefan it would be terrific if you could keep an eye on it 
while working on the engine. A file with properly handed 
dependencies could serve as instantiation cache and save a ton 
of re-instantiation waste. Thanks! -- Andrei


instantiation ?
Do you mean mixin-expansion ?
or are you talking about mixins created in templates ?

Although Caching mixin expansions hits on the same problem as 
chaching template-instances, it is more difficult since a mixin 
can appear anywhere.

and one has to worry about a much wider scope.

I'll see what I can come up with, for now the debugging is 
priority.

@Ethan can you share code illustrating your usecase.
(My head is inside compiler internals and building test-code is a 
rather unpleasant context switch)


Re: inout delegate

2016-10-03 Thread David Nadlinger via Digitalmars-d

On Monday, 3 October 2016 at 02:47:09 UTC, Manu wrote:

On 3 October 2016 at 02:37, Timon Gehr via Digitalmars-d
This is a known issue: 
https://issues.dlang.org/show_bug.cgi?id=3720


(What I do is: typeof(&typeof(this).f) is int delegate(), but 
auto x = &f

does not compile as the 'this' reference is missing.)


It compiles for me... (using yesterday's nightly)
I pasted it right from my code.


It wouldn't compile using Timon's frontend, which was his point.

 — David


Re: inout delegate

2016-10-03 Thread Manu via Digitalmars-d
On 3 October 2016 at 17:18, Jacob Carlborg via Digitalmars-d
 wrote:
> On 2016-10-03 05:06, Manu via Digitalmars-d wrote:
>
>> Okay, well my current project is blocked on this. I can't progress.
>> https://issues.dlang.org/show_bug.cgi?id=16572
>
>
> I You can remove "inout" ;)

That just makes a different problem, ie, the one that requires it to
be inout in the first place.


Re: inout delegate

2016-10-03 Thread Jacob Carlborg via Digitalmars-d

On 2016-10-03 05:06, Manu via Digitalmars-d wrote:


Okay, well my current project is blocked on this. I can't progress.
https://issues.dlang.org/show_bug.cgi?id=16572


I You can remove "inout" ;)

--
/Jacob Carlborg