September 03, 2016
On Tuesday, 30 August 2016 at 22:24:12 UTC, Ali Çehreli wrote:
> I can't wrap my head around the fact that a library template called by my module cannot see my private members.

Well, it was never possible to access them either, didn't seem to cause much confusion. Also getSymbolsByUDA is built on a hack around that access check https://github.com/dlang/phobos/blob/cb09746cb11bcbe7b730f05d29792e6252669175/std/traits.d#L6979.
Note that you can pass private symbols to templates, so `hasUDA!(S.invisible, UDA)` works fine.
I don't see any other examples where we'll have much issues with that change other than w/ this weird getSymbolsByUDA API, which aliases to !(S.field, S.func, S.Nested).
Most templates operating on wholes types already didn't have access to private members.
September 03, 2016
On Saturday, 3 September 2016 at 14:48:54 UTC, Martin Nowak wrote:
> 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.

just a wrapper class, which will hold the actual instantiation and a scope. most of the code should "pass thru" the wrapper (i thing that `alias this` can be used for that, but have to check it), yet `__traits` can use additional info. sure, that will require some work, but it's not that impossible, and should not ruin caching. yeah, we will waste additional 16/32 bytes per template instance this way. not that much, and it will solve the problem in most natural way.
September 03, 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!

It will, e.g. having getMember bypass protection means vibe.d would now serialize private members https://github.com/rejectedsoftware/vibe.d/blob/c1180791de61d0f8c9bfb584c2551a5b64627e32/source/vibe/internal/meta/traits.d#L146.
Until now getMember was just a DotIdExp (i.e. `T.indent`/`var.ident`), so it was used to test whether sth. can be accessed.
September 03, 2016
On Thursday, 1 September 2016 at 19:30:41 UTC, Basile B. wrote:
> https://github.com/dlang/DIPs/pull/39
>
> Co-authors welcome.

Slow down a bit until we've finally decided out how to resolve the problems.

September 03, 2016
On Saturday, 3 September 2016 at 15:48:24 UTC, ketmar wrote:
> just a wrapper class, which will hold the actual instantiation and a scope. most of the code should "pass thru" the wrapper (i thing that `alias this` can be used for that, but have to check it), yet `__traits` can use additional info. sure, that will require some work, but it's not that impossible, and should not ruin caching. yeah, we will waste additional 16/32 bytes per template instance this way. not that much, and it will solve the problem in most natural way.

Well, if you're making a difference based on the instantiation scope inside the template, then you're are leaking it into the template, do require a new instance for every instantiation, are ruining caching, do require unique mangling and redundant codegen.
We have mixin templates exactly for the purpose of instantiating them in the origin scope.
September 03, 2016
On Wednesday, 31 August 2016 at 21:12:54 UTC, Ali Çehreli wrote:
> 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) {
> }

What this derives a class in std.typecons that implements the interface, and yes such a derived class can't override/implement package protected methods.
AutoImplement would also work better as mixin in order to instantiate the passed in how template in the original instantiation scope.

>
> 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'

The missing interface method implementation should've give a compile error, please file a bug.

> 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.

Exaggeration won't help us to find good solutions. Remember that private fields never were accessible, so only some edge cases will be affected. The need for mixin templates will remain rare.
September 03, 2016
On 9/3/16, Martin Nowak via Digitalmars-d <digitalmars-d@puremagic.com> 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!
>
> It will, e.g. having getMember bypass protection means vibe.d would now serialize private members

Then just add a check in vibe.d itself to avoid serializing private members. You can still call getProtection on the symbol and skip serializing it.

Alternatively you can use UDAs so you can mark which fields should or
shouldn't be serializible. For example
https://github.com/msgpack/msgpack-d/blob/6046808c2e678e27cb2e2d9314241c361a6fd0ae/src/msgpack/attribute.d#L21

The bottom line is with restricting access to private symbols you have no choice on the matter, while allowing access lets you specialize whether to ignore the symbols or not.
September 03, 2016
On Tuesday, 30 August 2016 at 22:24:12 UTC, Ali Çehreli wrote:
> I don't agree with the current solution:

Well let's come up with a better solution then.
Let's start by finding some proper use-cases that require introspection on private members w/o having access to them.
September 03, 2016
On Saturday, 3 September 2016 at 16:52:50 UTC, Martin Nowak wrote:
> On Tuesday, 30 August 2016 at 22:24:12 UTC, Ali Çehreli wrote:
>> I don't agree with the current solution:
>
> Well let's come up with a better solution then.
> Let's start by finding some proper use-cases that require introspection on private members w/o having access to them.

In my user library, the serialization is based on the @Set and @Get UDAs. Typically there would be a setter (a public method) and no getter (i.e the data is read directly either from a protected or private variable).

The introspection is used to create a property descriptor. But because of the protection attributes I have to mix the introspection features (== a template) in each aggregate that declares properties and in each descendant class that declare new properties.



Class Foo
{
    mixin features f; // so that the private stuff are visible

private:
    @Get int _field;
public
    @Set void field(int value){}

    this()
    {f.analyze!Foo;}
}

class Bar: Foo
{
    mixin features f; // so that the private stuff are visible

private:
    @Get int _otherfield;
public
    @Set void otherfield(int value){}

    this()
    {f.analyze!Bar;}
}



while I could do, with the omniscient traits:



Class Foo
{
private:
    @Get int _field;
public
    @Set void field(int value){}

    this(this T)()
    {
        features.analyze!T;
    }
}

Class Bar: Foo
{
private:
    @Get int _otherfield;
public
    @Set void otherfield(int value){}
}

no need to re-mix the features for each derived class...



September 03, 2016
On 9/3/16 6:39 PM, Andrej Mitrovic via Digitalmars-d wrote:
> On 9/3/16, Martin Nowak via Digitalmars-d <digitalmars-d@puremagic.com> 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!
>>
>> It will, e.g. having getMember bypass protection means vibe.d
>> would now serialize private members
>
> Then just add a check in vibe.d itself to avoid serializing private
> members. You can still call getProtection on the symbol and skip
> serializing it.
>
> Alternatively you can use UDAs so you can mark which fields should or
> shouldn't be serializible. For example
> https://github.com/msgpack/msgpack-d/blob/6046808c2e678e27cb2e2d9314241c361a6fd0ae/src/msgpack/attribute.d#L21
>
> The bottom line is with restricting access to private symbols you have
> no choice on the matter, while allowing access lets you specialize
> whether to ignore the symbols or not.

I didn't follow this closely, but clearly we need some means to access private members for introspection purposes. I hope we don't paint ourselves out of that corner. -- Andrei