Using closure in function scope to make "real" private class members

Ola Fosheim Grøstad ola.fosheim.grostad at gmail.com
Tue Jun 7 19:42:00 UTC 2022


On Tuesday, 7 June 2022 at 18:07:34 UTC, Andrey Zherikov wrote:
> What you are speaking here about is encapsulation by convention 
> (naming rules for the members). This is good approach 
> especially when everyone follows it. Unfortunately people 
> don't. They tend to code their own way. As a result, for the 
> languages that don't provide encapsulation (like Python), 
> people started adding corresponding checks to static 
> analyzers/linters to force the encapsulation.

The general convention is to use underscore as a prefix for 
internals, that is pretty universal across languages and has been 
so for many decades. I believe even PyCharm will recognize this.

But it is easier to build a linter for D than for Python, so if 
you want it, then you can build it. You can also use user defined 
attributes in D if you don't like underscores?

Having a linter-eco system is something all languages will 
benefit from, so having something worthwhile to trigger people to 
build their own linters is not necessarily a disadvantage. If 
people want "@private" badly then it is great if they build a 
linter that they share with others. If enough people use it then 
that can trigger inclusion in the language.

This is how languages ought to evolve:

1a. First try a library solution (like OP), if you cannot do it…
1b. …try to build a generator of some sort, if you cannot do it…
1c. …try to build an analyzer of some sort etc…

2. Collect feedback from users of your solution.

3. Consider writing a DIP if the solution is working, but would 
benefit greatly from compiler support.

4. Find a compiler dev willing to cowrite the DIP.

Then use that as a proof of concept for the DIP. If enough people 
use your solution when the DIP is evaluated then it obviously 
will be a much stronger candidate for inclusion!


> compatible. So the better solution might be extending syntax 
> for `private` having something like `private(symbol[, symbol 
> ...])` where `symbol` is a symbol that has access to the member

How would users know that this `private` means something 
different?

It is very difficult to get good usability as long as most users 
coming from other languages have a rather firm interpretation of 
what `private` means. With the current setup `private` means «the 
strongest encapsulation» which at least is somewhat consistent 
with other languages.

You could introduce `internal` as a keyword, but that doesn't 
overcome the confusion of D'internal = C++'private and D'private 
≈ C++private&friend.

So no matter what you do, usability will suffer. Thus a breaking 
change is the only good alternative from a usability POV. And 
that won't happen in D2.





More information about the Digitalmars-d mailing list