1 day ago Re: Code That Says Exactly What It Means | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Friday, 31 October 2025 at 00:50:54 UTC, Walter Bright wrote:
> On 10/29/2025 8:48 PM, Steven Schveighoffer wrote:
>> There has always been only ONE deficiency for this, and that is documented unittests being allowed to use private symbols in the module. But this is a unittest problem, and not a private problem.
>>
>> Note that the OPs argument against (non-documented) unittests being able to access private data is ironically something I view as a necessity -- I often test functions on a type and then examine the private details to make sure the state is as I expect it.
>
> Since unittests aren't part of the finished program, preventing it from having access is not terribly useful. It's like you can prefix statements with `debug` when needing to override pure / @safe attributes.
I refer you back to my opening post, where I don't want to prevent access to 'private' parts, but 'scopeprivate' parts. This is by design - i.e. I've actually designed it this way, and the compile time unittest there helps to demonstrate that my design works as I intended, not just now, but also when somone maintaining this code comes along, and accidently adds acc.authToken to the log. No. My design explicitely does not allow that, so they cannot make a mistake like that. They'd have to really go out of their way to do that - which is exactly my intention in the design.
Without 'scopeprivate' I cannot write code like that.
Without type-level encapsulation, I have no type-safety, and no ability for the compiler to enforce my invariants. Rather I have to rely on the capability of the programmer.
Since the programmer in D has no type-level encapsulation available to them, they have to rethink everything! But class-oriented programming, including OOP (which D claims to support), is founded on the princple of type-level encapsulation.
Once you completely remove type-level encapsulation (as D has done), you cannot claim to support OOP.
You could claim " D supports a variation on OOP, where types themselves don't have encapsulation, but when wrapped in a module with no other code, it can simulate that encapsulation.
Again, good luck getting an OO programmer to take D seriously.
Outside of this issue, there are certainly things I really like about D. But I cannot sacrifice type-level encapsulation in favour of module-level encapsulation. I'm happy to accept both though.
Again, Swift has already (and correctly) resolved this tension.
scopeprivate is just a tool to resolve that exact same tension, in the least disrupting way.
// Compile-time visibility tests
unittest
{
auto acc = new Account(5, "Eve", 400.0, "tok5");
// Allowed:
static assert(__traits(compiles, acc.getBalance()));
// Forbidden (scopeprivate):
static assert(!__traits(compiles, acc.balance));
static assert(!__traits(compiles, acc.authToken));
}
| |||
1 day ago Re: Code That Says Exactly What It Means | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ealot | On Thursday, 30 October 2025 at 22:27:32 UTC, ealot wrote:
> On Thursday, 30 October 2025 at 21:49:45 UTC, Peter C wrote:
>> On Thursday, 30 October 2025 at 13:31:48 UTC, Zealot wrote:
>>> [...]
>>
>> Thanks for raising the discussion ;-)
>>
>> I think I might be missing your point though (i.e. the code below works just fine):
>>
>> // ===============
>>
>> module foo;
>> @safe:
>> private:
>>
>> import std;
>>
>> public class A
>> {
>> scopeprivate int p = 1;
>> private int a = 42;
>> protected int b = 43;
>> int c = 44;
>> }
>>
>> // ===============
>>
>> module bar;
>> @safe:
>> private:
>>
>> import std;
>> import foo;
>>
>> void main()
>> {
>> auto a = new A;
>>
>> static foreach(i; 0..a.tupleof.length)
>> {
>> writeln(__traits(getVisibility, a.tupleof[i]), " => ", a.tupleof[i]);
>> }
>> }
>>
>> // ===============
>>
>> scopeprivate => 1
>> private => 42
>> protected => 43
>> public => 44
>
> a) tupleof ignores the privacy attributes. tupleof allows you to access private state.
> b) any code that exists and uses getVisibility now has a new case introduced which it doesn't handle, so you would break all that code by introducing scopeprivate.
Reflection is critical to a number of D's standout features - e.g. compile-time metaprogramming and generic programming.
Thus, if scopeprivate were introduced, the guiding principle *must* be non-breaking behavior for existing reflection code.
So, in theory, existing code that doesn't know about scopeprivate won't break, crash or misbehave, but it might need to adapt to a new case that it didn't handle before.
That is, the burden will rightly be on the introspection logic itself, to filter or update its logic.
That’s the right balance: reflection remains stable, while introspection evolves to respect new semantics.
| |||
1 day ago Re: Code That Says Exactly What It Means | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Thank you, I did misunderstand your point. You're correct on all counts. | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply