August 31, 2016
On Wednesday, 31 August 2016 at 08:36:37 UTC, Ethan Watson wrote:
> On Tuesday, 30 August 2016 at 22:24:12 UTC, Ali Çehreli wrote:
>> I don't agree with the current solution:
>
> I'm somewhat surprised myself that "allMembers doesn't return all members" needs highlighting.
>
> Why not have a new trait "allVisibleMembers" and just fix the privacy issues?

nice idea, but this doesn't change the fact that the traits that access the results of the "omniscient" allMember must be tweaked to access everything.
August 31, 2016
On Wednesday, 31 August 2016 at 09:25:52 UTC, Basile B. wrote:
> nice idea, but this doesn't change the fact that the traits that access the results of the "omniscient" allMember must be tweaked to access everything.

I'm okay with this. My PrivacyLevel workaround does exactly this in fact.

But I would like to be able to read (and write) all members of a class without needing to mixin a template and without having to resort to .tupleof. Use case here is the extensive struct use we have, if we want them to match C++ exactly then that's where mixins become potentially hairy.
August 31, 2016
On Wednesday, 31 August 2016 at 09:30:43 UTC, Ethan Watson wrote:
> I'm okay with this. My PrivacyLevel workaround does exactly this in fact.

I keep forgetting that I'm all open sourced now and can just link directly to the full example.

https://github.com/Remedy-Entertainment/binderoo/blob/master/binderoo_client/d/src/binderoo/objectprivacy.d
August 31, 2016
Ugh, it really should just give everything and have getMember bypass it. That won't even break any code!
August 31, 2016
On Wednesday, 31 August 2016 at 08:33:28 UTC, Ethan Watson wrote:
> That's how it used to work, but getProtection would fail if the symbol wasn't public. Which led to me using a workaround to something of this effect:

Yeah, I kinda regret the design of getProtection (which is basically 100% my fault, I implemented it myself and pushed it through without thinking about private - I was only interested in public vs export for my personal use case...), but if getMember worked on private things too, getProtection would never have to return inaccessible and it would be pretty again.
August 31, 2016
On Wednesday, 31 August 2016 at 13:12:30 UTC, Adam D. Ruppe wrote:
> Ugh, it really should just give everything and have getMember bypass it. That won't even break any code!

you're right. "allMembers" means "all" after all. Another reason why the idea of "allVisibleMembers" is good. Puristes will be able to use this traits without messing with "getProtection".
August 31, 2016
On Tuesday, August 30, 2016 15:24:12 Ali Çehreli via Digitalmars-d wrote:
> v2.071.2-b3 is bringing a change for this bug:
>
>    https://issues.dlang.org/show_bug.cgi?id=15907
>
> I don't agree with the current solution:
>
>    http://dlang.org/changelog/2.071.2.html#traits-members-visibility
>
> Modules should be able to use library templates without needing to mix them in first.

Agreed. Having to mix stuff in for introspection is downright ugly. It makes far more sense to provide everything and then check the attributes as discussed elsewhere in this thread.

IMHO, having allMembers give different results depending on access level is just plain broken.

I confess that I see no problem being able to examine symbols that are not accessible due to the access level. They just shouldn't be usable or be involved in overload sets. Looking at their declarations and attributes and whatnot should be fine.

- Jonathan M Davis


August 31, 2016
On 08/30/2016 03:24 PM, Ali Çehreli wrote:
> v2.071.2-b3 is bringing a change for this bug:
>
>   https://issues.dlang.org/show_bug.cgi?id=15907
>
> I don't agree with the current solution:
>
>   http://dlang.org/changelog/2.071.2.html#traits-members-visibility
>
> Modules should be able to use library templates without needing to mix
> them in first.
>
> Do you think the solution in the change log usable? I don't think so
> because silently skipping my private members is an unexpected behavior
> that will cause bugs.

Here is a regression caused by the above change:

interface I {
    void foo();

package:

    void foo(int);
}

string how(alias Base, alias func)() {
    return "";
}

import std.typecons;
class C : AutoImplement!(I, how) {
}

void main() {
    auto c = new C();
    c.foo();
    c.foo(42);    // COMPILATION ERROR:
// deneme.o: In function `_Dmain':
// deneme.d:(.text._Dmain+0x39): undefined reference to `_D6deneme1I3fooMFiZv'
// collect2: error: ld returned 1 exit status
}

WAT?

It's not reasonable for the user to somehow suspect that AutoImplement may be using a D feature (__traits(allMembers) in this case) which happens to not see foo(int). (Note that AutoImplement may see foo(int) today but not tomorrow, if it's moved out of this package.)

The recommended solution of mixing in every template instance is not a viable solution because that would effectively remove IFTI from D. What a huge loss that would be. We can't afford that.

So, to be safe, every D code out there that happens to pass a struct to a piece of library function would have to

1) Know that that library function happens to be a template and

2) mixin the particular instantiation of that template.

That would be the only sane thing to do. Further, what happens if a function changes its implementation and becomes a template that happens to call __traits(allMembers)? How can the library notify its users to tell them to mixin an explicit instantiation?

Ali

September 01, 2016
On Wednesday, 31 August 2016 at 13:29:52 UTC, Basile B. wrote:
> On Wednesday, 31 August 2016 at 13:12:30 UTC, Adam D. Ruppe wrote:
>> Ugh, it really should just give everything and have getMember bypass it. That won't even break any code!
>
> you're right. "allMembers" means "all" after all. Another reason why the idea of "allVisibleMembers" is good. Puristes will be able to use this traits without messing with "getProtection".

https://github.com/dlang/DIPs/pull/39

Co-authors welcome.
September 03, 2016
On Wednesday, 31 August 2016 at 05:33:50 UTC, ketmar wrote:
> all this mess should be resolved in compiler by assigning template *two* visibility scopes: one is template's "normal" scope (so it can see symbols from it's originating module), and second is it's "instantiation" scope. after all, this is exactly what programmer is exepecting. current solution is not a solution at all, it's a hacky workaround promoted to "official technique".

This would require a new instance for every template instantiation. The instantiation scope does not leak into the template by design, it allows us to cache instantiations and greatly speed up compilation.