digitalmars.dip.ideas - Limited friend access
- claptrap (23/23) Nov 29 limited friend access
- Peter C (13/36) Nov 29 Fine-grained, cross-module friends would introduce a complex
- claptrap (6/12) Nov 30 If you want criticise my idea have at it.
- Peter C (2/14) Nov 30 Fine. Good luck with your proposal ;-)
- Peter C (32/37) Nov 30 You opened your DIP idea with: "limited friend access ..Ok
- Peter C (84/87) Nov 29 To back up my previous post:
- Sergey (2/4) Nov 30 No thanks.
- Peter C (2/3) Nov 30 Thanks, for the thoughtful and well-reasoned response.
- Peter C (71/73) Nov 30 So you want 'encapsulation with selective sharing'. Am I correct?
- Serg Gini (2/2) Nov 30 On Monday, 1 December 2025 at 07:42:10 UTC, Peter C wrote:
- Atila Neves (3/12) Dec 01 What, in your opinion, is the problem with needing to put
- claptrap (3/17) Dec 01 In general nothing, in the specific case I have now, I just want
- Peter C (9/11) Dec 01 If you want to keep platform-specific code isolated in separate
- claptrap (2/14) Dec 01 I don't like those solutions. Do you have any alternatives?
- Peter C (3/20) Dec 01 Sure. Just keep on pushing for your 'Limited friend access'...
- claptrap (3/24) Dec 02 The last thing I want is for anyone to take anything I say
- Peter C (19/36) Dec 01 Well, if you're determined to access private members from outside
- claptrap (2/40) Dec 02 What about just using "package"? Simple no?
limited friend access
Ok everyone around here seems to think "friend classes" were a
mistake in C++. But I think the reason they are a problematic is
that they grant access carte blanche. It gives the friend
unfettered access to everything. It's like giving a friend keys
to your house, car, credit cars, account logins, power of
attorney, when you just want him to feed the cat while you're on
holiday.
So what about just granting access to specific parts.
private friend(Foo):
// Foo can see what's here
private:
// Foo cant see anything now
private friend(Foo) void doSomething() {} // Foo can see this
method
So you add "friend(ClassName,ClassName2...)" after an access
modifier and it applies either just for that declaration, or
until the next block modifier.
IE, you grant the class in question access only to specific
parts. You can design a fully encapsulated private API only for
the friend.
This would negate the need to put everything in one module, while
also allow much more fine grained API exposure.
Nov 29
On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:
limited friend access
Ok everyone around here seems to think "friend classes" were a
mistake in C++. But I think the reason they are a problematic
is that they grant access carte blanche. It gives the friend
unfettered access to everything. It's like giving a friend keys
to your house, car, credit cars, account logins, power of
attorney, when you just want him to feed the cat while you're
on holiday.
So what about just granting access to specific parts.
private friend(Foo):
// Foo can see what's here
private:
// Foo cant see anything now
private friend(Foo) void doSomething() {} // Foo can see this
method
So you add "friend(ClassName,ClassName2...)" after an access
modifier and it applies either just for that declaration, or
until the next block modifier.
IE, you grant the class in question access only to specific
parts. You can design a fully encapsulated private API only for
the friend.
This would negate the need to put everything in one module,
while also allow much more fine grained API exposure.
Fine-grained, cross-module friends would introduce a complex
non-local access graph that would be difficult to understand and
maintain.
It would be a threat to local reasoning - the most crucial
property of a maintainable encapsulation system!
Tight coupling belongs locally, inside the D module.
A 'Local Grant' model, like scopeprivate provides - in OpenD they
call it private(this), is the proper architectural solution here.
I think you're targeting the wrong problem. The real problem that
needs to be addressed here, lies inside the D module -> a class
cannot protect its internals even from its tightly coupled
neighbors in the same file.
Nov 29
On Saturday, 29 November 2025 at 23:16:35 UTC, Peter C wrote:On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:If you want criticise my idea have at it. If you want to waffle about your own pet grievance start your own thread. If the former, then a hard requirement is the classes in separate modules.limited friend accessA 'Local Grant' model, like scopeprivate provides - in OpenD they call it private(this), is the proper architectural solution here.
Nov 30
On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:On Saturday, 29 November 2025 at 23:16:35 UTC, Peter C wrote:Fine. Good luck with your proposal ;-)On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:If you want criticise my idea have at it. If you want to waffle about your own pet grievance start your own thread. If the former, then a hard requirement is the classes in separate modules.limited friend accessA 'Local Grant' model, like scopeprivate provides - in OpenD they call it private(this), is the proper architectural solution here.
Nov 30
On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:If you want criticise my idea have at it. If you want to waffle about your own pet grievance start your own thread. If the former, then a hard requirement is the classes in separate modules.You opened your DIP idea with: "limited friend access ..Ok everyone around here seems to think "friend classes" were a mistake in C++. But I think the reason they are a problematic is that they grant access carte blanche. It gives the friend unfettered access to everything. It's like giving a friend keys to your house, car, credit cars, account logins, power of attorney, when you just want him to feed the cat while you're on holiday." If you think about it, the D module does exactly that as well, only locally (do you disagree?). So my point was entirely valid as a response, as I'm on board with the same problem you've identified! So why are you critical of C++'s approach and not D's approach? The only difference in D, is that it is more localised.. but it's still grants access carte blanche. That is, in D, classes cannot collaborate via module-private fields, while still protecting sensitive state. It's not about hijacking your thread for a pet grievance. We're actually talking about the exact same problem .. "unfettered access to everything. " If you're 'hard requirement' is that classes be in separate modules, then that suggests to me they don't even need to be accessing each others internal anyway. So why would you want to negate the need to put them in the same module by introducing a complex relationship between classes in different modules, when the D module already provides this shared functionality, albeit, in a carte blanche way. The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.
Nov 30
On Sunday, 30 November 2025 at 21:36:13 UTC, Peter C wrote:On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote: The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.This is the first time I have heard someone like `private` this much. Clearly we have all been distracted by minor things like [IES](https://dlang.org/spec/istring.html) and [ImportC](https://dlang.org/spec/importc.html). Anyway, about the DIP. Not sure really. I don't use `private` that often to have a good opinion about this.
Nov 30
On Sunday, 30 November 2025 at 23:57:06 UTC, Kapendev wrote:.. This is the first time I have heard someone like `private` this much. Clearly we have all been distracted by minor things like [IES](https://dlang.org/spec/istring.html) and [ImportC](https://dlang.org/spec/importc.html). Anyway, about the DIP. Not sure really. I don't use `private` that often to have a good opinion about this.Neither istring nor importc is of any interest to me, personally, although i accept it interests others. As for private, well if you don't need to use private, so be it. But for those of us who see it as an engineering benefit, we do use it.. a lot. Inside a D module, where tightly coupled classes may well exist (and is the best place for them to exist), scopeprivate provides the means to preserve certain class invariants by not explosing those particular parts to other tightly coupled classes in the same module. This results in less accidental or unintentional coupling inside the module. It's actually good engineering - at least that's how I see it. It signals what is internal to the class, and what is shared, within the module. This drastically reduces the surface area of the class that developers need to worry about, making the code easier to read, understand, and use. So, I see both private and scopeprivatte, as providing a core engineering benefit. The alternative in D, without scopeprivate, is "unfettered access to everything.". I had actually suggested that C++ should have 'originally' done more or less what is being proposed by claptrap (although I can't find the forum reference as yet). But the problem claptrap hightlights for C++, is the problem I highlight for D. The only difference between claptrap and myself in this thread, is that I see the problem he is highlighting in C++, as the same problem 'inside' the D module - that is, "unfettered access to everything.". So we're sort of in agreement on what constitutes a problem here, but we're coming at it from very different perspectives and solutions. If something as simple as what scopeprivate cannot make it into 'official' D, after more that a decade of various people pushing for it - [and btw. it is already available in OpenD, as 'private(this) ], then claptraps proposal has ... what...more likelihood of succeeding?? claptrap and I are in agreement about the necessity for controlled sharing. We clearly just have different perspectives on how to solve it.
Nov 30
On Sunday, 30 November 2025 at 21:36:13 UTC, Peter C wrote:On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:LMFAO really? That is absolutely hilarious! **THATS** the killer feature you cant live without???The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.
Nov 30
On Monday, 1 December 2025 at 00:18:18 UTC, claptrap wrote:On Sunday, 30 November 2025 at 21:36:13 UTC, Peter C wrote:yep. It's how I write code - share what I need, protect what I must, and expose only what makes sense.On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:LMFAO really? That is absolutely hilarious! **THATS** the killer feature you cant live without???The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.
Nov 30
On Monday, 1 December 2025 at 05:11:02 UTC, Peter C wrote:On Monday, 1 December 2025 at 00:18:18 UTC, claptrap wrote:Hmm i think maybe I still don't understand what you mean, could you explain it again?On Sunday, 30 November 2025 at 21:36:13 UTC, Peter C wrote:yep. It's how I write code - share what I need, protect what I must, and expose only what makes sense.On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:LMFAO really? That is absolutely hilarious! **THATS** the killer feature you cant live without???The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.
Dec 01
On Monday, 1 December 2025 at 11:52:07 UTC, claptrap wrote:On Monday, 1 December 2025 at 05:11:02 UTC, Peter C wrote:I'm not sure whether you're being sarcastic here, or whether you're saying that I've already overexplained myself (which is often the case). What's I'm referring to, is 'progressive exposure' - that is, a gradual increase in access to data and functionality, where privacy and encapsulation are carefully maintained at each stage. It's a deliberate design strategy I use, as my default. I do not accept D's defaults. So in D, that means my .d template has to look like this: module mymodule; // safe: private: class MyClass { scopeprivate: } Now any intention to share (either in or outside of this module) will be both progressive and explicit. It's not for everyone, but it works for me.On Monday, 1 December 2025 at 00:18:18 UTC, claptrap wrote:Hmm i think maybe I still don't understand what you mean, could you explain it again?On Sunday, 30 November 2025 at 21:36:13 UTC, Peter C wrote:yep. It's how I write code - share what I need, protect what I must, and expose only what makes sense.On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:LMFAO really? That is absolutely hilarious! **THATS** the killer feature you cant live without???The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.
Dec 01
On Monday, 1 December 2025 at 22:45:42 UTC, Peter C wrote:On Monday, 1 December 2025 at 11:52:07 UTC, claptrap wrote:Genius!On Monday, 1 December 2025 at 05:11:02 UTC, Peter C wrote:I'm not sure whether you're being sarcastic here, or whether you're saying that I've already overexplained myself (which is often the case). What's I'm referring to, is 'progressive exposure' - that is, a gradual increase in access to data and functionality, where privacy and encapsulation are carefully maintained at each stage. It's a deliberate design strategy I use, as my default. I do not accept D's defaults. So in D, that means my .d template has to look like this: module mymodule; // safe: private: class MyClass { scopeprivate: } Now any intention to share (either in or outside of this module) will be both progressive and explicit. It's not for everyone, but it works for me.On Monday, 1 December 2025 at 00:18:18 UTC, claptrap wrote:Hmm i think maybe I still don't understand what you mean, could you explain it again?On Sunday, 30 November 2025 at 21:36:13 UTC, Peter C wrote:yep. It's how I write code - share what I need, protect what I must, and expose only what makes sense.On Sunday, 30 November 2025 at 10:15:10 UTC, claptrap wrote:LMFAO really? That is absolutely hilarious! **THATS** the killer feature you cant live without???The only useful (unoffical) addition to the D language for my use cases, has been scopeprivate. There is no other addition to the language that has even come close in terms of its usefulness to me. Without it, I would dump D immediately.
Dec 01
On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:... This would negate the need to put everything in one module, while also allow much more fine grained API exposure.To back up my previous post: What D really needs, is fine grained API exposure inside the module itself, not across modules. - Use scopeprivate for sensitive state that must remain strictly class‑internal. - Use private for module‑level cooperation between closely related classes. - Use public for safe, external APIs. The **principle**: - share what you need, protect what you must, and expose only what makes sense. I believe this would make the D module a far more suitable enclosure for strongly coupled types. Without scopeprivate, D forces developers into either the C++ friend‑like problem of overexposed internals, or awkward design contortions with extra modules. I am really surprised there isn't more demand for this. --- class Point { // sensitive state: only Point itself can access these.. scopeprivate { int x; int y; } // module-private: PointColor can access these.. private { int cachedMagnitude; } public { this(int x, int y) { this.x = x; this.y = y; cachedMagnitude = x * x + y * y; } int magnitude() { return cachedMagnitude; } void describe(PointColor pc) { // Access PointColor's module-private label writeln("Point(", x, ", ", y, ") has color label: ", pc.label); } } } public class PointColor { // sensitive state: only PointColor itself can access these.. scopeprivate { int r, g, b; } // module-private: Point can access these.. private { string label; } public { this(int r, int g, int b, string label) { this.r = r; this.g = g; this.b = b; this.label = label; } void colorizePoint(Point p) { // Use Point's module-private cachedMagnitude int brightness = p.cachedMagnitude % 256; writeln("Colorizing Point with brightness ", brightness, " using color (", r, ", ", g, ", ", b, ") and label ", label); } } }
Nov 29
On Sunday, 30 November 2025 at 05:29:57 UTC, Peter C wrote:What D really needs, is fine grained API exposure inside the module itself, not across modules.No thanks.
Nov 30
On Sunday, 30 November 2025 at 09:30:22 UTC, Sergey wrote:No thanks.Thanks, for the thoughtful and well-reasoned response.
Nov 30
On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:.. So what about just granting access to specific parts.So you want 'encapsulation with selective sharing'. Am I correct? As you've highlighted, you cannot have this in C++, because once you make class B a friend of class A, you've explicitly allowed B to access *ALL* of A's private members. The above is *exactly* the same within the D module. That is, the C++ friend concept has already been imported into D - it's just that it is scoped to the module. I'm troubled by the engineering consequences of your proposal to share selected private members with classes in another module. D deliberately avoids these engineering consequences by enforcing private to be private-to-the module. Any attempt to share even 'selected' private members with classes in other modules, will mean classes are harder to reason about, in terms what's truly internal vs. external, because 'friend-like' relationships can (and will) scatter across the codebase. Selective sharing of private class members across modules, will create obscure coupling, where class B in another module can depend on the internal representation of class A. If A changes its private layout, B breaks - even though they're supposed to be in separate modules. So no, selective sharing of private members across modules should NOT be allowed, and I reject your proposal. I'm also troubled by the engineering consequences of the status quo in D. That is, the C++ like 'all-or-nothing' friendship inside the D module. What should be enabled, is selective sharing *within* a D module. This solves your issue of wanting selective sharing, rather than the C++'s and D's all-or-nothing approach It also solves my issue of concern to your proposal -> the engineering consequences of obscure coupling. It also solves my other concern -> the engineering consequences of the status quo. So 3 birds to kill here, with one stone. (and no, do NOT stone birds!!!) Two (or more) classes that are tightly coupled, should be allowed to exist in the same module to let them share private members, while still allowing each class to maintain control over that sharing, when needed. This kind of solution would avoid the complexity of managing 'selective' friendship networks, maintain D's clean module boundary, and enable your desire (and mine) for selective sharing, without any negative cost to software engineering. Example code below (to demonstrate this principle): public class A { scopeprivate int secret; // A owns its secret! private int cache; // shared within module public int x; // visible everywhere public this(int x, int s) { this.x = x; secret = s; cache = x; } // Controlled exposure of secret public int revealSecret() { return secret; } } public class B { private int[] r; public this(int[] arr) { r = arr; } public void sync(A a) { r[0] = a.x; // public: always accessible r[1] = a.cache; // private: accessible in same module // r[2] = a.secret; // blocked: scopeprivate r[2] = a.revealSecret(); // allowed via A's public method } public void show() { writeln(r); } }
Nov 30
On Monday, 1 December 2025 at 07:42:10 UTC, Peter C wrote:What is stopping you just use OpenD?
Nov 30
On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:limited friend access Ok everyone around here seems to think "friend classes" were a mistake in C++. But I think the reason they are a problematic is that they grant access carte blanche. It gives the friend unfettered access to everything. It's like giving a friend keys to your house, car, credit cars, account logins, power of attorney, when you just want him to feed the cat while you're on holiday. [...]What, in your opinion, is the problem with needing to put everything in one module in order to grant access?
Dec 01
On Monday, 1 December 2025 at 17:47:15 UTC, Atila Neves wrote:On Saturday, 29 November 2025 at 22:29:35 UTC, claptrap wrote:In general nothing, in the specific case I have now, I just want to keep platform specific code each in it's own module.limited friend access Ok everyone around here seems to think "friend classes" were a mistake in C++. But I think the reason they are a problematic is that they grant access carte blanche. It gives the friend unfettered access to everything. It's like giving a friend keys to your house, car, credit cars, account logins, power of attorney, when you just want him to feed the cat while you're on holiday. [...]What, in your opinion, is the problem with needing to put everything in one module in order to grant access?
Dec 01
On Monday, 1 December 2025 at 21:41:38 UTC, claptrap wrote:.. I just want to keep platform specific code each in it's own module.If you want to keep platform-specific code isolated in separate modules, while also maintain a clean design architecture, then you may simply need to do some refactoring. Perhaps the visitor design pattern and/or the dependency injection design pattern, would be a suitable solution here? Remember, that these patterns support the implementation of a well-thought-out design, but good design comes first. You must still combine them with good architectural principles.
Dec 01
On Monday, 1 December 2025 at 22:34:51 UTC, Peter C wrote:On Monday, 1 December 2025 at 21:41:38 UTC, claptrap wrote:I don't like those solutions. Do you have any alternatives?.. I just want to keep platform specific code each in it's own module.If you want to keep platform-specific code isolated in separate modules, while also maintain a clean design architecture, then you may simply need to do some refactoring. Perhaps the visitor design pattern and/or the dependency injection design pattern, would be a suitable solution here? Remember, that these patterns support the implementation of a well-thought-out design, but good design comes first. You must still combine them with good architectural principles.
Dec 01
On Monday, 1 December 2025 at 23:08:06 UTC, claptrap wrote:On Monday, 1 December 2025 at 22:34:51 UTC, Peter C wrote:Sure. Just keep on pushing for your 'Limited friend access'... maybe someone will take it seriously.On Monday, 1 December 2025 at 21:41:38 UTC, claptrap wrote:I don't like those solutions. Do you have any alternatives?.. I just want to keep platform specific code each in it's own module.If you want to keep platform-specific code isolated in separate modules, while also maintain a clean design architecture, then you may simply need to do some refactoring. Perhaps the visitor design pattern and/or the dependency injection design pattern, would be a suitable solution here? Remember, that these patterns support the implementation of a well-thought-out design, but good design comes first. You must still combine them with good architectural principles.
Dec 01
On Tuesday, 2 December 2025 at 05:40:38 UTC, Peter C wrote:On Monday, 1 December 2025 at 23:08:06 UTC, claptrap wrote:The last thing I want is for anyone to take anything I say seriously.On Monday, 1 December 2025 at 22:34:51 UTC, Peter C wrote:Sure. Just keep on pushing for your 'Limited friend access'... maybe someone will take it seriously.On Monday, 1 December 2025 at 21:41:38 UTC, claptrap wrote:I don't like those solutions. Do you have any alternatives?.. I just want to keep platform specific code each in it's own module.If you want to keep platform-specific code isolated in separate modules, while also maintain a clean design architecture, then you may simply need to do some refactoring. Perhaps the visitor design pattern and/or the dependency injection design pattern, would be a suitable solution here? Remember, that these patterns support the implementation of a well-thought-out design, but good design comes first. You must still combine them with good architectural principles.
Dec 02
On Monday, 1 December 2025 at 23:08:06 UTC, claptrap wrote:On Monday, 1 December 2025 at 22:34:51 UTC, Peter C wrote:Well, if you're determined to access private members from outside the module in which they are declared, then..yeah ...here's another solution for ya. You'll need to use an older version of the compiler though (prior to 2.079) - or, do some modifications to a more recent version. module myModule; import std.stdio; import myDataModule; // see below as to what that module looks like. void main() { writeln("PrivateKey is: ", myDataModule.secretKey); // fine! } /+ module myDataModule; private string secretKey = "12345-HIDDEN-67890"; +/ // compile: dmd myDataModule.d myModule.dOn Monday, 1 December 2025 at 21:41:38 UTC, claptrap wrote:I don't like those solutions. Do you have any alternatives?.. I just want to keep platform specific code each in it's own module.If you want to keep platform-specific code isolated in separate modules, while also maintain a clean design architecture, then you may simply need to do some refactoring. Perhaps the visitor design pattern and/or the dependency injection design pattern, would be a suitable solution here? Remember, that these patterns support the implementation of a well-thought-out design, but good design comes first. You must still combine them with good architectural principles.
Dec 01
On Tuesday, 2 December 2025 at 07:42:46 UTC, Peter C wrote:On Monday, 1 December 2025 at 23:08:06 UTC, claptrap wrote:What about just using "package"? Simple no?On Monday, 1 December 2025 at 22:34:51 UTC, Peter C wrote:Well, if you're determined to access private members from outside the module in which they are declared, then..yeah ...here's another solution for ya. You'll need to use an older version of the compiler though (prior to 2.079) - or, do some modifications to a more recent version. module myModule; import std.stdio; import myDataModule; // see below as to what that module looks like. void main() { writeln("PrivateKey is: ", myDataModule.secretKey); // fine! } /+ module myDataModule; private string secretKey = "12345-HIDDEN-67890"; +/ // compile: dmd myDataModule.d myModule.dOn Monday, 1 December 2025 at 21:41:38 UTC, claptrap wrote:I don't like those solutions. Do you have any alternatives?.. I just want to keep platform specific code each in it's own module.If you want to keep platform-specific code isolated in separate modules, while also maintain a clean design architecture, then you may simply need to do some refactoring. Perhaps the visitor design pattern and/or the dependency injection design pattern, would be a suitable solution here? Remember, that these patterns support the implementation of a well-thought-out design, but good design comes first. You must still combine them with good architectural principles.
Dec 02
On Tuesday, 2 December 2025 at 08:52:34 UTC, claptrap wrote:What about just using "package"? Simple no?That sounds just like the C++ friends problem to me. I prefer a consistent mental model -> the 'module' is the fundamental boundary of encapsulation in D. With that mental model, it becomes much easier to reason about where and how internals are shared. It also avoids the chaos that will come with loosely coupled, overly shared internals. Shared internals outside of the module, should immediately set off the warning alarm/lights: "Ding Ding! Breach of Modularity! Breach of Modularity!". I think a good design must impose strict control over shared internals. So for me, the best place for controlled sharing of internals, is inside the D module. That is also why I need (and have) scopeprivate. As without that, you do not have controlled sharing inside the module - it's all or nothing.
Dec 02
On Tuesday, 2 December 2025 at 22:13:42 UTC, Peter C wrote:On Tuesday, 2 December 2025 at 08:52:34 UTC, claptrap wrote:I just still don't get it, sounds awfully complicated.What about just using "package"? Simple no?That sounds just like the C++ friends problem to me. I prefer a consistent mental model -> the 'module' is the fundamental boundary of encapsulation in D. With that mental model, it becomes much easier to reason about where and how internals are shared. It also avoids the chaos that will come with loosely coupled, overly shared internals. Shared internals outside of the module, should immediately set off the warning alarm/lights: "Ding Ding! Breach of Modularity! Breach of Modularity!". I think a good design must impose strict control over shared internals. So for me, the best place for controlled sharing of internals, is inside the D module. That is also why I need (and have) scopeprivate. As without that, you do not have controlled sharing inside the module - it's all or nothing.
Dec 02
On Tuesday, 2 December 2025 at 23:04:58 UTC, claptrap wrote:On Tuesday, 2 December 2025 at 22:13:42 UTC, Peter C wrote:Honestly, if you're just writing code that only you need to understand and maintain, then do whatever you please - I mean really, nobody should care less what you do in that case. And it that is the case, then I couldn't care less ;-) It's when you want others to understand your code, or help maintain it, that you'll need to make better design decisions. Although, even when the code is for you and you alone, good design decisions will benefit you as well, because what you can understand, you can modify and extend. Unfortunately, D's default of everything public, puts good design decisions not at the beginning of your coding, but well after you've started .. if ever. The reason people don't like OOP, are the same reasons people like public by default - i.e. you can just start coding, and think about the important stuff later on... Perhaps you would feel more comfortable, with this as your default .d template: module mymodule; package: class MyClass { package: }On Tuesday, 2 December 2025 at 08:52:34 UTC, claptrap wrote:I just still don't get it, sounds awfully complicated.What about just using "package"? Simple no?That sounds just like the C++ friends problem to me. I prefer a consistent mental model -> the 'module' is the fundamental boundary of encapsulation in D. With that mental model, it becomes much easier to reason about where and how internals are shared. It also avoids the chaos that will come with loosely coupled, overly shared internals. Shared internals outside of the module, should immediately set off the warning alarm/lights: "Ding Ding! Breach of Modularity! Breach of Modularity!". I think a good design must impose strict control over shared internals. So for me, the best place for controlled sharing of internals, is inside the D module. That is also why I need (and have) scopeprivate. As without that, you do not have controlled sharing inside the module - it's all or nothing.
Dec 02









Peter C <peterc gmail.com> 