September 04, 2016
On 9/3/16 11:54 PM, Jacob Carlborg wrote:
> On 2016-09-03 22:40, Andrei Alexandrescu wrote:
>
>> That... doesn't sound good. I wonder how such important changes slip by
>> Walter and myself unnoticed.
>
> Here's the PR that introduced the change:
> https://github.com/dlang/dmd/pull/6078

Thanks. -- Andrei

September 04, 2016
On Saturday, 3 September 2016 at 20:40:57 UTC, Andrei Alexandrescu wrote:
> On 9/3/16 7:57 PM, Jonathan M Davis via Digitalmars-d wrote:
>> Previously __traits(allMembers, T) listed _all_ members, whereas now it wil
>> only list the ones that are accessible. The same for
>> __traits(derivedMembers, T). So, they'll still give you the private members
>> if you use them inside the module in question but not elsewhere.
>
> That... doesn't sound good. I wonder how such important changes slip by Walter and myself unnoticed.

It didn't slip, but I wish Walter had at least stated his opinion on the PR before merging.

> My thinking is that the plebes should be able to access things via the object.member syntax by obeying the usual visibility rules. But __traits(allMembers, T) should be the reflection backdoor that gives the savvy users total access, at the obvious cost of an awkward syntax.

As explained several times here and in the announce thread, private members have never been accessible, other than introspecting attributes, and making them accessible comes with a performance cost and a fairly big language change.
So the real question is, why do we need introspection without access, and can we handle that few cases with mixin templates.
If we really need introspection of private members than we might need to go back to the drawing board and modify the visibility concept introduced with DIP22.
September 04, 2016
On Sunday, 4 September 2016 at 03:14:18 UTC, Martin Nowak wrote:
>
> It didn't slip, but I wish Walter had at least stated his opinion on the PR before merging.
>
>> My thinking is that the plebes should be able to access things via the object.member syntax by obeying the usual visibility rules. But __traits(allMembers, T) should be the reflection backdoor that gives the savvy users total access, at the obvious cost of an awkward syntax.
>
> As explained several times here and in the announce thread, private members have never been accessible, other than introspecting attributes, and making them accessible comes with a performance cost and a fairly big language change.
> So the real question is, why do we need introspection without access, and can we handle that few cases with mixin templates.
> If we really need introspection of private members than we might need to go back to the drawing board and modify the visibility concept introduced with DIP22.

While I do understand, that there could be a potential performance when  private members could be changed around because they are not visible form outside.

I fail to see how we would take advantage of that without breaking our object-model.


September 04, 2016
On Saturday, 3 September 2016 at 17:57:08 UTC, Jonathan M Davis wrote:
> I do get the feeling that too much of what we do with features like this is ad-hoc without really designing things up front, and then we keep having to tweak stuff as we go along in ways that aren't always particularly nice.

That's not true, there was DIP22, and it explicitly mentions how traits should work.
The problem that was new and very hard to see, is that allowing traits to bypass visibility checks means we either can't replace access checks, must allow access of private members (w/ the cost tradeoffs mentioned in the announce thread), or come up with a different solution.
While it's fairly straightforward to skip visibility checks during traits lookups, I couldn't come up with a useful use-case while writing tests for that implementation, and after some more thought came up with the allMembers change.
September 04, 2016
On Sunday, 4 September 2016 at 03:21:05 UTC, Stefan Koch wrote:
> While I do understand, that there could be a potential performance when  private members could be changed around because they are not visible form outside.
>
> I fail to see how we would take advantage of that without breaking our object-model.

It's mostly about linkage of private methods.
September 04, 2016
On Saturday, 3 September 2016 at 17:23:53 UTC, Basile B. wrote:
> 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).

A public setter for private members is weird, but well. As a library template can't read private fields, you don't need the @Get attribute.

> The introspection is used to create a property descriptor.

What does that mean? You're creating a property in the serialised data?

Defining de-/serialize methods in the class/struct, e.g. with a mixin template would be the cleaner and more obvious approach IMO.
September 04, 2016
On Saturday, 3 September 2016 at 18:56:33 UTC, Dicebot wrote:
> Obviously serialization libraries come to mind, especially important for binary serialization because private members still affect the layout of the struct.

Let me repeat that another time, private members have never been accessible by traits. That's the main reasoning this change was based upon.
September 04, 2016
On Saturday, 3 September 2016 at 19:31:12 UTC, Jacob Carlborg wrote:
> That can usually be solved using .tupleof[i], but I agree.

Well, .tupleof gives you a typed representation of the memory layout, to me it's something different than qualified access of fields, just a safer mean to access memory. And sure you can always memcpy data.
Also introspection works on .tupleof, so it's not affected by the allMembers change and it's awkward to mix them b/c names and layout don't have a simple 1-to-1 relation.
September 04, 2016
On Sunday, 4 September 2016 at 03:45:50 UTC, Martin Nowak wrote:
> On Saturday, 3 September 2016 at 17:23:53 UTC, Basile B. wrote:
>> 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).
>
> A public setter for private members is weird, but well.

No in Object Pascal that's a common to have

    property Foo: string read fFoo write setFoo;

By the way there's an error from my part, in my lib it's @SetGet which gives access to private/protected field "directly".

> As a library template can't read private fields, you don't need the @Get attribute.
>
>> The introspection is used to create a property descriptor.
>
> What does that mean? You're creating a property in the serialised data?

The introspection creates a special structure for each property annotated with @Set, @Get, or @SetGet. This is a kind of interface for serialization/binding/object inspector (a bit like "published" in Object Pascal).

https://gist.github.com/BBasile/39fb66f7a0189660182cc637ab8d698b/archive/3e0f7441cfba89b5959b78eef63b9538d137a55a.zip (you can "dub a.d")

>
> Defining de-/serialize methods in the class/struct, e.g. with a mixin template would be the cleaner and more obvious approach IMO.

I see your strategy...each time someone will find an argument to make the traits omniscients you'll say, "no because it's cleaner to do like that" ?
September 04, 2016
Am Sun, 04 Sep 2016 03:29:59 +0000
schrieb Martin Nowak <code@dawg.eu>:

> On Sunday, 4 September 2016 at 03:21:05 UTC, Stefan Koch wrote:
> > While I do understand, that there could be a potential performance when  private members could be changed around because they are not visible form outside.
> >
> > I fail to see how we would take advantage of that without breaking our object-model.
> 
> It's mostly about linkage of private methods.

Allowing access to private fields / functions also means that
those members are part of the public API/ABI of a library. So changing
private members can break dependent libraries...