2 days ago

On Thursday, 30 October 2025 at 10:20:01 UTC, Zealot wrote:

>

On Wednesday, 29 October 2025 at 22:33:50 UTC, Peter C wrote:

>

And really, if scopeprivate produces cognitive overload in a programmers brain, they probably should choose another profession.

maybe you should choose another profession /s.

there's a lot of complexity if you consider metaprogramming, tupleof, ...

and you can simply do this for the exact same result:

import std;

class A {
    struct _____ {
        int a = 42;
        int b = 43;
    }
    _____ _;

    void foo() {
        writeln(_.a);
    }
}

void main() {
    auto a = new A;
    a.foo();
    a._.a.writeln; // you don't do this accidentially
}

_____ is a beautiful name. Kinda hard to guess how many _ there are. Maybe _696969 is a better name.

2 days ago

On Thursday, 30 October 2025 at 06:21:41 UTC, Peter C wrote:

>

But I am genuinely open to listening to a good, rational argument, make no mistake about that.

you ignore the amount of code adding scopeprivate would affect. for example any code that uses __traits getVisibility would be likely broken by introducing a new case.

metaprogramming also would have new weird special cases.

funnily tupleof would keep working (because it's arguably broken now); protection doesn't work the way you think it does anyway, consider this:


--- foo.d
module foo;
import std;

    class A {
        private int a = 42;
        protected  int b = 43;
        int c = 44;
    }

    --- bar.d
    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]);
        }
    }

    ```
2 days ago

On Thursday, 30 October 2025 at 03:48:01 UTC, 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.

I consider not even this a deficiency, because unittests within_the_same_module are per definition whitebox tests, so they should be allowed to use private stuff. (In C++ they are required to be "friends").

If you want to do blackbox tests, by definition they have to be written in a different file (as touching the original file would be a violation of "blackbox"). And then they really can't see the private stuff.

So, everything is fine.

Having scope private would simply be lying in your pocket. Not having this is a clear improvement.

2 days ago
On 31/10/2025 4:03 AM, Dom DiSc wrote:
> On Thursday, 30 October 2025 at 03:48:01 UTC, 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.
> 
> I consider not even this a deficiency, because unittests _within_the_same_module_ are per definition whitebox tests, so they should be allowed to use private stuff. (In C++ they are required to be "friends").
> 
> If you want to do blackbox tests, by definition they have to be written in a different file (as touching the original file would be a violation of "blackbox"). And then they really can't see the private stuff.
> 
> So, everything is fine.
> 
> Having scope private would simply be lying in your pocket. Not having this is a clear improvement.

This isn't what Steven is talking about.

What Steven is talking about is documentation unittests.

These need to be runnable by the user, in a different module.

We've had cases where documentation unittests that are used in examples for Phobos not work outside of the module when tried by people.

2 days ago

On Thursday, 30 October 2025 at 05:23:29 UTC, Peter C wrote:

>

An putting aside any idea of adding scopeprivate to D, let's remind ourselves that abstraction is one of the central principles of software engineering, what an abstract data type actually is, and why it's important for it to have the capacity to establish and maintain its own invariants:

https://learn.adacore.com/courses/ada-in-practice/chapters/abstract_data_types.html

If I put these two types in the same module, where you can reasonably argue they belong, then the concerns in the article above become an immediate reality in D:

Ironically in C# enumerator accesses all collection members directly, including _version. Here's System.Collections.Generic.List:

public struct Enumerator : IEnumerator<T>, IEnumerator
{
	private readonly List<T> _list;
	private int _index;
	private readonly int _version;
	private T? _current;

	internal Enumerator(List<T> list)
	{
		_list = list;
		_index = 0;
		_version = list._version;
		_current = default;
	}

	public void Dispose()
	{
	}

	public bool MoveNext()
	{
		List<T> localList = _list;

		if (_version == localList._version && ((uint)_index < (uint)localList._size))
		{
			_current = localList._items[_index];
			_index++;
			return true;
		}
		return MoveNextRare();
	}

	private bool MoveNextRare()
	{
		if (_version != _list._version)
		{
			ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
		}

		_index = _list._size + 1;
		_current = default;
		return false;
	}

	public T Current => _current!;

	object? IEnumerator.Current
	{
		get
		{
			if (_index == 0 || _index == _list._size + 1)
			{
				ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumOpCantHappen();
			}
			return Current;
		}
	}

	void IEnumerator.Reset()
	{
		if (_version != _list._version)
		{
			ThrowHelper.ThrowInvalidOperationException_InvalidOperation_EnumFailedVersion();
		}

		_index = 0;
		_current = default;
	}
}
2 days ago

On Thursday, 30 October 2025 at 13:24:14 UTC, Kapendev wrote:

>

_____ is a beautiful name. Kinda hard to guess how many _ there are. Maybe _696969 is a better name.

React uses __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED name and another SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED.

2 days ago

On Thursday, 30 October 2025 at 15:19:37 UTC, Richard (Rikki) Andrew Cattermole wrote:

>

On 31/10/2025 4:03 AM, Dom DiSc wrote:

>

On Thursday, 30 October 2025 at 03:48:01 UTC, 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.

I consider not even this a deficiency, because unittests within_the_same_module are per definition whitebox tests, so they should be allowed to use private stuff. (In C++ they are required to be "friends").

If you want to do blackbox tests, by definition they have to be written in a different file (as touching the original file would be a violation of "blackbox"). And then they really can't see the private stuff.

So, everything is fine.

Having scope private would simply be lying in your pocket. Not having this is a clear improvement.

This isn't what Steven is talking about.

What Steven is talking about is documentation unittests.

These need to be runnable by the user, in a different module.

We've had cases where documentation unittests that are used in examples for Phobos not work outside of the module when tried by people.

Steve’s point was a little confusing. He said it’s a unit test problem and not an accessibility problem. Regular unit tests should be able to access the rest of the module but documented unit tests shouldn’t. But would we really want to strictly enforce that for documented unit tests? The point might be that it’s not an issue of other parts of the module accessing the internals of the unittest, it’s about the ability of the unittest to access the private elements of the module. So I don’t think the equivalent of scope-private would solve that issue. You would need to make everything else in the module scope-private instead of private, which you may not want to do. Seems like it would need something else. Maybe instead of a “friend” you would need an “enemy”. ;)

2 days ago
>
public struct Enumerator : IEnumerator<T>, IEnumerator
{
	private readonly List<T> _list;
	private int _index;
	private readonly int _version;
	private T? _current;

	internal Enumerator(List<T> list)
	{

Also notice that Enumerator's constructor has internal access attribute, which is broader than needed, because it's intended to be called only by the List class, but is callable by any code in the library. D can provide better encapsulation here by declaring the constructor with private access attribute, which broad enough to be callable by the collection, but stricter than C#'s internal.

2 days ago

On Thursday, 30 October 2025 at 11:30:47 UTC, Arafel wrote:

>

On 10/30/25 11:20, Zealot wrote:

>

and you can simply do this for the exact same result:

That is a slippery slope. Of course you can manage visibility by convention: python does it, and is widely successful, whether because or in spite of it.

Now the question is that if you go this way... why do you then need any visibility attributes at all? Because to me this seems like the worst of both worlds: you have some attributes enforced by the compiler, and some others enforced by convention. Now that's cognitive load.

Also please don't misunderstand me. While I would prefer and use something like scopeprivate, I come from java. This means that having one class per file* feels kind of good enough to me, so I'm not going to make a fuss about it.

*: Actually, you can have more than one class per file, just one public one. But it feels really unidiomatic.

This jumps into Clojure territory.

Fogus: "Following that idea—some people are surprised by the fact that Clojure does not engage in data-hiding encapsulation on its types. Why did you decide to forgo data-hiding?"

Rich Hickey: "If people don’t have the sensibilities to desire to program to abstractions and to be wary of marrying implementation details, then they are never going to be good programmers."

https://harfangk.github.io/2017/12/08/rich-hickey-interview-from-codequarterly.html

I largely agree with that viewpoint, so I see this entire discussion as a waste, and proposals for private by default as a disaster.

2 days ago

On Thursday, 30 October 2025 at 16:02:36 UTC, jmh530 wrote:

>

Steve’s point was a little confusing. He said it’s a unit test problem and not an accessibility problem. Regular unit tests should be able to access the rest of the module but documented unit tests shouldn’t. But would we really want to strictly enforce that for documented unit tests? The point might be that it’s not an issue of other parts of the module accessing the internals of the unittest, it’s about the ability of the unittest to access the private elements of the module. So I don’t think the equivalent of scope-private would solve that issue. You would need to make everything else in the module scope-private instead of private, which you may not want to do. Seems like it would need something else. Maybe instead of a “friend” you would need an “enemy”. ;)

If you look at it another way, you can't document usage with a unittest that is not inside the module. There simply isn't a way to tie an external unittest to the function, it has to go right after it.

This is a unittest problem, but in fact, it's very nice to have the documented unittest required to be right after it (for maintenance purposes). The better solution is to prevent documented unittests (or at least provide the ability to prevent) from accessing private data.

-Steve