September 04, 2016
On 9/4/16 11:09 AM, Martin Nowak 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:
>> 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.
>
> Still haven't heard really good use cases for the above, but the
> trade-offs for also allowing access to private members aren't that bad,
> thus it seems like the better path forward.
> See http://forum.dlang.org/post/ymkehalxcigswvltlfjj@forum.dlang.org

There are a few cases I can think of:

* Serialization and deserialization, shallow and deep. These would need access to the object layout, and possibly field names too (for cross-checking and versioning purposes).

* Binary saving, loading, and fixup (a subset of serialization/deserialization) - that thing when you copy raw memory to a file and then load it raw and fix pointers up.

* Memory management and garbage collection: access to field types allows efficient generic tracing.

* Database interfacing, automated binding, object-relational mapping, etc. It stands to reason that field names would be needed and fields would be private, yet the database loader does have access to them.

Of course the more important applications are those I can't yet imagine. The way I see it introspection must have full power and unfettered access. So definitely it must be able to pass through regular protection.


Andrei
September 04, 2016
On 9/4/16 5:45 AM, Martin Nowak wrote:
> A public setter for private members is weird

How do you mean that? It's an absolute classic. Please elaborate, thanks. -- Andrei
September 04, 2016
On 9/4/16 2:37 PM, David Nadlinger wrote:
> On Sunday, 4 September 2016 at 12:33:07 UTC, Andrei Alexandrescu wrote:
>> Thanks for answering. Yes, we really need introspection of private
>> members. One way or another we need to support that.
>
> Do we, though? It's easy to state a general claim like this, but I find
> it hard to actually justify.

Static introspection is by far the most powerful feature of D. The last thing to do with it is hamstring it with nonsense like private :o).

Quoting elsethread:

> There are a few cases I can think of:
>
> * Serialization and deserialization, shallow and deep. These would need access to the object layout, and possibly field names too (for cross-checking and versioning purposes).
>
> * Binary saving, loading, and fixup (a subset of serialization/deserialization) - that thing when you copy raw memory to a file and then load it raw and fix pointers up.
>
> * Memory management and garbage collection: access to field types allows efficient generic tracing.
>
> * Database interfacing, automated binding, object-relational mapping, etc. It stands to reason that field names would be needed and fields would be private, yet the database loader does have access to them.
>
> Of course the more important applications are those I can't yet imagine. The way I see it introspection must have full power and unfettered access. So definitely it must be able to pass through regular protection.


Andrei
September 05, 2016
On Sunday, 4 September 2016 at 12:51:05 UTC, Andrei Alexandrescu wrote:
>> See http://forum.dlang.org/post/ymkehalxcigswvltlfjj@forum.dlang.org
>
> There are a few cases I can think of:

The classical ones, but again the question was for introspection without access (b/c named access through getMember was never allowed, only .tupleof).
As the trade-offs for allowing access to private members don't seem that bad, we'll now try to go in the other direction, skipping visibility checks now and removing the access checks in a later release.
September 05, 2016
Am Sun, 4 Sep 2016 14:54:33 +0200
schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:

> On 9/4/16 2:37 PM, David Nadlinger wrote:
> > On Sunday, 4 September 2016 at 12:33:07 UTC, Andrei Alexandrescu wrote:
> >> Thanks for answering. Yes, we really need introspection of private members. One way or another we need to support that.
> >
> > Do we, though? It's easy to state a general claim like this, but I find it hard to actually justify.
> 
> Static introspection is by far the most powerful feature of D. The last thing to do with it is hamstring it with nonsense like private :o).
> 
> Quoting elsethread:
> 
> > There are a few cases I can think of:
> >
> > * Serialization and deserialization, shallow and deep. These would need access to the object layout, and possibly field names too (for cross-checking and versioning purposes).
> >
> > * Binary saving, loading, and fixup (a subset of serialization/deserialization) - that thing when you copy raw memory to a file and then load it raw and fix pointers up.
> >
> > * Memory management and garbage collection: access to field types allows efficient generic tracing.
> >
> > * Database interfacing, automated binding, object-relational mapping, etc. It stands to reason that field names would be needed and fields would be private, yet the database loader does have access to them.
> >
> > Of course the more important applications are those I can't yet imagine. The way I see it introspection must have full power and unfettered access. So definitely it must be able to pass through regular protection.
> 
> 
> Andrei

All these examples need access to private data fields only.
Most performance optimizations are only possible for private functions
anyway. So is there a use case to access/call private functions?
September 05, 2016
On Monday, 5 September 2016 at 07:48:11 UTC, Johannes Pfau wrote:
> Am Sun, 4 Sep 2016 14:54:33 +0200
> schrieb Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org>:
>
>> On 9/4/16 2:37 PM, David Nadlinger wrote:
>> > [...]
>> 
>> Static introspection is by far the most powerful feature of D. The last thing to do with it is hamstring it with nonsense like private :o).
>> 
>> Quoting elsethread:
>> 
>> > [...]
>> 
>> 
>> Andrei
>
> All these examples need access to private data fields only.
> Most performance optimizations are only possible for private functions
> anyway. So is there a use case to access/call private functions?

One use case would be accessing UDA on private fields, to inspect which fields need to be injected with a dependency, in aggregate type, just like spring from java does with autowire annotation. You mark a private field with autowired, and spring calls associated setter for the field.

Does tupleof allow access to associated UDAs of contained fields, as well field names?
September 05, 2016
On 2016-09-04 14:36, Andrei Alexandrescu wrote:

> Yah, .tupleof is great to have. I think that should be enough for most
> introspection needs. Only the field names are missing, can those be
> accessed somehow? -- Andrei

Yes:

module foo;

struct Foo
{
    private int a;
}

module main;

import foo;
static assert(__traits(identifier, Foo.tupleof[0]) == "a");

-- 
/Jacob Carlborg
September 05, 2016
On 2016-09-04 14:51, Andrei Alexandrescu wrote:

> Of course the more important applications are those I can't yet imagine.
> The way I see it introspection must have full power and unfettered
> access. So definitely it must be able to pass through regular protection.

* Linking up GUI controls to instance variables in the code, like Xcode/Interface Builder

-- 
/Jacob Carlborg
September 05, 2016
On 9/5/16 10:38 AM, Jacob Carlborg wrote:
> On 2016-09-04 14:36, Andrei Alexandrescu wrote:
>
>> Yah, .tupleof is great to have. I think that should be enough for most
>> introspection needs. Only the field names are missing, can those be
>> accessed somehow? -- Andrei
>
> Yes:
>
> module foo;
>
> struct Foo
> {
>     private int a;
> }
>
> module main;
>
> import foo;
> static assert(__traits(identifier, Foo.tupleof[0]) == "a");

Thank you. This is good news. -- Andrei

September 06, 2016
On 09/04/2016 05:37 AM, David Nadlinger wrote:
> On Sunday, 4 September 2016 at 12:33:07 UTC, Andrei Alexandrescu wrote:
>> Thanks for answering. Yes, we really need introspection of private
>> members. One way or another we need to support that.
>
> Do we, though? It's easy to state a general claim like this, but I find
> it hard to actually justify.
>
>  — David

Let me try to reword what I've already said elsewhere in this thread.

As the user of a library I shouldn't need to know whether a template of that library uses __traits(allMembers) or not. Unfortunately, if __traits(allMembers) depends on access rights, I am forced to mixin *every* template in my code because I don't and should not know the template's implementation. If I don't know their implementation, I have to prepare myself for the worst and mixin *every* template. That's insanity.

Even if I know that they don't use __traits(allMembers) today, they may change their implementation in the future. So, I really have to mixin every template today.

Further, I have to be on my toes and watch every feature of every library in case they changed e.g. a function to a function template in a new release. Oh yes, I have to mixin that new template as well! (Again, because I can't be sure whether they use __traits(allMembers) or not.)

This new behavior and its mixin workaround is so insane to me that I can't even find ways to spell it out clearly. This behavior kills IFTI altogether because I don't know who uses __traits(allMembers). I can't rely on IFTI. I have to mixin every template instantiation myself. Crazy.

Ali