June 04, 2022

On Saturday, 4 June 2022 at 14:29:58 UTC, zjh wrote:

>

On Saturday, 4 June 2022 at 14:21:41 UTC, Ola Fosheim Grøstad wrote:

>

More and more users are using Python… Cheating pays off!

Cheating first feel good, but then it all fell into bad luck.

Adding one little feature here and one little feature there is just a distraction that takes the focus off completing and streamlining what is already in the language.

June 04, 2022

On Friday, 3 June 2022 at 05:58:06 UTC, Mike Parker wrote:

>

The only difference here is that in one case, the function manipulating _x is above the brace that terminates Foo, and in the other case it's below it. In practical terms, the person editing the module has access to the function in both cases.

I like private in D, but there is a big problem with synchronized members:

synchronized class C {
	private int i;
}

public void foo(C c) {
	c.i++;
}
$ dmd -vasm -c old/syncclass.d
_D9syncclass3fooFCQq1CZv:
0000:   FF 40 08                 inc       dword ptr 8[EAX]
0003:   C3                       ret

foo just incremented i without locking c.

June 04, 2022

On Saturday, 4 June 2022 at 16:53:45 UTC, Nick Treleaven wrote:

>

I like private in D, but there is a big problem with synchronized members:

Filed: https://issues.dlang.org/show_bug.cgi?id=23158

June 04, 2022

On Friday, 3 June 2022 at 22:50:06 UTC, forkit wrote:

>

On Friday, 3 June 2022 at 15:41:04 UTC, Mike Parker wrote:

>

On Friday, 3 June 2022 at 12:13:47 UTC, forkit wrote:

>

Practically speaking, anyone that uses a class in D, must be put it in its own module - no exceptions.

That's just nonsense.

How is it nonsense? I don't get it.

Because practical experience - at least mine - suggests almost the complete opposite of what you're saying. Let's take a practical example. Imagine I'm making a GUI label struct.

struct Label
{ private ubyte[] content;

  string text()
  { //whatever...
  }

  string text(string arg)
  { //assign arg to content...;
  }

  Tuple(Font, size_t)[] getFonts
  { //Get list of fonts used, along
    //with their usage starting
    //points...
  }

  //and other members...
}

I'm marking content private because I want to keep myself free to change that to some other internal represenataion in the future.

Let's say this struct is not the only thing in the module. A realistic scenario would be that there are 2000 other lines that can access content if they really want to. That's not a big problem. Others will usually instead use the public functions of Label. If I someday decide to change the internal representation, it's possible that one or two things in the module depend on it if I'm unlucky. Those are quick and easy to fix, and I can fix them myself since they are in the same module.

I probably won't bother to put Label to it's own file just to avoid such an insignificant risk, and I'm pretty sure an average D programmer would agree with me in this.

June 04, 2022
On 6/4/22 04:15, forkit wrote:
> On Saturday, 4 June 2022 at 07:04:35 UTC, Ali Çehreli wrote:
>>
>> ...
>> I think the reason is there is no strong argument for one way or the
>> other. There are two options:
>>
>> a) 'private' means "private to the class", which necessitates the
>> equivalent of the keyword 'friend'. This option is what C++ chose.
>>
>> b) 'private' means "private to the module", which frees 'friend' as a
>> user symbol. This option is what D chose.
>>
>> > I really do think there is idealogical resistance to such a
>> change, and
>> > it's this that brings about these strong reactions.
>>
>> Since D came after C++, it is clear that option b was seen to be
>> superior. Let's hear arguments why option a is better than b.
>
> It's interesting that whenever this topic is brought up, that people in
> the D community (like you, for example), try to rephrase it as if we're
> all being forced to make a choice between A *or* B.
>
> I'd like to have A *and* B.

Languages don't provide every want without weighing pros of cons. It may very well be good to have both A and B but I am not convinced.

> You normally come up with ideas to issues that people raise (even ideas
> that to me see pretty ordinary)

I am happy to be simple and happily finding ways to become more so.

> , except, when it is this issue??

I am not going to come up with ideas for non-issues. I asked whether you've seen a single case where somebody forgot to mark a variable 'private' and there was an issue. I seriously doubt it. People are not crazy creatures that change members willy nilly.

In fact, encapsulation can be achieved purely by convention: Name all members in a special way e.g. with a leading underscore and let it mean "this is private" and you have encapsulation. Nobody will access those members. If they ever do access, that's because they have a business case to do so. I gave the real-world example of how one company did access D runtime's GC statistics, which happened to be marked as 'private' when it was first designed.

> Why this idea encounters sooo.. much resistance, is..well. interesting.

I man not resisting this idea but your presentation of it. You present it as if D is broken. I asked for your arguments for favoring per-class encapsulation vs. per-module encapsulation. I haven't seen those arguments yet but I suspect you favor class because other languages do so.

My "text book" reference was related: Is there a computer science consensus on class should be the unit of encapsulation?

I gave another example where your favoring per-class encapsulation comes short: What about private members that are accessed only by a subset of the member functions of a class. That pattern emerges a lot in my types. Does not the same logic apply to that case? Member function foo() can access array _buffer even though _buffer should be accessed only by bar() and zar().

I know one can put _buffer, bar(), and zar() in a different class and get lower level encapsulation but that's not different from moving code to another module to get lower level of encapsulation.

> The rest of your response I couldn't make any sense of.. so I'll ignore it.

I tried to explain above:

- Why do you favor 'class' over module?

- If you stop at 'class', you will come up short.

> In the end though, encapsulation of a class, in D, is broken

That is wrong.

And exactly that kind of mistaken but so-sure statement moves me to so much resistence. The encapsulation point is merely arbitrary. Please you explain why you are so strong on where you stop encapsulation. Why class? Is there a computer science theory behind it?

> and cannot
> be statically verified by the compiler

As I said, since nobody will reach private members willy nilly, static verification of it is overkill. Encapsulation can be achieved by a convention.

I will go further and note that private does not add any value to the program: Replace all with 'public' and the program will run in exactly the same way with exactly the same level of safety.

> Since there is no option B, to do otherwise, is what I would consider
> unsound programming, as it is not possible to reason about the code of
> the class contained within a module, without understanding ALL the code
> in that module.

Really? That does not make sense at all. Why would e.g. Vector's code have anything to do with List's code? How does one get a hold of an object of the other to access its private members? This kind of statement is misguided. I am afraid people new to programming will take those and be concerned. There is no such problem at all. I haven't seen a single case of such violation of encapsulation. None.

> It's also not possible to prove (again, without human intervention) that
> other code in the module does not violate the modular requirements of
> the class.

My example above holds: List's code does not even receive a Vector object.

I don't know what kind of projects you work with but I am happy to never have encountered such violations of modular requirements. (?)

> A possible counter agrument to the above, is that there is no
> encapsulation of a class in D. The module provides all the encapsulation
> anyone will ever need.
>
> I'm not sure I'd want to be on that side of the argument ;-)

You clearly are not and I proudly am.

Besides, there are other ways of providing encapsulation when really needed. The reason I don't hear the pimpl idiom in D circles is because nobody really needs it.

Ali

June 05, 2022
On Saturday, 4 June 2022 at 23:11:24 UTC, Ali Çehreli wrote:
>
> I man not resisting this idea but your presentation of it. You present it as if D is broken. I asked for your arguments for favoring per-class encapsulation vs. per-module encapsulation. I haven't seen those arguments yet but I suspect you favor class because other languages do so.

Again (how many time do I have to say this??), my argument is not favouring one or the other. It's favouring the 'option' to have both.


> - Why do you favor 'class' over module?

Again, I don't. How many times do I have to say this??


>
> (me) In the end though, encapsulation of a class, in D, is broken
>
> (you) That is wrong.

Again, you pick only part of my argument so that it suits your agenda.

Here is what I actually wrote:

"In the end though, encapsulation of a class, in D, is broken, and cannot be statically verified by the compiler, unless you put that class in it's own file (which is what you're expected to do anyway, based on the reponses this idea always provoke)."

It's pointless for me to discuss an issue with people who are clearly ideologically opposed to it.

So I won't ;-)



June 05, 2022
On Sunday, 5 June 2022 at 00:30:14 UTC, forkit wrote:
>
> Again (how many time do I have to say this??), my argument is not favouring one or the other. It's favouring the 'option' to have both.

Well, to be clear, both exist already (i.e. one class per module, and it's done).

But my argument is to have both in the context of a module that contains a class, as well as other code (as I've made very clear from the beginning).

I don't want to have to manually audit a whole module, just becasue it contains code other than a class, and therefore, there is no way to ensure the invariants of that class are being upheld, without manually inspecting all code in that module. This is my point. I should not have to do this manually, and I do not want to 'forced' by the language to put each class in its own module, because of this.

That's the end of my discussion on this topic ;-)
June 04, 2022
On 6/4/22 04:15, forkit wrote:

> You normally come up with ideas to issues that people raise

Has anyone suggested the following syntax yet?

class C {
  private class:
    // really private

  private module:
    // module-level as today

  private:
    // same as 'private module'
}

If there are syntax issues, perhaps paranthesis can work:

  private(class):

Ali

June 05, 2022
On Sunday, 5 June 2022 at 01:32:45 UTC, Ali Çehreli wrote:
> On 6/4/22 04:15, forkit wrote:
>
> > You normally come up with ideas to issues that people raise
>
> Has anyone suggested the following syntax yet?
>
> class C {
>   private class:
>     // really private
>
>   private module:
>     // module-level as today
>
>   private:
>     // same as 'private module'
> }
>
> If there are syntax issues, perhaps paranthesis can work:
>
>   private(class):
>
> Ali

See. I knew you could do it ;-)

All it takes is an open mind -> not wanting to be forced into thinking the way a language wants you to think.

June 05, 2022
On Sunday, 5 June 2022 at 01:32:45 UTC, Ali Çehreli wrote:
>

btw. Has anyone ever conducted a code review into representation exposure in phobos, at the intra-module level (within a module, including unit-tests)?

It would be interesting to see, if, and where, invariants are not being preserved, and why.