digitalmars.D - Code That Says Exactly What It Means
- Peter C (191/191) Oct 25 Among D developers, the idea of adding a new visibility attribute
- monkyyy (14/20) Oct 26 "What do you call a specification that a computer can turn into a
- Peter C (15/22) Oct 26 You might be missing the point here ;-)
- monkyyy (7/10) Oct 26 the core devs just hate datastructures, fixed point type would be
- Richard (Rikki) Andrew Cattermole (3/12) Oct 26 It is a LOT more than 50 lines.
- Peter C (9/19) Oct 26 opend is where I got the idea. (though I got uncomfortable with
- Walter Bright (8/10) Oct 27 I'd just use `long` and have it represent the number of pennies. This gi...
- Kapendev (10/11) Oct 26 Don't have a strong opinion about this because I'm not the target
- Steven Schveighoffer (4/11) Oct 26 This has been proposed and rejected many times. In D private is
- Peter C (21/33) Oct 26 I'm wouldn't say I'm proposing it, but rather demonstrating how
- Peter C (9/12) Oct 27 btw. just for interest sake if nothing else... Swift's 'privacy
- Serg Gini (7/12) Oct 27 D design team doesn't ignore it, but against this feature.
- Peter C (38/41) Oct 27 They're against locks on doors?
- Walter Bright (2/2) Oct 27 I know you didn't propose this, but I had quite enough of C++'s "friend"...
- monkyyy (2/4) Oct 27 go the extra mile and delete private and immutable
- Kapendev (2/7) Oct 28 Based monkey take!!! Let's go!!
- Peter C (34/36) Oct 28 There is nothing conceptually wrong with the C++ friend concept.
- Walter Bright (8/20) Oct 28 Sure, it does mean a change in layout from other languages. But the capa...
- Peter C (13/17) Oct 28 I need to push back just one more time.
- Lance Bachmeier (10/24) Oct 28 Over the years this has come up many times. Can you provide an
- Peter C (18/29) Oct 28 Example after example will get nowhere, fast.
- monkyyy (17/18) Oct 28 Everywhere: all the time. Kaps lib had one use of the private
- Kapendev (12/18) Oct 28 I would like to issue a public and formal apology.
- claptrap (6/25) Oct 28 Pink Floyds album "The Wall" was about the dark side of object
- Lance Bachmeier (8/39) Oct 28 The problem with your approach is that you're proposing a major
- Peter C (14/64) Oct 28 Honestly, I couldn't care less about D so much as the principle
- claptrap (3/11) Oct 29 You are totally correct, but it wont change anything.
- Serg Gini (2/16) Oct 29 How long time ago you started talking with yourself? xD
- Kagamin (2/4) Oct 29 Current design is valid, because it works.
- Peter C (14/16) Oct 29 Actually, that really is not what I'm doing.
- jmh530 (61/72) Oct 29 I should preface this by repeating again that I really don't care
- Paul Backus (26/37) Oct 29 It's a change to the grammar, which means that all parser-based
- jmh530 (72/109) Oct 29 Hmm, I don't have a sense of how much of a lift that is. But I
- Sergey (23/29) Oct 29 Thanks.
- H. S. Teoh (6/9) Oct 29 Exactly.
- jmh530 (16/31) Oct 29 Are they the same person? I can't keep track. People should just
- Steven Schveighoffer (26/40) Oct 29 I think it's unfair to judge all new questions with this lens,
- Peter C (22/65) Oct 29 unittests being able to access private data should be put within
- Peter C (62/62) Oct 29 On Thursday, 30 October 2025 at 03:48:01 UTC, Steven
- Peter C (26/89) Oct 29 And for those that argue.. well .. in Ada.. packages are the unit
- zod (6/10) Oct 30 we're not holding you hostage. you are free to pick whatever
- Kapendev (5/17) Oct 30 There is nothing modern about this. It's just a *preference*
- Peter C (17/38) Oct 30 That's where I strongly disagree.
- Peter C (2/7) Oct 30 oops. I flipped that the wrong way ;-)
- Zealot (28/30) Oct 30 you ignore the amount of code adding scopeprivate would affect.
- Kagamin (66/75) Oct 30 Ironically in C# enumerator accesses all collection members
- Kagamin (6/16) Oct 30 Also notice that Enumerator's constructor has internal access
- Sergey (9/12) Oct 30 Thank you. I agree
- claptrap (11/21) Oct 30 I have never argued for class private, search the forum and find
- Dom DiSc (13/16) Oct 30 I consider not even this a deficiency, because unittests
- Richard (Rikki) Andrew Cattermole (6/23) Oct 30 This isn't what Steven is talking about.
- jmh530 (15/42) Oct 30 Steve’s point was a little confusing. He said it’s a unit test
- Steven Schveighoffer (11/24) Oct 30 If you look at it another way, you can't document usage with a
- H. S. Teoh (30/52) Oct 30 lol, to further distance ourselves from C++, we should introduce the
- Kagamin (5/14) Oct 30 I'd say it's not wrong, private members should be documented. The
- Walter Bright (4/12) Oct 30 Since unittests aren't part of the finished program, preventing it from ...
- Steven Schveighoffer (37/52) Oct 30 I've already started replying again, even though I said I
- Walter Bright (2/2) Oct 31 Thank you, I did misunderstand your point.
- Peter C (42/57) Oct 30 I refer you back to my opening post, where I don't want to
- Peter C (21/31) Oct 30 Here there may well be an argument to make. Although it took me
- Peter C (17/28) Oct 29 There is nothing complex about scopeprivate. That's yet another
- Zealot (23/26) Oct 30 maybe you should choose another profession /s.
- Arafel (14/15) Oct 30 That is a slippery slope. Of course you can manage visibility by
- Zealot (8/24) Oct 30 the difference is that nothing is stopping you from simply
- Lance Bachmeier (12/28) Oct 30 This jumps into Clojure territory.
- Kapendev (3/29) Oct 30 `_____` is a beautiful name. Kinda hard to guess how many `_`
- Kagamin (3/5) Oct 30 React uses `__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`
- zod (12/18) Oct 29 the thing is, it doesnt actually solve anything. if you have
- jmh530 (2/4) Oct 28 You are correct on this.
- Max Samukha (6/11) Oct 28 He's been attacking a strawman. Nobody asked for friend classes.
- jmh530 (2/16) Oct 28 More of a slippery slope than a strawman. ;)
- Peter C (16/30) Oct 28 I think that 'Disclaimer' misses the point of this thread.
- Alexandru Ermicioi (11/19) Oct 28 Then use packages, not modules, and you'll get the properties you
- Peter C (10/14) Oct 28 yet another strawman argument.
- Alexandru Ermicioi (11/12) Oct 29 That was a genuine recommendation to get you out of the rut.
- jmh530 (13/25) Oct 27 To be fair, it keeps coming up because people (not me!) say they
- Walter Bright (17/26) Oct 27 D is also regularly accused of supporting too many paradigms.
- Peter C (68/99) Oct 27 I think you're missing the point here.
- Sergey (9/22) Oct 28 There is no problems as I can see.
- Kapendev (8/17) Oct 28 Please don't make it a popularity discussion because it will turn
- Walter Bright (13/20) Oct 28 D has terrible marketing.
- Walter Bright (20/23) Oct 28 Yes. If you want to hide the internals of a class, put it in its own mod...
- Peter C (21/49) Oct 28 Your position is clear, and I won't push it further.
- Kapendev (2/5) Oct 28 Different tools, different philosophies. Good luck.
- Paul Backus (2/5) Oct 28 Does that mean you're going to stop posting about it?
- Kapendev (5/16) Oct 28 D is secretly the **MOST** opinionated language ever made
- Fustiki Scuria (11/11) Nov 02 I'd like to say that I'd much rather see this as protected
Among D developers, the idea of adding a new visibility attribute
like scopeprivate often meets with scepticism. After all, D
already has private for module-level encapsulation and package
for sharing across sibling modules. And if you really want to
lock a class down, you can always put it in its own module. So
why bother?
The problem is that these existing tools force you into coarse
choices. If helpers and tests live in the same module, they see
everything. If you isolate the class in its own module, they see
nothing. And while package is useful for widening access across a
package hierarchy, it doesn't let you narrow visibility inside a
module. Rather, package widens visibility, across a whole package
hierarchy. That's not the same as narrowing it down. In practice,
this means you can't express a very common design intent:
"helpers in the same module should see some internals, but not
the most sensitive ones."
That's where a 'scopeprivate' comes in. It introduces a missing
rung on the visibility ladder: type-only access. With it, you
could mark fields like Account.id or Account.owner as private or
package, so persistence and logging helpers can use them, while
marking fields like Account.balance or Account.authToken as
scopeprivate, so only the class itself can touch them. The
compiler enforces this boundary, preventing accidental leaks in
logs, persistence, or tests. You no longer need to split every
class into its own module just to achieve stricter encapsulation,
and you no longer need to rely on convention or code review to
stop sensitive data from slipping out.
In other words, scopeprivate doesn't make the impossible possible
- you can already hack around with module boundaries and package.
What it does is make disciplined program design, explicit and
enforceable. It lets you express intent directly at the
declaration site, keeps related code together without sacrificing
safety, and ensures that invariants remain protected by
construction.
For developers who care about clarity, maintainability, and
correctness, that's not redundant - it's a meaningful step toward
code that says exactly what it means.
module exampleOnly;
safe:
private:
//import std;
import std.stdio : writeln;
import std.exception : enforce;
public class Account
{
private
{
int id;
string owner;
}
scopeprivate
{
double balance;
string authToken;
}
public this(int id, string owner, double openingBalance, string
token)
{
this.id = id;
this.owner = owner;
this.balance = openingBalance;
this.authToken = token;
}
public void deposit(double amount)
{
enforce(amount > 0, "Deposit must be positive");
balance += amount;
}
public void withdraw(double amount)
{
enforce(amount > 0 && amount <= balance, "Invalid
withdrawal");
balance -= amount;
}
public double getBalance() const { return balance; }
}
// Can see IDs and owners (enough to write to DB), but not
balances or tokens.
public void saveToDatabase(Account a)
{
writeln("[DB] INSERT INTO accounts (id, owner) VALUES (", a.id,
", '", a.owner, "')");
// Example compiler message if you were to uncomment the lines
below:
// writeln("Balance: %s", a.balance);
// Error: no property `balance` for `a` of type
`finance.Account` [`balance` is not accessible here]
// writeln("AuthToken: %s", a.authToken);
// Error: no property `authToken` for `a` of type
`finance.Account` [`authToken` is not accessible here]
}
// Logs can include IDs and owners for traceability, but cannot
leak sensitive state.
public void logTransactionStart(Account a, string action)
{
writeln("[LOG] Account id=", a.id, " owner=", a.owner, "
starting action=", action);
// Example compiler message if you were to uncomment the lines
below:
//writeln("[LOG] Account balance = %s", a.balance);
// Error: no property `balance` for `a` of type
`finance.Account` [`balance` is not accessible here]
//writeln("[LOG] Account authToken = %s", a.authToken);
// Error: no property `authToken` for `a` of type
`finance.Account` [`authToken` is not accessible here]
}
public void logTransactionEnd(Account a, string action, bool
success)
{
writeln("[LOG] Account id=", a.id, " owner=", a.owner, "
finished action=", action, " status=", success ? "OK" : "FAILED");
}
// Unit tests are also subject to scopeprivate's visibility
restriction.
// 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));
}
// Constructor tests
unittest
{
auto acc = new Account(1, "Alice", 100.0, "tok");
assert(acc.getBalance() == 100.0);
}
// Deposit tests
unittest
{
import std.exception : assertThrown;
auto acc = new Account(2, "Bob", 50.0, "tok2");
acc.deposit(25.0);
assert(acc.getBalance() == 75.0);
assertThrown!Exception(acc.deposit(0));
assertThrown!Exception(acc.deposit(-10));
}
// Withdraw tests
unittest
{
import std.exception : assertThrown;
auto acc = new Account(3, "Charlie", 200.0, "tok3");
acc.withdraw(50.0);
assert(acc.getBalance() == 150.0);
assertThrown!Exception(acc.withdraw(0));
assertThrown!Exception(acc.withdraw(-5));
assertThrown!Exception(acc.withdraw(500)); // too much
}
// Logging and DB output tests
system unittest
{
// helper to capture writeln output
string captureOutput(void delegate() dg)
{
import std.array : appender;
import std.stdio : stdout, File;
import core.stdc.stdio : fflush;
import std.string : strip;
auto buf = appender!string();
auto old = stdout;
auto f = File.tmpfile();
scope(exit) f.close();
stdout = f;
dg();
fflush(f.getFP());
f.rewind();
foreach (line; f.byLine)
buf.put(line.idup);
stdout = old;
return buf.data.strip;
}
auto acc = new Account(4, "Dana", 300.0, "tok4");
auto dbOut = captureOutput({ saveToDatabase(acc); });
assert(dbOut == "[DB] INSERT INTO accounts (id, owner) VALUES
(4, 'Dana')");
auto logStart = captureOutput({ logTransactionStart(acc,
"deposit"); });
assert(logStart == "[LOG] Account id=4 owner=Dana starting
action=deposit");
auto logEndOk = captureOutput({ logTransactionEnd(acc,
"deposit", true); });
assert(logEndOk == "[LOG] Account id=4 owner=Dana finished
action=deposit status=OK");
auto logEndFail = captureOutput({ logTransactionEnd(acc,
"withdraw", false); });
assert(logEndFail == "[LOG] Account id=4 owner=Dana finished
action=withdraw status=FAILED");
}
Oct 25
On Sunday, 26 October 2025 at 06:33:11 UTC, Peter C wrote:Among D developers, the idea of adding a new visibility attribute like scopeprivate often meets with scepticism. For developers who care about clarity, maintainability, and correctness, that's not redundant - it's a meaningful step toward code that says exactly what it means."What do you call a specification that a computer can turn into a program? code we call it code"; this cuts both ways, both telling "business logic"/vibe coders to go to hell; and you to shut up if my code compiles. If you take 300 lines to implement what I can in 10, your *just factually* being verbose and redundant, mere assertions otherwise are absurd. I hate function coloring, I hate "stop working" tagging, I hate extending dependencys... I hate safetyism itself.codeYou wrote a big class, only to use floats to represent money. All the safety keywords and you broke your type theory. When you do this, youd be fired instantly; but if for some reason you managed to ship people would steal pennies with floating point errors. Your reducing clarity.
Oct 26
On Sunday, 26 October 2025 at 08:32:37 UTC, monkyyy wrote:.. You wrote a big class, only to use floats to represent money. All the safety keywords and you broke your type theory. When you do this, youd be fired instantly; but if for some reason you managed to ship people would steal pennies with floating point errors. Your reducing clarity.You might be missing the point here ;-) decimal type. But my knowledge of D is somewhat limited - I don't think it even has a decimal type?? - and the code was merely an example (as per the name of the module) to demonstrate code that desires to narrow the visiblity,in a particular case, not widen it (with package). Nothing else in the code is relevant here, except 'how' to implement that programmers desire. In that example code, it is 'scopeprivate' that allowed the programmer of that code, to do just that, in an explicit and enforceable manner. Without scopeprivate, I'm not sure how that programmer could have expressed that intent 'in a meaningful way', and certainly not in a way that is enforceable.
Oct 26
On Sunday, 26 October 2025 at 09:35:47 UTC, Peter C wrote:But my knowledge of D is somewhat limited - I don't think it even has a decimal type??the core devs just hate datastructures, fixed point type would be reasonable to ask from an std and probably would be 50 lines of code ish But that should be a lib type not a fundamental onescopeprivateI believe its in opend but feel free to guess how much I verified it works
Oct 26
On 27/10/2025 4:51 AM, monkyyy wrote:
On Sunday, 26 October 2025 at 09:35:47 UTC, Peter C wrote:
But my knowledge of D is somewhat limited - I don't think it even
has a decimal type??
the core devs just hate datastructures, fixed point type would be
reasonable to ask from an std and probably would be 50 lines of code ish
But that should be a lib type not a fundamental one
It is a LOT more than 50 lines.
- Somebody who has actually written a fixed point data type.
Oct 26
On Sunday, 26 October 2025 at 15:51:51 UTC, monkyyy wrote:On Sunday, 26 October 2025 at 09:35:47 UTC, Peter C wrote:opend is where I got the idea. (though I got uncomfortable with typing (and looking at) 'private(this)' and changed it to 'scopeprivate'. It works well enough in opend, but the implementation needs a little more work. Just for example, in D, all non-static, non-final member functions of a class are virtual unless they are private or package functions. So private(this) member functions should not be virtual. This is a pretty simple fix in fund.dBut my knowledge of D is somewhat limited - I don't think it even has a decimal type??the core devs just hate datastructures, fixed point type would be reasonable to ask from an std and probably would be 50 lines of code ish But that should be a lib type not a fundamental onescopeprivateI believe its in opend but feel free to guess how much I verified it works
Oct 26
On 10/26/2025 2:35 AM, Peter C wrote:But my knowledge of D is somewhat limited - I don't think it even has a decimal type??I'd just use `long` and have it represent the number of pennies. This gives you representation up to long.max, or: $92,233,720,368,547,758.07 I.e. $92 quadrillion dollars. The national debt is currently $38 trillion, and would have to increase in size by a factor of about 2,421 to overflow. You're good for the foreseeable future!
Oct 27
On Sunday, 26 October 2025 at 06:33:11 UTC, Peter C wrote:scopeprivateDon't have a strong opinion about this because I'm not the target user. The only time I use `private` is when I have something temporary in my library or some internal C bindings. I can see it being useful I guess for some people. The simplest solution now is to prefix your "scopeprivate" functions with a `_`. Ugly names are kinda powerful because you always feel weird about using them. Same as `__traits` or `__gshared` I assume :) You can also search for `_` in your source code. Not the solution you want probably, but anyway.
Oct 26
On Sunday, 26 October 2025 at 06:33:11 UTC, Peter C wrote:Among D developers, the idea of adding a new visibility attribute like scopeprivate often meets with scepticism. After all, D already has private for module-level encapsulation and package for sharing across sibling modules. And if you really want to lock a class down, you can always put it in its own module. So why bother? [...]This has been proposed and rejected many times. In D private is for the module. This is intentional. -Steve
Oct 26
On Sunday, 26 October 2025 at 14:55:07 UTC, Steven Schveighoffer wrote:On Sunday, 26 October 2025 at 06:33:11 UTC, Peter C wrote:I'm wouldn't say I'm proposing it, but rather demonstrating how it would be useful. D's philosophy that modules are the true encapsulation boundary, is just that, a philosophy. The code I presented, and the reasoning behind it, is the real world, and that is what matters. I do agree that the module boundary makes complete sense when you're dong Rust like programming. But when you are programming with objects, based on class types - and come from one of the many languages that do support a boundary on the class type - and discover that in D the class type has no boundary, the mental model of OOP becomes blurred. I believe when Swift became widely used, there was some significant pushback on how they blurred the boundaries on types. I would expect the same to occur in D, if it ever achieved wide spread use. Imagine you're looking for a new building for your business, and you ask the proprietor whether i can put locks on some of the offices, and the proprietor says, no you cannot. If you want a locked office, you'll need to put it in a separate building.Among D developers, the idea of adding a new visibility attribute like scopeprivate often meets with scepticism. After all, D already has private for module-level encapsulation and package for sharing across sibling modules. And if you really want to lock a class down, you can always put it in its own module. So why bother? [...]This has been proposed and rejected many times. In D private is for the module. This is intentional. -Steve
Oct 26
On Sunday, 26 October 2025 at 14:55:07 UTC, Steven Schveighoffer wrote:This has been proposed and rejected many times. In D private is for the module. This is intentional. -Stevebtw. just for interest sake if nothing else... Swift's 'privacy saga' is a neat case study in how language design collides with developer expectations. In the end, developers mental model of 'classes as encapsulation units' was too entrenched for the Swift design team to ignore. Mental models can be really hard to change. https://swiftunwrapped.github.io/episodes/4e7ad642/
Oct 27
On Monday, 27 October 2025 at 10:14:43 UTC, Peter C wrote:In the end, developers mental model of 'classes as encapsulation units' was too entrenched for the Swift design team to ignore. Mental models can be really hard to change. https://swiftunwrapped.github.io/episodes/4e7ad642/D design team doesn't ignore it, but against this feature. And D is not widely adopted - so small amount of D users are fine with the current approach, and wider volumes of developers will just go away to other languages. So this use case is not very relevant for D
Oct 27
On Monday, 27 October 2025 at 11:22:33 UTC, Serg Gini wrote:.. D design team doesn't ignore it, but against this feature. ...They're against locks on doors? The Building Analogy (of D): Offices = Classes or Types Each office represents a type (like a class or struct). Inside the office are documents (fields, methods, data). Locks on doors = Access Modifiers (i.e. scopeprivate) This lock lets you decide who can enter. You can keep sensitive documents private (scopeprivate) while still working in the same building. No locks allowed = No type privacy. If the language doesn’t support scopeprivate members, then anyone can walk into any office and read or change the documents. Separate buildings = Modules or Packages. To achieve scopeprivacy, you’d have to move the sensitive office into a completely different building. That way, only people with access to that building can see it. But this workaround is just clumsy compared to simply locking the door. D doesn't let you lock the office door, so your only option is to move the office into another building - but that’s a poor substitute for a real lock. Most people (programmers) already expect to be able to have a lock on their door, and also the freedom to not have it when so desired. So this is something D will need to grapple with, 'if' it ever becomes widely used. I think that is the lesson of Swift - not to underestimate the power of the mental model that a large portion of programmers already have - a model that provides clarity in complexity. I could restore my own mental model of programming, somewhat, by starting my D coding with this template: module someModule; safe: private: public class myPublicClass { scopeprivate: }
Oct 27
I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.
Oct 27
On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.go the extra mile and delete private and immutable
Oct 27
On Tuesday, 28 October 2025 at 04:02:24 UTC, monkyyy wrote:On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:Based monkey take!!! Let's go!!I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.go the extra mile and delete private and immutable
Oct 28
On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.There is nothing conceptually wrong with the C++ friend concept. It provides a controlled exception, where you can grant access only to specific functions or classes, without opening everything up. It balances strict encapsulation with practical flexibility. Something that you yourself clearly recognise as being important in D as well. In C++, the actual problem was not the friend keyword, but rather the programmers who misused it, which lead to poor design and a blurred abstraction boundary. If D didn't have the class type, I'd say that D solved this problem rather nicely. But a class type also has an abstraction boundary -> it's *own* scope. Without appropriate scope rules, you can't enforce that boundary, and you lose encapsulation - and encapsulation is the foundation of abstract data types. Then, the distinction between interface and implementation collapses. Then, the type's internal rules are meaningless - the abstraction collapses, the type becomes harder to reason about, everything becomes global, its internal state leaks into the rest of the module, breaking any guarantees that the type is supposed to enforce. Without scope, your type just becomes a bags, that anyone can poke into, undermining abstraction, modularity, and reliability. Like with C++ friend, the programmers is invited to misuse it, leading to poor design and a blurred abstraction boundaries. So there is no alternative now, but to create 'one-class modules'. 'scopeprivate' could remove all of these problems, and wouldn't force any change on anyone. Although during a code review, I'd be asking myself, why has this programmer decided to use private instead of scopeprivate - and there better be a bloody good reason for it!
Oct 28
On 10/28/2025 12:21 AM, Peter C wrote:Without appropriate scope rules, you can't enforce that boundary, and you lose encapsulation - and encapsulation is the foundation of abstract data types. Then, the distinction between interface and implementation collapses. Then, the type's internal rules are meaningless - the abstraction collapses, the type becomes harder to reason about, everything becomes global, its internal state leaks into the rest of the module, breaking any guarantees that the type is supposed to enforce. Without scope, your type just becomes a bags, that anyone can poke into, undermining abstraction, modularity, and reliability.Sure, it does mean a change in layout from other languages. But the capability is there. The boundary is at the module level. The "friends" are the other functions in the module. If they are not actually friends, they shouldn't be in that module. It's entirely under the programmer's control. As for the distinction between interface and implementation, that can also be done with .di files. The 'i' in .di stands for "interface".
Oct 28
On Tuesday, 28 October 2025 at 08:01:40 UTC, Walter Bright wrote:... Sure, it does mean a change in layout from other languages. But the capability is there.I need to push back just one more time. That capability is not there. That is my whole point and reason for this thread. You cannot say this in D code: "this particular part of my class is mine alone, not even my friendly module neighbors can touch it." People can debate as to whether I should have the right (or need) to say that "this part of my class is mine alone, not even my friendly module neighbors can touch it.", but they cannot argue that I can already do this. D's position is very clear though. That is, "You simply cannot say this in D - and that's they way we want it to remain."
Oct 28
On Tuesday, 28 October 2025 at 21:49:00 UTC, Peter C wrote:On Tuesday, 28 October 2025 at 08:01:40 UTC, Walter Bright wrote:Over the years this has come up many times. Can you provide an example showing the value of doing that? I understand that maybe that's your preference for whatever valid reason, but I've never seen anyone give an example where it's actually a constraint. If you want to push on this, that's where you should start. Because every previous such proposal I've seen has died, as the people requesting it keep arguing from authority that it's the correct way to do things, rather than demonstrating the benefit of a major change to the language.... Sure, it does mean a change in layout from other languages. But the capability is there.I need to push back just one more time. That capability is not there. That is my whole point and reason for this thread. You cannot say this in D code: "this particular part of my class is mine alone, not even my friendly module neighbors can touch it."
Oct 28
On Tuesday, 28 October 2025 at 22:36:58 UTC, Lance Bachmeier wrote:.. Over the years this has come up many times. Can you provide an example showing the value of doing that? I understand that maybe that's your preference for whatever valid reason, but I've never seen anyone give an example where it's actually a constraint. If you want to push on this, that's where you should start. Because every previous such proposal I've seen has died, as the people requesting it keep arguing from authority that it's the correct way to do things, rather than demonstrating the benefit of a major change to the language.Example after example will get nowhere, fast. It's a matter or principle, not examples. The principal behind one perspective is: Modules are collaboration units, types are sovereign owners. The principle behind the other perspective says: Modules disolve ownership, and they are all or nothing. I am a firm believer, that each type should be able to guard its invariants, even in a collaborative module. It just so happens that I primarily use class types, so the principle itself often gets overlooked in the discussion, and (some) people focus their attention on their dislike of OOP instead ;-) I firmly believe that types should retain their sovereignty, even in within a module, and scopeprivate would accomplish this. Collaboration, should not erase ownership. Can you give me an example where it should ;-)
Oct 28
On Tuesday, 28 October 2025 at 23:15:36 UTC, Peter C wrote:Can you give me an example where it should ;-)Everywhere: all the time. Kaps lib had one use of the private keyword he added on a whim for a week, I needed to go edit it out within 2 hours of downloading the new copy. "Stop working" keywords can only make (overall) less code compile; I like to think compilers should try to compile code, by the little known philosophy of "you have ONE JOB" and "clankers lack an immortal soul and have no right to question me a divine being" If a problem is naturally imperative; and thats all of io; you may mathematically be able to convert it to a something "pure" but the further you push the more it will look like Haskell telling you need to learn about monads to print hello world; you should just skip ahead on the path of "safety enlightenment" to full Haskell, look at a monad implementing the same bug you could've done in c-89 in less time, and return to embrace the chaos.
Oct 28
On Tuesday, 28 October 2025 at 23:58:35 UTC, monkyyy wrote:On Tuesday, 28 October 2025 at 23:15:36 UTC, Peter C wrote:I would like to issue a public and formal apology. I was depressed at the time and did not understand the gravity of my actions, nor the pain I caused by having to edit it out within two hours of downloading the new copy. It was irresponsible and reckless. I have since reflected deeply on my actions. I've unlearned everything, rebuilt my worldview from the ground up. I am a new person. To everyone affected, I am sorry. To monkyyy, I am sorry. To the compiler that had to process my code, I am sorry. I am sorry.Can you give me an example where it should ;-)Everywhere: all the time. Kaps lib had one use of the private keyword he added on a whim for a week, I needed to go edit it out within 2 hours of downloading the new copy.
Oct 28
On Wednesday, 29 October 2025 at 00:19:10 UTC, Kapendev wrote:On Tuesday, 28 October 2025 at 23:58:35 UTC, monkyyy wrote:Pink Floyds album "The Wall" was about the dark side of object orientated encapsulation. It has it's climax in the song "The Trial" where the wall is final torn down and monkey is simultaneously exposed and freed from his mental prison. Tear down the wall!On Tuesday, 28 October 2025 at 23:15:36 UTC, Peter C wrote:I would like to issue a public and formal apology. I was depressed at the time and did not understand the gravity of my actions, nor the pain I caused by having to edit it out within two hours of downloading the new copy. It was irresponsible and reckless. I have since reflected deeply on my actions. I've unlearned everything, rebuilt my worldview from the ground up. I am a new person. To everyone affected, I am sorry. To monkyyy, I am sorry. To the compiler that had to process my code, I am sorry. I am sorry.Can you give me an example where it should ;-)Everywhere: all the time. Kaps lib had one use of the private keyword he added on a whim for a week, I needed to go edit it out within 2 hours of downloading the new copy.
Oct 28
On Tuesday, 28 October 2025 at 23:15:36 UTC, Peter C wrote:On Tuesday, 28 October 2025 at 22:36:58 UTC, Lance Bachmeier wrote:The problem with your approach is that you're proposing a major change to the language. You need to demonstrate the benefit. I'm not proposing anything, just telling you that if you don't want to dump your time in a hole, you're going to need to provide a more compelling argument to the powers in charge (which does not include me). I don't recall anyone ever arguing for this feature and making a real attempt to justify it as a language change... Over the years this has come up many times. Can you provide an example showing the value of doing that? I understand that maybe that's your preference for whatever valid reason, but I've never seen anyone give an example where it's actually a constraint. If you want to push on this, that's where you should start. Because every previous such proposal I've seen has died, as the people requesting it keep arguing from authority that it's the correct way to do things, rather than demonstrating the benefit of a major change to the language.Example after example will get nowhere, fast. It's a matter or principle, not examples. The principal behind one perspective is: Modules are collaboration units, types are sovereign owners. The principle behind the other perspective says: Modules disolve ownership, and they are all or nothing. I am a firm believer, that each type should be able to guard its invariants, even in a collaborative module. It just so happens that I primarily use class types, so the principle itself often gets overlooked in the discussion, and (some) people focus their attention on their dislike of OOP instead ;-) I firmly believe that types should retain their sovereignty, even in within a module, and scopeprivate would accomplish this. Collaboration, should not erase ownership. Can you give me an example where it should ;-)
Oct 28
On Wednesday, 29 October 2025 at 01:18:42 UTC, Lance Bachmeier wrote:On Tuesday, 28 October 2025 at 23:15:36 UTC, Peter C wrote:Honestly, I couldn't care less about D so much as the principle that "Collaboration, should not erase ownership". Nobody has ever demonstrated why it should - most likely, because it's not a valid principle. It's sad that a discussion on this principle has to always get derailed. A few are already trying hard to do that. I guess this is a discussion for a more professionaly minded audience - so I'll leave it for now. btw. If I had been involved when someone suggested friends in C++, I would have actively argued the same principle. So it's now about D per se. Actually, I would have argued in C++, for friendprivate ;-)On Tuesday, 28 October 2025 at 22:36:58 UTC, Lance Bachmeier wrote:The problem with your approach is that you're proposing a major change to the language. You need to demonstrate the benefit. I'm not proposing anything, just telling you that if you don't want to dump your time in a hole, you're going to need to provide a more compelling argument to the powers in charge (which does not include me). I don't recall anyone ever arguing for this feature and making a real attempt to justify it as a language change... Over the years this has come up many times. Can you provide an example showing the value of doing that? I understand that maybe that's your preference for whatever valid reason, but I've never seen anyone give an example where it's actually a constraint. If you want to push on this, that's where you should start. Because every previous such proposal I've seen has died, as the people requesting it keep arguing from authority that it's the correct way to do things, rather than demonstrating the benefit of a major change to the language.Example after example will get nowhere, fast. It's a matter or principle, not examples. The principal behind one perspective is: Modules are collaboration units, types are sovereign owners. The principle behind the other perspective says: Modules disolve ownership, and they are all or nothing. I am a firm believer, that each type should be able to guard its invariants, even in a collaborative module. It just so happens that I primarily use class types, so the principle itself often gets overlooked in the discussion, and (some) people focus their attention on their dislike of OOP instead ;-) I firmly believe that types should retain their sovereignty, even in within a module, and scopeprivate would accomplish this. Collaboration, should not erase ownership. Can you give me an example where it should ;-)
Oct 28
On Wednesday, 29 October 2025 at 01:32:38 UTC, Peter C wrote:On Wednesday, 29 October 2025 at 01:18:42 UTC, Lance BachmeierYou are totally correct, but it wont change anything. Happy now?Honestly, I couldn't care less about D so much as the principle that "Collaboration, should not erase ownership". Nobody has ever demonstrated why it should - most likely, because it's not a valid principle. It's sad that a discussion on this principle has to always get derailed. A few are already trying hard to do that.
Oct 29
On Wednesday, 29 October 2025 at 09:06:57 UTC, claptrap wrote:On Wednesday, 29 October 2025 at 01:32:38 UTC, Peter C wrote:How long time ago you started talking with yourself? xDOn Wednesday, 29 October 2025 at 01:18:42 UTC, Lance BachmeierYou are totally correct, but it wont change anything. Happy now?Honestly, I couldn't care less about D so much as the principle that "Collaboration, should not erase ownership". Nobody has ever demonstrated why it should - most likely, because it's not a valid principle. It's sad that a discussion on this principle has to always get derailed. A few are already trying hard to do that.
Oct 29
On Wednesday, 29 October 2025 at 09:17:19 UTC, Serg Gini wrote:On Wednesday, 29 October 2025 at 09:06:57 UTC, claptrap wrote:On Wednesday, 29 October 2025 at 01:32:38 UTC, Peter C wrote:How long time ago you started talking with yourself? xDOn Wednesday, 29 October 2025 at 01:18:42 UTC, Lance BachmeierYou are totally correct, but it wont change anything. Happy now?Honestly, I couldn't care less about D so much as the principle that "Collaboration, should not erase ownership". Nobody has ever demonstrated why it should - most likely, because it's not a valid principle. It's sad that a discussion on this principle has to always get derailed. A few are already trying hard to do that.
Oct 29
On Wednesday, 29 October 2025 at 09:17:19 UTC, Serg Gini wrote:On Wednesday, 29 October 2025 at 09:06:57 UTC, claptrap wrote:On Wednesday, 29 October 2025 at 01:32:38 UTC, Peter C wrote:On Wednesday, 29 October 2025 at 01:18:42 UTC, Lance BachmeierWe are all mostly just talking to ourselves.Happy now?How long time ago you started talking with yourself? xD
Oct 29
On Wednesday, 29 October 2025 at 01:32:38 UTC, Peter C wrote:Nobody has ever demonstrated why it should - most likely, because it's not a valid principle.Current design is valid, because it works.
Oct 29
On Wednesday, 29 October 2025 at 01:18:42 UTC, Lance Bachmeier wrote:The problem with your approach is that you're proposing a major change to the language....Actually, that really is not what I'm doing. What I am trying to do, is establish a set of principles that people can agree on. That what is difficult. Getting it the language is pretty simple, if the principles are sound, and people agree that they are sound. See me previous post just know as to what those 2 principles are. Those 2 principles already exist in D. All I'm asking, is why does D need to discard those 2 principles for code inside a module? I prefer a consistent mental model based on principles that don't get discarded - just for convenience.
Oct 29
On Tuesday, 28 October 2025 at 22:36:58 UTC, Lance Bachmeier wrote:[snip] Over the years this has come up many times. Can you provide an example showing the value of doing that? I understand that maybe that's your preference for whatever valid reason, but I've never seen anyone give an example where it's actually a constraint. If you want to push on this, that's where you should start. Because every previous such proposal I've seen has died, as the people requesting it keep arguing from authority that it's the correct way to do things, rather than demonstrating the benefit of a major change to the language.I should preface this by repeating again that I really don't care about whether to make this change... You say it's a "major change to the language". Is it really? I thought `private(this)` was added to Open D without much difficulty. The whole argument as I see it is: a) the proponents saying they want this feature so that other code in a module can't reach into their classes/structs (I don't think there is a good argument that they shouldn't care about this, hence...) b) the other side saying that the workaround is putting the class into a separate module and importing (there are also - what I view as - secondary arguments that 1) there is a mental complexity budget for the language and 2) each language addition requires thinking about how it impacts all the other features), and c) the proponents saying they want to organize the code in one module and not split it up. The proponents could add on that it's a little more complicated than just putting the class into its own module (and it's each class you want to enforce this on). For instance, what if what you want is a module with function A that is used by class B, which you want to be the equivalent of `privateScope` (or whatever it gets called), and then there is also a function C uses both function A and class B. If you move class B into its own module, then it will need to import the original module to get access to function A. It's considered best practices not to have circular dependencies (and not possible under some conditions), so you may want to move function A into its own module too. So they may have to do more than just move the classes you want to enforce this restriction on into separate modules. It's also occasionally more difficult to split up code into multiple modules. For instance, what if you are prototyping something in run.dlang.io (impossible I think in this case) or what if you just want a small command line script. Of course the obvious reply is why are you doing something sophisticated enough to require this kind of access control in scripts. With respect to the secondary arguments: 1) On the mental complexity budget issue, I don't view that as a big issue as it is a convenient extension of the protection modifiers. `protected` and `package` are probably more confusing than this. 2) On the language feature interaction issue, maybe this is a concern, but I don't know enough about the compiler internals to say how significant it is. The language already has access modifiers. `private` is already implemented. This is a more of a limited version of `private`. I wouldn't think it would cause too many problems beyond those related to `private`. It would need to be included with the `getVisibility` trait and I'm not sure offhand how that would impact downstream code. What I think is the best practical argument against this feature is that making the language change requires people to do it and the people who would usually do it are busy with other things they think are more important. This is a good argument. I think the people who favor this change should be responsible for writing the DIP and getting it implemented. How about DIP approval conditional on implementation? And maybe delayed until after editions are implemented.
Oct 29
On Wednesday, 29 October 2025 at 13:55:42 UTC, jmh530 wrote:You say it's a "major change to the language". Is it really? I thought `private(this)` was added to Open D without much difficulty.It's a change to the grammar, which means that all parser-based tooling (DCD, DScanner, serve-d, etc.) would need to be updated to support it.It's also occasionally more difficult to split up code into multiple modules. For instance, what if you are prototyping something in run.dlang.io (impossible I think in this case)You can actually have multiple modules on run.dlang.io, using the following syntax: --- lib.d module lib; int fun() { return 42; } --- app.d module app; import lib; void main() { assert(fun() == 42); }With respect to the secondary arguments: 1) On the mental complexity budget issue, I don't view that as a big issue as it is a convenient extension of the protection modifiers. `protected` and `package` are probably more confusing than this.language design. If you don't take this seriously, your language ends up like C++ or Perl--a huge mess that nobody really understands completely. (You could argue that D has already crossed this line, but even if that's true, it doesn't mean we should make it worse.) Even features that are small and simple in isolation can add up to an enormous amount of complexity if you accumulate too many of them (see: Perl). So the fact that this individual feature is relatively simple is not a strong counterargument.
Oct 29
On Wednesday, 29 October 2025 at 16:18:22 UTC, Paul Backus wrote:On Wednesday, 29 October 2025 at 13:55:42 UTC, jmh530 wrote:Hmm, I don't have a sense of how much of a lift that is. But I think it comes back to putting the burden on the people who support the DIP. Make a list of tools that need to be updated and say the DIP is only approved if they update those to support it.You say it's a "major change to the language". Is it really? I thought `private(this)` was added to Open D without much difficulty.It's a change to the grammar, which means that all parser-based tooling (DCD, DScanner, serve-d, etc.) would need to be updated to support it.Sorry, I think I knew this but had forgotten. (Jonathan Marler who wrote the HAR code left the D community for Zig, might be something that the DLF could take over)It's also occasionally more difficult to split up code into multiple modules. For instance, what if you are prototyping something in run.dlang.io (impossible I think in this case)You can actually have multiple modules on run.dlang.io, using the following syntax: --- lib.d module lib; int fun() { return 42; } --- app.d module app; import lib; void main() { assert(fun() == 42); }The optimal amount of complexity isn't zero. Obviously. As with all things, there is a trade-off, whether that's against performance, expressiveness, etc. If all you care about is complexity, then you would never add any new features. It's an argument for setting things in stone (and I thought the whole point of editions was to allow the language to evolve). The argument about complexity is most convincing when it is phrased like "this feature adds complexity without generating enough of an improvement in performance/expressiveness/etc" (or from a second-level basis something like if we add this feature now then it may place a higher burden on adding additional features). In this sense, it is a question of marginal cost (complexity) vs. marginal benefit (performance/expressiveness/etc). On the marginal cost side, there are lots of different kinds of complexity. What you responded to was me talking about cognitive complexity. I happen to think that's really small here. But people can disagree. The complexity I would be more worried about is the impact on the compiler code base. I don't have the ability to speak to that, but I take people like Dennis and Walter at their word that it's something to be concerned about. But if the argument against it is that complexity will increase, then the argument carries more weight if we can spell out more concretely how it will increase. On the marginal benefit side, there are clearly people out there pounding the table for this feature, even if it's not that important to most. My point is that I don't think it's a slam dunk in favor of adding this feature, or for that matter saying no. I think it's something that should get weighed. This complexity vs. expressiveness trade-off shows up in a number of places in D. The string interpolation debate was one example where a less complex solution was proposed and was loudly shouted down in favor of a more complex and more expressive solution (and led to the creation of openD). When DIP1000 was originally discussed, the approach was argued for as less complex than a more generally expressive approach. And we're still debating these issues now, like 9 years later. Sometimes the more expressive approach will be less demanding from a cognitive perspective, even if it is more complex to implement. At the top I said the optimal amount of complexity isn't zero. Even something like the trade off between complexity and performance/expressiveness/etc., we would be trying to evaluate the language on a more-or-less objective basis. Another way to think about it is whether adding a feature will mean more projects get written in D than otherwise (or even better consider something similar that incorporates profits or some measure of value-add) (note: I don't mean actual people writing actual projects per se, so much as hypothetical people writing hypothetical projects). This could also account for second order effects where if the feature makes D harder to implement other new features or have higher cognitive load, then it would impact the trajectory. This framework would suggest that if has a first order impact of getting more people to write more D projects (esp. if they are projects with positive value-add) with limited second order impact, then it should be given a reasonable considered, especially with Editions being added to the language. The D leadership has built a really cool programming language, but it's still a niche programming language. And I don't see much on the horizon to change that. If they want it to stay a niche language, then that's fine. If they want to make it a more popular language, then they might need to change the way they think about some of these issues.With respect to the secondary arguments: 1) On the mental complexity budget issue, I don't view that as a big issue as it is a convenient extension of the protection modifiers. `protected` and `package` are probably more confusing than this.language design. If you don't take this seriously, your language ends up like C++ or Perl--a huge mess that nobody really understands completely. (You could argue that D has already crossed this line, but even if that's true, it doesn't mean we should make it worse.) Even features that are small and simple in isolation can add up to an enormous amount of complexity if you accumulate too many of them (see: Perl). So the fact that this individual feature is relatively simple is not a strong counterargument.
Oct 29
On Wednesday, 29 October 2025 at 19:59:15 UTC, jmh530 wrote:The D leadership has built a really cool programming language, but it's still a niche programming language. And I don't see much on the horizon to change that. If they want it to stay a niche language, then that's fine. If they want to make it a more popular language, then they might need to change the way they think about some of these issues.Thanks. This is well thought analysis. I think the question of personality (author of proposal) is also important. Proposals from well-known: - compiler/phobos contributors - library creators - ecosystem maintainers (thanks for maintaining Mir btw) have different "weight" than from "first time forum poster 3 days ago" or from forkit/claptrap. That's why the comparison of the situation with i-strings when it was a discussion between Paul, Adam, Steven, Timon and Walter has nothing to do with messages that popping up every year from the same one single person. So the pushback in the current situation is understandable. But do you personally jmh530 think that this is the main issue that core developers need to spend their time (even for analysis and consideration)? I don't think that adding class-private will change anything in D popularity and ability to bring attention from wider range of developers. And D has more important things to fix first.
Oct 29
On Wed, Oct 29, 2025 at 09:01:03PM +0000, Sergey via Digitalmars-d wrote: [...]I don't think that adding class-private will change anything in D popularity and ability to bring attention from wider range of developers. And D has more important things to fix first.Exactly. T -- Once the bikeshed is up for painting, the rainbow won't suffice. -- Andrei Alexandrescu
Oct 29
On Wednesday, 29 October 2025 at 21:01:03 UTC, Sergey wrote:[snip] have different "weight" than from "first time forum poster 3 days ago" or from forkit/claptrap. That's why the comparison of the situation with i-strings when it was a discussion between Paul, Adam, Steven, Timon and Walter has nothing to do with messages that popping up every year from the same one single person. So the pushback in the current situation is understandable.Are they the same person? I can't keep track. People should just stick with one ID. If it's just one person making a big deal about this, then it would change the calculus.But do you personally jmh530 think that this is the main issue that core developers need to spend their time (even for analysis and consideration)?I've been pretty clear on this thread that it's not something that's important to me and that all actual work on something like this should be pushed to the people who are advocating for it. Even in an ideal situation, core developers would still have to spend some time for evaluating the DIP.I don't think that adding class-private will change anything in D popularity and ability to bring attention from wider range of developers. And D has more important things to fix first.My point wasn't about class-private specifically. It was about more about a framework for thinking about changes to the language. Standing athwart history yelling stop isn't a good strategy for getting wider adoption. I wouldn't be the first person to say that when the D leadership team takes stances that push away effective contributors, then that has a big impact on the ecosystem.
Oct 29
On Thursday, 30 October 2025 at 03:00:02 UTC, jmh530 wrote:On Wednesday, 29 October 2025 at 21:01:03 UTC, Sergey wrote:I think it's unfair to judge all new questions with this lens, it's showing a bias that is not really focused on the topic at hand. Yes, there was an individual who posted with multiple account names, and this person continually brought up "scopeprivate" or "private(this)" or whatever new incarnation of this tired idea that D should adopt lest it leave behind the millions of developers just waiting to use the language as soon as this gets fixed. But I'm not totally convinced this latest handle is the same person, I will at least give that benefit of doubt. But that doesn't mean we have to keep entertaining the idea when it's been discussed to death. Bottom line: D has module private (similar to Java), and this is not going to change, no matter how many pleas are posted here. 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. This is the last time I'll post on this thread. And probably it should just be dropped. -Steve[snip] have different "weight" than from "first time forum poster 3 days ago" or from forkit/claptrap. That's why the comparison of the situation with i-strings when it was a discussion between Paul, Adam, Steven, Timon and Walter has nothing to do with messages that popping up every year from the same one single person. So the pushback in the current situation is understandable.Are they the same person? I can't keep track. People should just stick with one ID. If it's just one person making a big deal about this, then it would change the calculus.
Oct 29
On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer wrote:On Thursday, 30 October 2025 at 03:00:02 UTC, jmh530 wrote:unittests being able to access private data should be put within the scope of the type with that data. This presents a consistent mental model of encapsulation. My grip with D, is the mental model of encapsulation (that literally millions of programmers already have), is discarded just so D can say 'the module is the unit of encapsulation'. There is nothing wrong with D saying instead: That the module is the unit of encapsulation, however, user-defined types (specifically class and structs), can continue to maintain their own invariants when required, by using scopeprivate, and thus the two principles of (1) 'collaboration does not disolve ownership' and (2) 'make things open by default, restrict them only when you mean to', continue to remain true. To me, that is really not a contraversial idea. What is controversial to me, is that a module disolves the encapsulation of types. Perhaps what D should advertise instead, is: "The module is the unit of encapsulation in D, and thus it disolves the encapsulation of types". Good luck getting an audience with that ;-)On Wednesday, 29 October 2025 at 21:01:03 UTC, Sergey wrote:I think it's unfair to judge all new questions with this lens, it's showing a bias that is not really focused on the topic at hand. Yes, there was an individual who posted with multiple account names, and this person continually brought up "scopeprivate" or "private(this)" or whatever new incarnation of this tired idea that D should adopt lest it leave behind the millions of developers just waiting to use the language as soon as this gets fixed. But I'm not totally convinced this latest handle is the same person, I will at least give that benefit of doubt. But that doesn't mean we have to keep entertaining the idea when it's been discussed to death. Bottom line: D has module private (similar to Java), and this is not going to change, no matter how many pleas are posted here. 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. This is the last time I'll post on this thread. And probably it should just be dropped. -Steve[snip] have different "weight" than from "first time forum poster 3 days ago" or from forkit/claptrap. That's why the comparison of the situation with i-strings when it was a discussion between Paul, Adam, Steven, Timon and Walter has nothing to do with messages that popping up every year from the same one single person. So the pushback in the current situation is understandable.Are they the same person? I can't keep track. People should just stick with one ID. If it's just one person making a big deal about this, then it would change the calculus.
Oct 29
On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer 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: class Collection { int[] data; scopeprivate int _version; // it's vital here that Collection maintain control over this. scopeprivate makes that explicit and enforcable. This is a good thing, not a bad thing. this(int[] values) { data = values.dup; _version = 0; } void add(int value) { data ~= value; _version++; } int getVersion() { return _version; } } class CollectionIterator { private Collection coll; private size_t index; private int expectedVersion; this(Collection c) { coll = c; index = 0; expectedVersion = c.getVersion(); } bool hasNext() { checkForModification(); return index < coll.data.length; } int next() { checkForModification(); return coll.data[index++]; } private void checkForModification() { if (coll.getVersion() != expectedVersion) { throw new Exception("Collection modified during iteration!"); } } }
Oct 29
On Thursday, 30 October 2025 at 05:23:29 UTC, Peter C wrote:On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer wrote:And for those that argue.. well .. in Ada.. packages are the unit of encapsulation too.. so what's the big deal with D having choosing to have the module as the unit of encapsulation? I'd answer: it is very likely, that if Ada were designed today, in a world dominated by class-oriented programming, the designers would likely blend the two models: - Keep packages as the unit of modularity. - Give types the ability to maintain their own encapsulation boundary (so invariants are truly type‑owned) - ( which is what a 'scopeprivate' like attribute .. would do). Then D would align with the modern 'a class maintains its own invariants' model. Perhaps, that would attract more programmers to D - if indeed that's the objective (since most programmers live in a world where this is the model they work with). But I am genuinely open to listening to a good, rational argument, make no mistake about that. But the argument that we do it this way, and that's that, doesn't impress me. I will leave it here, as it's becoming pretty clear this is a dead issue in this forum. If programmers are happy with their types encapsulation boundary being disolved completely by the module, that is their perogative, I guess. But it's not the kind of code I want to be writing, reviewing, or maintaining.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: class Collection { int[] data; scopeprivate int _version; // it's vital here that Collection maintain control over this. scopeprivate makes that explicit and enforcable. This is a good thing, not a bad thing. this(int[] values) { data = values.dup; _version = 0; } void add(int value) { data ~= value; _version++; } int getVersion() { return _version; } } class CollectionIterator { private Collection coll; private size_t index; private int expectedVersion; this(Collection c) { coll = c; index = 0; expectedVersion = c.getVersion(); } bool hasNext() { checkForModification(); return index < coll.data.length; } int next() { checkForModification(); return coll.data[index++]; } private void checkForModification() { if (coll.getVersion() != expectedVersion) { throw new Exception("Collection modified during iteration!"); } } }
Oct 29
On Thursday, 30 October 2025 at 06:21:41 UTC, Peter C wrote:If programmers are happy with their types encapsulation boundary being disolved completely by the module, that is their perogative, I guess. But it's not the kind of code I want to be writing, reviewing, or maintaining.we're not holding you hostage. you are free to pick whatever language suits your needs. but as i said before, scopeprivate is as good as simply naming your internal variables int ___internal____dont_touch______abc; you can circumvent both.
Oct 30
On Thursday, 30 October 2025 at 06:21:41 UTC, Peter C wrote:And for those that argue.. well .. in Ada.. packages are the unit of encapsulation too.. so what's the big deal with D having choosing to have the module as the unit of encapsulation? I'd answer: it is very likely, that if Ada were designed today, in a world dominated by class-oriented programming, the designers would likely blend the two models: - Keep packages as the unit of modularity. - Give types the ability to maintain their own encapsulation boundary (so invariants are truly type‑owned) - ( which is what a 'scopeprivate' like attribute .. would do). Then D would align with the modern 'a class maintains its own invariants' model.There is nothing modern about this. It's just a *preference* thing. Also, did you ask the Ada devs whether they would even want that? Sure, it's an old language, but that doesn't mean much.
Oct 30
On Thursday, 30 October 2025 at 13:20:34 UTC, Kapendev wrote:On Thursday, 30 October 2025 at 06:21:41 UTC, Peter C wrote:That's where I strongly disagree. The lessons from the Swift community is there for everyone to see - and learn from. It wasn't just a matter of preference. Public by default or private by default, that is a matter of preference. Removing the concept of an encapsulated type... that is in a whole different ballpark. It was the Swift programmers, not the language designers, that eventually got Swift corrected (from the perspective of the programmers) - in line with what (a majority of) programmers expected, and not what the designers wanted. It's not that scopeprivate is a bad idea. It's that D doesn't have a majority of programmers who think its a bad idea .. and likely never will. But if it does, then I'll be the first to say .."I told you so" ;-)And for those that argue.. well .. in Ada.. packages are the unit of encapsulation too.. so what's the big deal with D having choosing to have the module as the unit of encapsulation? I'd answer: it is very likely, that if Ada were designed today, in a world dominated by class-oriented programming, the designers would likely blend the two models: - Keep packages as the unit of modularity. - Give types the ability to maintain their own encapsulation boundary (so invariants are truly type‑owned) - ( which is what a 'scopeprivate' like attribute .. would do). Then D would align with the modern 'a class maintains its own invariants' model.There is nothing modern about this. It's just a *preference* thing. Also, did you ask the Ada devs whether they would even want that? Sure, it's an old language, but that doesn't mean much.
Oct 30
On Thursday, 30 October 2025 at 21:30:16 UTC, Peter C wrote:.. It's not that scopeprivate is a bad idea. It's that D doesn't have a majority of programmers who think its a bad idea .. and likely never will.oops. I flipped that the wrong way ;-)
Oct 30
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: ```d --- 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]); } } ```
Oct 30
On Thursday, 30 October 2025 at 13:31:48 UTC, Zealot wrote:On Thursday, 30 October 2025 at 06:21:41 UTC, Peter C 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 => 44But 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: ```d --- 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]); } } ```
Oct 30
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: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.[...]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
Oct 30
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: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.On Thursday, 30 October 2025 at 13:31:48 UTC, Zealot wrote: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.[...]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
Oct 30
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: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; } } ```
Oct 30
```
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
Oct 30
On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer wrote:I think it's unfair to judge all new questions with this lens, it's showing a bias that is not really focused on the topic at hand.Thank you. I agree I didn’t mean newcomers can’t make valuable proposals and ideas. And newcomers of course more than welcome :) Just the whole current of discussion from topic starter shows the same style as original claptrap had. I also agree that closing this thread would be the most proper solution to eliminate further distraction.
Oct 30
On Thursday, 30 October 2025 at 07:09:22 UTC, Sergey wrote:On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer wrote:I have never argued for class private, search the forum and find a message where I have. I think you missed the sarcasm in my earlier post in this thread. IE, he says he doesnt care about D and yet posts over and over about this one topic. Hence my sarcastic "yes you're absolutely right, are you happy now?" If it's true he doesnt care about D, as he claims, the only other interpretation of his behaviour is that he's desperate for someone to tell him that he is right. He's the archetypal xkcd "Someone is WRONG on the internet".I think it's unfair to judge all new questions with this lens, it's showing a bias that is not really focused on the topic at hand.Thank you. I agree I didn’t mean newcomers can’t make valuable proposals and ideas. And newcomers of course more than welcome :) Just the whole current of discussion from topic starter shows the same style as original claptrap had.
Oct 30
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.
Oct 30
On 31/10/2025 4:03 AM, Dom DiSc wrote:On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer wrote: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.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.
Oct 30
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: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”. ;)On Thursday, 30 October 2025 at 03:48:01 UTC, Steven Schveighoffer wrote: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.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.
Oct 30
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
Oct 30
On Thu, Oct 30, 2025 at 05:53:15PM +0000, Steven Schveighoffer via Digitalmars-d wrote:On Thursday, 30 October 2025 at 16:02:36 UTC, jmh530 wrote:lol, to further distance ourselves from C++, we should introduce the 'enemy' keyword in lieu of 'friend'. :-PSteve’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.Yes. Though we already have a related (but tangential) issue with this inside templated aggregates: if the template never gets instantiated, none of the unittest blocks inside it would ever instantiate. And the unittests would also instantiate multiple times, once per instantiation, which leads to a lot of bloat when the tests don't actually depend on the template arguments of the current instantiation (i.e., they manually specify specific instantiations that they are testing).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.[...] Do I smell a further abu^Wextension of the 'static' keyword to prevent unittests from accessing private members? ;-) ```d /// Your average typical ddoc'd aggregate struct Stuff { private int x; /// Your average typical member function void member() {} /// My awesome ddoc'd unittest! static unittest { Stuff s; s.x; // error: cannot access private member x } } ``` T -- Synonym rolls: just like grammar used to make them.
Oct 30
On Thursday, 30 October 2025 at 17:53:15 UTC, Steven Schveighoffer wrote: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.I'd say it's not wrong, private members should be documented. The problem looks more like ddoc doesn't differentiate between public and private documentation.
Oct 30
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.
Oct 30
On Friday, 31 October 2025 at 00:50:54 UTC, Walter Bright wrote:On 10/29/2025 8:48 PM, Steven Schveighoffer wrote:I've already started replying again, even though I said I wouldn't, but this is an important point to get right, Walter. I agree normal unittests should be able to access private members, I said as much in the second paragraph above. What we are talking about is *documented* unittests. Consider the following documented unittest: ```d private int foo(int x) => 2 * x; /// Do some interesting stuff public int doStuff() => 42; /// How to use doStuff unittest { auto val = doStuff(); assert(foo(val) == 84); } ``` Now, what happens here is that the ddoc system will show the documented unittest for `doStuff` in the documentation for it. But it has used a private function! The user has to go look at the source code of the module, to understand what `foo` actually does, to undestand what `doStuff` actually does. The point of a documented unittest is to show to a user how a function works. If it is using private undocumented symbols, then the user is clueless as to what it means. So my recommendation would be to either ban private symbol use in documented unittests, or to provide a mechanism to allow unittests to be banned from using private symbols (maybe `public unittest`? I don't know) Note that we had problems with code on dlang.org for years on this front, and it was finally solved by writing a tool that parses d code, and outputs all the unittests as external functions to ensure they aren't using private symbols. See the code here: https://github.com/dlang/tools/blob/master/tests_extractor.d It would be very nice if we didn't have to do this extra step. -SteveThere 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.
Oct 30
Thank you, I did misunderstand your point. You're correct on all counts.
Oct 31
On Friday, 31 October 2025 at 00:50:54 UTC, Walter Bright wrote:On 10/29/2025 8:48 PM, Steven Schveighoffer wrote: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)); }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.
Oct 30
On Wednesday, 29 October 2025 at 19:59:15 UTC, jmh530 wrote:... The complexity I would be more worried about is the impact on the compiler code base. I don't have the ability to speak to that, but I take people like Dennis and Walter at their word that it's something to be concerned about. But if the argument against it is that complexity will increase, then the argument carries more weight if we can spell out more concretely how it will increase.Here there may well be an argument to make. Although it took me less than an hour to implement scopeprivate, I cannot really judge its impact on the rest of the compiler code. So I agree, that could be a concern. But even then, is that a problem with the idea of scopeprivate, or the complexity in the compilers code, or the enourmous amount of features it already has to implement. I'd say the 'idea itself' - of scopeprivate, is the less concerning issue here.This complexity vs. expressiveness trade-off shows up in a number of places in D ...It's also about local reasoning, which is hard to do when the encapsulation barrier of the module supercedes the encapsulation barrier of your type. Swift made the same mistake - and had to correct it. Good on them for having the courage to go all the way, instead of just implementing scopeprivate (i.e. reverting private to what the mental model that programmers held, and introducing fileprivate. Here's a nice talk, although a little drawn-out, about the importance of being able to reason locally. https://youtu.be/bhizxAXQlWc
Oct 30
On Wednesday, 29 October 2025 at 16:18:22 UTC, Paul Backus wrote:.. language design. If you don't take this seriously, your language ends up like C++ or Perl--a huge mess that nobody really understands completely. (You could argue that D has already crossed this line, but even if that's true, it doesn't mean we should make it worse.) Even features that are small and simple in isolation can add up to an enormous amount of complexity if you accumulate too many of them (see: Perl). So the fact that this individual feature is relatively simple is not a strong counterargument.There is nothing complex about scopeprivate. That's yet another strawman arguement. scopeprivate fits absolutely perfectly with D's principle: "make things open by default, restrict them only when you mean to." it also fits absolutey perfectly with the principle that: "Collaboration does not disolve ownership" - which already applies with to private, package and public - with the unfortunate scenario that it suddenly no longer applys anymore when more than one type is within a module, or a type and a helper method, or a type and a unittest. scopeprivate restores a consistency mental model. It's also about balancing the safe use of a type, with practical collaboration. It's a little bewildering to my why that would be so controversial. And really, if scopeprivate produces cognitive overload in a programmers brain, they probably should choose another profession.
Oct 29
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: ```d 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 } ```
Oct 30
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.
Oct 30
On Thursday, 30 October 2025 at 11:30:47 UTC, Arafel wrote:On 10/30/25 11:20, Zealot wrote:the difference is that nothing is stopping you from simply editing the class, when you edit the file anyway, so the protection would just prevent accidental use. there'S also nothing stopping you from not using scopeprivate, that is also just a convention you'd have to use. sure the compiler would enforce it, but the point is: it's a non issue for it not to do so.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.
Oct 30
On Thursday, 30 October 2025 at 11:30:47 UTC, Arafel wrote:On 10/30/25 11:20, Zealot wrote: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.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.
Oct 30
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:`_____` is a beautiful name. Kinda hard to guess how many `_` there are. Maybe `_696969` is a better name.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: ```d 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 } ```
Oct 30
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`.
Oct 30
On Wednesday, 29 October 2025 at 13:55:42 UTC, jmh530 wrote:On Tuesday, 28 October 2025 at 22:36:58 UTC, Lance Bachmeier wrote:the thing is, it doesnt actually solve anything. if you have access to the module, you can simply change the class to gain access. you can simply cast the class to something. so all it really does it prevent accidential use. and you can have the same thing by just naming your variables accordingly. the whole thing only makes sense when you have a closed 'module' someone else accesses without the ability to edit it. and we have that. also every language addition (even minor ones) make the language very complex and harder to maintain and understand.[...]I should preface this by repeating again that I really don't care about whether to make this change... [...]
Oct 29
On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.You are correct on this.
Oct 28
On Tuesday, 28 October 2025 at 13:25:42 UTC, jmh530 wrote:On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:He's been attacking a strawman. Nobody asked for friend classes. People have been asking for the ability to restrict access to non-friend class members inside a module. Even Rust gives you that by allowing struct implementations in in-file submodules. (Dislaimer: I don't care about "class-private".)I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.You are correct on this.
Oct 28
On Tuesday, 28 October 2025 at 16:26:57 UTC, Max Samukha wrote:On Tuesday, 28 October 2025 at 13:25:42 UTC, jmh530 wrote:More of a slippery slope than a strawman. ;)On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:He's been attacking a strawman. Nobody asked for friend classes. People have been asking for the ability to restrict access to non-friend class members inside a module. Even Rust gives you that by allowing struct implementations in in-file submodules. (Dislaimer: I don't care about "class-private".)I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.You are correct on this.
Oct 28
On Tuesday, 28 October 2025 at 16:26:57 UTC, Max Samukha wrote:On Tuesday, 28 October 2025 at 13:25:42 UTC, jmh530 wrote:I think that 'Disclaimer' misses the point of this thread. In my view, the [internal aspect of a] module should represent a 'collaboration boundary', not an 'ownership boundary'. That is the real distinction I'm trying to make. This is where different perspectives should take their positions. It just so happens that I'm using a class type here, but it could be any type. One side of the argument is: If you put related types in the same module, they should own each other. I say no - actually, I put them in the same module because they needed to collaborate much more closely than they would be able to if they were not in the same module. But they certainly do not need to own each other. I have not seen any valid argument, for why 'they should own each other'.On Tuesday, 28 October 2025 at 02:28:41 UTC, Walter Bright wrote:He's been attacking a strawman. Nobody asked for friend classes. People have been asking for the ability to restrict access to non-friend class members inside a module. Even Rust gives you that by allowing struct implementations in in-file submodules. (Dislaimer: I don't care about "class-private".)I know you didn't propose this, but I had quite enough of C++'s "friend" classes. I've never missed that misfeature in D.You are correct on this.
Oct 28
On Tuesday, 28 October 2025 at 22:16:19 UTC, Peter C wrote:One side of the argument is: If you put related types in the same module, they should own each other. I say no - actually, I put them in the same module because they needed to collaborate much more closely than they would be able to if they were not in the same module. But they certainly do not need to own each other. I have not seen any valid argument, for why 'they should own each other'.Then use packages, not modules, and you'll get the properties you want. Have modules encapsulate a single type with friends instead, or a set of overly friendly types not privy to messing with each one around behind the back of other colleagues (types) in the code. You can then have package act as a module when imported somewhere else. Over-fixating on why you cant have it all in a single module will only lead to unnecessary frustration (seen it here before). Best regards.
Oct 28
On Tuesday, 28 October 2025 at 22:51:35 UTC, Alexandru Ermicioi wrote:.. Over-fixating on why you cant have it all in a single module will only lead to unnecessary frustration (seen it here before). Best regards.yet another strawman argument. I believe Walter touched on this strawman argument also - https://forum.dlang.org/post/10dpahf$1dgm$1 digitalmars.com You can have a 10,000 line module with or without scopeprivate. And I believe some already exist - or close to it. See my previous response just now, as to what the discussion should really be about: https://forum.dlang.org/post/vdigkqqodpqvakmytcbr forum.dlang.org
Oct 28
On Tuesday, 28 October 2025 at 23:28:32 UTC, Peter C wrote:yet another strawman argument.That was a genuine recommendation to get you out of the rut. In D, the notion of module is clear and well defined. If you want it changed, you'll probably need provide real use benefits to convince people. A simple, "this is right use of module/encapsulation concept in my mind", is not enough, especially when current state doesn't really prevent you achieve what you need, albeit in a different form than a single file. Wish you well, Alexandru.
Oct 29
On Sunday, 26 October 2025 at 14:55:07 UTC, Steven Schveighoffer wrote:On Sunday, 26 October 2025 at 06:33:11 UTC, Peter C wrote:To be fair, it keeps coming up because people (not me!) say they want the feature and the reasons for being opposed to it have never been that great. The people opposed say D’s unit of encapsulation is the module, great, but what you’re really doing is presuming a paradigm of programming that is different from how they want to work. If D advertises itself as a multi-paradigm language that supports object-oriented programming and a bunch of object oriented programmers say they want scopePrivate / privateScope (and several get upset and leave the community), then it doesn’t really come across as that supportive of the paradigm.Among D developers, the idea of adding a new visibility attribute like scopeprivate often meets with scepticism. After all, D already has private for module-level encapsulation and package for sharing across sibling modules. And if you really want to lock a class down, you can always put it in its own module. So why bother? [...]This has been proposed and rejected many times. In D private is for the module. This is intentional. -Steve
Oct 27
On 10/27/2025 6:19 PM, jmh530 wrote:To be fair, it keeps coming up because people (not me!) say they want the feature and the reasons for being opposed to it have never been that great. The people opposed say D’s unit of encapsulation is the module, great, but what you’re really doing is presuming a paradigm of programming that is different from how they want to work. If D advertises itself as a multi-paradigm language that supports object-oriented programming and a bunch of object oriented programmers say they want scopePrivate / privateScope (and several get upset and leave the community), then it doesn’t really come across as that supportive of the paradigm.D is also regularly accused of supporting too many paradigms. For example, GC is optional in D. But some people do not want it optional, they want it to not be there. Hence, -betterC. But D gets criticized for that, too. There's no way to please everybody. I wish there was. I've programmed first in BASIC, then Fortran, then C, then C++, then Java, then Javascript, then D. My first Fortran programs looked like BASIC. My first C programs looked like Fortran, and so on. It's always off-putting at first, until it becomes natural and you're done with the previous way for good. In the olden days, file lookups were slow and it made sense to cram it all into a small number of source files. Those days are long gone now, and IDEs make navigating multiple source files super easy. Having the unit of encapsulation being the file which is the same as the module makes a great deal of sense. I.e. if you have a 10,000+ line module, it's likely time to consider dividing it into distinct modules, rather than dividing up the scopes in the file.
Oct 27
On Tuesday, 28 October 2025 at 02:41:51 UTC, Walter Bright wrote:On 10/27/2025 6:19 PM, jmh530 wrote:I think you're missing the point here. public class BankAccount { private double balance; // hidden? public void deposit(double amount) { balance += amount; } public double getBalance() { return balance; } } A typical programmers mental model of this type is: "I can deposit and check balance, but I cannot directly mess with the balance field." But in D, this mental model no longer holds - for those millions of programmers who share the same mental model as I do - when other code is within the same module (even just unittests!) The internal state of this type, in D, 'automatically' leaks into the rest of the module. D does not give the programmer explicit control over this. The language itself takes control. Cognitive load is automatically increased, as the programmer needs to study the details of the other code in the module, to see when this types 'apparent' contract holds, and when it does not. Cognitive Load Reduction: With 'scopeprivate', the programmers desire to restrict access to a member does not need to be 'simulated' through 'one class modules', or via _conventions. And, the internal state of these scopeprivate members would no longer 'automatically' leak into the rest of the module. scopeprivate is not some weird concept. Millions of programmers using the most widely used languages today (and even some of those being developed as successor languages - Carbon for example), already have this mental model. Swift's mental-model-breaking implementation of private, was also controversial in the early stages of its development/evolution. Personally, I think they should have left private as they originally implemented it in Swift (meaning private to the file), and just added scopeprivate. That would have avoided a lot of the controversy over the change, and everyones code would have still compiled just as it did before they added scopeprivate. So, getting back to my initial point - for you to dismiss the idea of scopeprivate, as 'well, you can't please everybody', just sound disingenous to me. What is the reason then? I can probably rule out one - It's too difficult/complex to implement and maintain? Well, with no compiler experience whatsoever, I was able to implement scopeprivate in less than an hour. None of my extensive tests have (yet) shown even the slightest problem with my implementation. I've actually found it very pleasant to work with - better than 'private(this)', and I can just use "scopeprivate:" at the start of class type (so only ever need to type it once per class implementation. Conceptually, it works well as it fits my mental model, and programmatically it works well also. The module boundary of the member is not affected, unless the programmer opts-in to using scopeprivate. There are no breaking changes. Everyones code will still compile. So what's the problem then? Slightly off topic now: Here is a nice talk - https://youtu.be/gG4BJ23BFBE - regarding C++'s need for a successor. Even after more that two decades of devlopment, the D Programming Language didn't even get a single mention. It's not that it was mentioned and then discarded as not being a suitable succesor for this or that reason, it just wasn't mentioned. Not even a mention from the audience at question time. This was just last year! I was pretty suprised by this actually. I'd love to ask Helge Penne why he never mentioned the D Programming Language.To be fair, it keeps coming up because people (not me!) say they want the feature and the reasons for being opposed to it have never been that great. The people opposed say D’s unit of encapsulation is the module, great, but what you’re really doing is presuming a paradigm of programming that is different from how they want to work. If D advertises itself as a multi-paradigm language that supports object-oriented programming and a bunch of object oriented programmers say they want scopePrivate / privateScope (and several get upset and leave the community), then it doesn’t really come across as that supportive of the paradigm.D is also regularly accused of supporting too many paradigms. For example, GC is optional in D. But some people do not want it optional, they want it to not be there. Hence, -betterC. But D gets criticized for that, too. There's no way to please everybody. I wish there was. I've programmed first in BASIC, then Fortran, then C, then C++, then Java, then Javascript, then D. My first Fortran programs looked like BASIC. My first C programs looked like Fortran, and so on. It's always off-putting at first, until it becomes natural and you're done with the previous way for good. In the olden days, file lookups were slow and it made sense to cram it all into a small number of source files. Those days are long gone now, and IDEs make navigating multiple source files super easy. Having the unit of encapsulation being the file which is the same as the module makes a great deal of sense. I.e. if you have a 10,000+ line module, it's likely time to consider dividing it into distinct modules, rather than dividing up the scopes in the file.
Oct 27
On Tuesday, 28 October 2025 at 06:47:14 UTC, Peter C wrote:Conceptually, it works well as it fits my mental model, andGood for you!programmatically it works well also. The module boundary of the member is not affected, unless the programmer opts-in to using scopeprivate. There are no breaking changes. Everyones code will still compile. So what's the problem then?There is no problems as I can see. You wanted this feature - you've implemented it and now you can use it. It's not going to happen in upstream D. You can speak with Adam and try to include it into OpenD.Slightly off topic now: Even after more that two decades of devlopment, the D Programming Language didn't even get a single mention. It's not that it was mentioned and then discarded as not being a suitable succesor for this or that reason, it just wasn't mentioned. Not even a mention from the audience at question time. This was just last year! I was pretty suprised by this actually.The real reason : https://x.com/cyrus_msk/status/1855399721998876761
Oct 28
On Tuesday, 28 October 2025 at 06:47:14 UTC, Peter C wrote:Even after more that two decades of devlopment, the D Programming Language didn't even get a single mention. It's not that it was mentioned and then discarded as not being a suitable succesor for this or that reason, it just wasn't mentioned. Not even a mention from the audience at question time. This was just last year! I was pretty suprised by this actually. I'd love to ask Helge Penne why he never mentioned the D Programming Language.Please don't make it a popularity discussion because it will turn this forum post into a mess of random words. I think a good way of thinking about this is that some languages just do things in a specific way. Nothing wrong with that. You it like C++. All of these languages have OOP ideas, but they implement them in different ways.
Oct 28
On 10/27/2025 11:47 PM, Peter C wrote:Even after more that two decades of devlopment, the D Programming Language didn't even get a single mention. It's not that it was mentioned and then discarded as not being a suitable succesor for this or that reason, it just wasn't mentioned. Not even a mention from the audience at question time. This was just last year! I was pretty suprised by this actually. I'd love to ask Helge Penne why he never mentioned the D Programming Language.D has terrible marketing. Adding more features won't change that. What matters are people doing things with D, and then writing articles about it and posting them online. Lots of people are doing great things with D, but nobody writes articles about it. I've seen plenty of pretty lame articles about other languages posted online. There's no reason we cannot do better with this. People are willing to make presentations for Dconf. But none will take the next step and write an article about the contents of their presentation. I don't really understand that. Besides, writing programming articles is a great way for engineers to become known in the programming world, which means better opportunities and more pay!
Oct 28
On 10/27/2025 11:47 PM, Peter C wrote:The internal state of this type, in D, 'automatically' leaks into the rest of the module.Yes. If you want to hide the internals of a class, put it in its own module. The "friends" then can no longer access the internals.So what's the problem then?Every feature adds complexity. At some point, the language becomes unwieldy, where nobody knows the entire language, and people use only islands of it (see C++). Maintaining a language is always a battle with complexity. Having too many ways to accomplish the same goal is not very desirable. Your proposal does indeed have merit. But is it a big enough to justify a new keyword, and more documentation? The more pages a language spec has, the fewer people will read it. People love languages that can do a lot with very few pages. You could learn C in an hour reading K+R. I remember when Go was introduced and people loved that they could learn Go in just one lecture. It needs more to justify it. P.S. The major driver of the new "editions" feature is to enable us to remove features that do not carry their weight, and that have easy alternatives. It's not that they are useless features. It's just that features should have a big impact. For example, Manu and Timon convinced me that placement new would have a substantial impact on what could be done with D. P.P.S. I do appreciate the time you took to present your proposal. You've thought it out well. Thank you!
Oct 28
On Tuesday, 28 October 2025 at 08:37:46 UTC, Walter Bright wrote:On 10/27/2025 11:47 PM, Peter C wrote:Your position is clear, and I won't push it further. When a programming language actively and intentionally prevents me from being explicit about how the members of my class can be accessed, the programming language becomes irrelevant to me. Taking away a tool that millions of programmers use, it not going to get D the audience it 'supposedly' desires. I can't even do this in D! // 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)); } seek a successor language ;-) Good luck with the future of your language.The internal state of this type, in D, 'automatically' leaks into the rest of the module.Yes. If you want to hide the internals of a class, put it in its own module. The "friends" then can no longer access the internals.So what's the problem then?Every feature adds complexity. At some point, the language becomes unwieldy, where nobody knows the entire language, and people use only islands of it (see C++). Maintaining a language is always a battle with complexity. Having too many ways to accomplish the same goal is not very desirable. Your proposal does indeed have merit. But is it a big enough to justify a new keyword, and more documentation? The more pages a language spec has, the fewer people will read it. People love languages that can do a lot with very few pages. You could learn C in an hour reading K+R. I remember when Go was introduced and people loved that they could learn Go in just one lecture. It needs more to justify it. P.S. The major driver of the new "editions" feature is to enable us to remove features that do not carry their weight, and that have easy alternatives. It's not that they are useless features. It's just that features should have a big impact. For example, Manu and Timon convinced me that placement new would have a substantial impact on what could be done with D. P.P.S. I do appreciate the time you took to present your proposal. You've thought it out well. Thank you!
Oct 28
On Tuesday, 28 October 2025 at 20:59:06 UTC, Peter C wrote:seek a successor language ;-) Good luck with the future of your language.Different tools, different philosophies. Good luck.
Oct 28
On Tuesday, 28 October 2025 at 20:59:06 UTC, Peter C wrote:When a programming language actively and intentionally prevents me from being explicit about how the members of my class can be accessed, the programming language becomes irrelevant to me.Does that mean you're going to stop posting about it?
Oct 28
On Tuesday, 28 October 2025 at 23:30:36 UTC, Paul Backus wrote:On Tuesday, 28 October 2025 at 20:59:06 UTC, Peter C wrote:We should set up a forum called D Apostates, there could be an "Introduce Yourself" thread where you say why you stopped using D and what language you're switching to.When a programming language actively and intentionally prevents me from being explicit about how the members of my class can be accessed, the programming language becomes irrelevant to me.Does that mean you're going to stop posting about it?
Oct 29
On Wednesday, 29 October 2025 at 16:20:35 UTC, Abdulhaq wrote:On Tuesday, 28 October 2025 at 23:30:36 UTC, Paul Backus wrote:Significant cases are well knownOn Tuesday, 28 October 2025 at 20:59:06 UTC, Peter C wrote:We should set up a forum called D Apostates, there could be an "Introduce Yourself" thread where you say why you stopped using D and what language you're switching to.When a programming language actively and intentionally prevents me from being explicit about how the members of my class can be accessed, the programming language becomes irrelevant to me.Does that mean you're going to stop posting about it?
Oct 29
On Tuesday, 28 October 2025 at 01:19:27 UTC, jmh530 wrote:To be fair, it keeps coming up because people (not me!) say they want the feature and the reasons for being opposed to it have never been that great. The people opposed say D’s unit of encapsulation is the module, great, but what you’re really doing is presuming a paradigm of programming that is different from how they want to work. If D advertises itself as a multi-paradigm language that supports object-oriented programming and a bunch of object oriented programmers say they want scopePrivate / privateScope (and several get upset and leave the community), then it doesn’t really come across as that supportive of the paradigm.D is secretly the **MOST** opinionated language ever made #exposed #real ... No memes now, but OOP as a term is overloaded with ideas, so you could go on and on about what is missing and what is not in D.
Oct 28
I'd like to say that I'd much rather see this as protected becoming non-mutually-exclusive with private, package, and public. It's already pretty much orthogonal to them and would have a very similar effect to scopeprivate without introducing a new keyword. This would make a private protected member only accessible to a subclass within the same module which would have to be a very deliberate choice (but not an invalid one, there can be uses for this, especially in recursive typed structure like ASTs). None of the semantics of the visibility modifiers particularly change and the use-case of scopeprivate is dealt with, for the most part.
Nov 02









"Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> 