Adding a new design constraint to D

Chris Katko ckatko at gmail.com
Tue Jun 14 13:55:57 UTC 2022


On Tuesday, 14 June 2022 at 05:43:49 UTC, forkit wrote:
> So there has been extensive discussions in other threads, 
> around the idea of adding a new 'design constraint feature' to 
> the D programming language.
>
> The design constraint feature, is 'designed' to allow the 
> programmer to make an explicit declaration, that some aspect of 
> the design of a class, should be private to that class, and 
> thereby make that aspect of the class (logically) inaccessible 
> to code outside of that class, but in the same module.
>
> The constraint could, in theory, apply to other types such as 
> struct or enum. But the suggestion currently relates to the 
> class type only.
>
> The below example compiles just fine, as you would expect.
>
> // ------
> module test;
> @safe:
>
> class someClass
> {
>     private:
>         string _id;
>
>     public:
>         void setID(string id)
>         {
>             // some condition(s), if met, then:
>             _id = id;
>         }
> }
>
> unittest
> {
>     someClass myclass = new someClass();
>     myclass.setID("123");
> }
>
> // -----
>
> Is the above code consistent with the design intent of 
> someClass?
>
> The answer must be yes, since in D, private is private to the 
> module.
>
> But what if the intent was to require other code to 'use the 
> inteface' to access x?
>
> The problem is, many coming to D, come from languages where you 
> can already declare such an intent, and equally importantly, 
> have that intent enforced by the compiler, at compile time.
>
> But the D programming language has no feature to declare such 
> an intent. So where does this leave those programmers?
>
> The argument has been made, that D does not need such a 
> feature, because scope is always at the module level.
>
> But it does not follow, that scope at the module level 
> eliminates the need for such a feature. That argument is not 
> logical.
>
> The next response, is that if you need this feature, then you 
> can 'simulate it' by putting the class that needs this feature, 
> into its own module.
>
> However, the one-class-per-module approach, imposes its own new 
> design constraint, and not one the programmer necessarily makes 
> of his/her own volition.
>
> It also does not necessarily follow, that a class in its own 
> module, is there for the purposes of stipulating this 
> constraint.
>
> There are any number of a reason, why a class might be put into 
> its own module. You cannot infer anything from that. You'd have 
> to speak the designer to know intent.
>
> Other arguments have also been made against adding such a 
> feature, but it is difficult to take them seriously - such as 
> 'why would a class ever need to hide something'.
>
> Now the advantage of adding such a feature, is that it provides 
> private at the scope level for those who want or expect such a 
> feature, it provides evidence of the designers intent to 
> separate implementations from interface, and the compiler which 
> now knows the intent, can enforce that intent, at compile time.
>
> So the only logical outcome of this discussion, is whether the 
> benefit of adding a design constraint *option* to the language, 
> outweighs the cost of adding it to the langauge.
>
> The benefits of adding this feature appear to be self-evident.
>
> So ultimately, this comes down to a benefit-vs-cost 
> consideration.
>
> The cost of adding it to the language, is less self-evident.
>
> Is the cost, the unjustified cognitive burden of having both 
> 'private' and 'private(scope)', instead of just 'private'?
>
> Is the cost - it's just too complicated to change the compiler 
> source to accomodate this option?
>
> What do you think the cost of adding such a feature is?

I just want to +1 this. Even if I had to use a compiler switch.

'private' exists in many languages and has survived the test of 
time. Just because you don't use it doesn't mean other people 
don't--especially with D's bias toward gigantic 3000+ line module 
files. And if you don't like it, I don't see why you'd be 
suffering when it's an opt-in feature and you can just not use it.

I find that private makes for a great way for rapid incremental 
development (that D is great at). You get things working, then 
"private" them, and immediately all references to that variable, 
function, or "hidden thing" are now visible as compiler errors 
that you can go down the line and fix. It's not "opt in" (the way 
error correction is supposed to be--opt-out so you cannot 
accidentally miss it). There's no possibility of human error in 
the list. If you make an outside reference illegal, it's now 
visible to the compiler and you. You can private members and 
fields, as often or rarely as you want. One at a time, clean up 
some references, then another one.

The "alternative" is either do some gymnastics with entire 
classes moving around files to poorly emulate private, or, rename 
your interface variable/method in question which highlights all 
references to it as an error. Except that also includes CORRECT 
references in the list!

You don't want to use it in the standard library, go ahead. But 
that doesn't make it not useful. By that logic, I guess we should 
rip out BetterC.


More information about the Digitalmars-d mailing list