November 01, 2018
On Thursday, 1 November 2018 at 16:32:23 UTC, H. S. Teoh wrote:
>
> Java also enforces, by policy, the creation of a separate file for every public class.  This is no different.
>
>
> T

If I wanted Java in D, I already have Java - which does a better job at being Java, than D.

Also, I do not consider a single class, to be such a big bucket of code, that it should necessarily be a module all of it's own.

Again, D kind forces this onto anyone coming from a class based, oop langauge - but only because D won't all private to be private in modules. And I don't know many class-based oo programmers, that find that acceptable.

The only options D give such programmers, is:

(a) stiff, stick to you current language if you don't like how D does it.
(b) make sure you only ever have one class in a module in D.
(c) stop thinking like that, and start thinking like D apparently wants you to think.

I don't believe langauges should force a particular design upon the programmer.

I'm not big fan of inheritance either, despite it being a valid and useful way to architect your solution. I like self-contained classes - and would like to have more than one self-contained class in a module. Java requires that only one can be public, which is a design pain point for me, that forces you into Java like design.

It is not too much to ask, in my opinion, to have a 'strict private' like concept in D, which does everything private does (so it's not a breaking change), but additionally, keeps it private within the module too.

That would also give the programmer, the option to write unit-tests that cannot access private parts. That surely would be a good thing (again, it's an option for the programmers - it's not forced upon them).

Argue about how that should be done (syntax), fine. But telling programmers they only have the 3 options mentioned above, is kinda sad.

Those do don't like the change, are really not that affected. They can just keep doing what they've always done. A good option for the syntax, would ensure it's immediately clear, that the programmer want their private parts, to remain private.

How difficult/complex that would be, to actually implement, well that's a discussion that would interest me. But nobody is benefitting from just saying 'no' all the time.

It's not about securing your code from other code in the module.

It's about clean architecture.


November 02, 2018
On Thursday, 1 November 2018 at 23:23:55 UTC, unprotected-entity wrote:
> It's about clean architecture.

If you use interfaces correctly, there will be no private members accessible regardless of privacy and D's module system.

interface I {}
class B : I {}

void workWithIt(I i) {
    // nothing in B is accessible without ugly casts!
}
November 02, 2018
On Friday, 2 November 2018 at 00:54:43 UTC, Adam D. Ruppe wrote:
>
> If you use interfaces correctly, there will be no private members accessible regardless of privacy and D's module system.
>
> interface I {}
> class B : I {}
>
> void workWithIt(I i) {
>     // nothing in B is accessible without ugly casts!
> }

".. but it would be tenuous to argue that transparency was a positive contributor; more plausibly, it was a risk minimized by intensive management." - Andrei Alexandrescu - page 200

Now, I might be accused of taking that out of context, but am I really?

In D, public is the default (I wonder how many realise this, when they come to D, let alone the issue with private).

" .. (heck, public sets the bar pretty low.. )." - Andrei Alexandrescu - page 202

So, in D, the bar is already pretty low?

Also, in D, there simply is no way to get privacy within the module.

Just how low does the bar get, in D?

(to quote informally), It's a transparent, white box, 'everything knows everything' approach to designing software - page 199  (again, i could be accused of taking this out of context, but am i really?)

To me, D modules are 'a risk minmized by intensive management'

(perhaps using the techniques you've demonstrated ;-)

But gee, the bar is soooooo low.... in D.


November 02, 2018
On Thursday, 1 November 2018 at 17:59:35 UTC, Steven Schveighoffer wrote:
> On 11/1/18 10:29 AM, Atila Neves wrote:
>> On Wednesday, 31 October 2018 at 20:46:05 UTC, Zot wrote:
>>> On Monday, 29 October 2018 at 09:25:07 UTC, unprotected-entity wrote:
>>>> Just how often does one need to access the private members of a class, within a module?
>>>
>>> a lot actually. e.g. unittests
>> 
>> Unit tests should go through the public interface like anyone else. All private members and functions are implementation details that shouldn't matter and shouldn't break any tests if they're all removed.
>
> So... don't test private functions?

Precisely.

Caveat: test them if you *really* want to, but be prepared to delete the tests with extreme prejudice.

I never do, implementation details are just that.


> I do all the time. I want to test every single function I can.

Testing to me is like going to the gym. I don't actually want to do it, but I do anyway because the alternative is worse. IMHO, tests take time to write, and testing implementation details is not a worthwhile use of my time.


> I also look at internals, especially when I find bugs about them that can be caught with a peek at internal data.

Sure, but that's not what my point was.

> Perhaps the internals implement some protocol, and you want to check it's in the right state part-way through a transaction.

If you're writing it from scratch, I'd say write a test for that as you're going. But then delete it after you're done.

If it's already written I'd use a debugger.

> However, I would *love* to be able to specify unit tests that *can't* access private internals for testing purposes. IIRC, it was proposed at some point to require this for documented unittests.

I do this all the time by having the tests in a different file, which is what I always do now given how much trouble in-module unittests have been for me.


November 02, 2018
On Thursday, 1 November 2018 at 18:30:33 UTC, 12345swordy wrote:
> On Thursday, 1 November 2018 at 17:58:34 UTC, Atila Neves wrote:
>> On Thursday, 1 November 2018 at 16:19:57 UTC, 12345swordy wrote:
>>> On Thursday, 1 November 2018 at 14:17:13 UTC, Atila Neves wrote:
>>>> On Monday, 29 October 2018 at 23:15:58 UTC, unprotected-entity wrote:
>>>>> On Monday, 29 October 2018 at 15:50:56 UTC, Jonathan M Davis wrote:
>>>>>>
>>>>> It's not (just) that I don't like it, it's that I don't like not giving the programmer the tool to better encapsulate their code (specifically classes) *within* a module.
>>>>
>>>> You don't need to protect code in your module from other code in your module. If you do, put them in different modules.
>>> That typically involves creation of files, which is not always ideal if you are working with code that is considerably small.
>>
>> If the code is considerably small you don't need private. You don't need any good engineering principles at all, use goto to your heart's content. It just doesn't matter.
> Not the point. We talking about encapsulating code which involves creation of another modules which always involved in creation of another file. Which is not always good solution if your code is remarkably small.

That wasn't my point either. My point is that if your code is "remarkably small", you don't need _any_ good engineering practices. You don't need encapsulation, abstraction, maintainability, anything. It's like killing an ant with a bazooka.

Pretty much nothing you do in a 100 SLOC codebase matters unless it's a library, in which case the only important thing is the API.

>> That makes as much sense to me as introducing a keyword to protect a class from itself.
> It the equivalent of building another house to give your new child its own room, when you can simply assign a room in the house that you already have.

That's the beauty of code, isn't it? Building another house is easy so why not? If in real life I could conjure a whole new house in less than a second for a child to live in, why wouldn't I???
November 02, 2018
On Thursday, 1 November 2018 at 18:46:37 UTC, Patrick Schluter wrote:
> On Thursday, 1 November 2018 at 14:28:27 UTC, Atila Neves wrote:
>> On Tuesday, 30 October 2018 at 08:18:57 UTC, Bastiaan Veelo wrote:
>>> On Tuesday, 30 October 2018 at 00:01:18 UTC, unprotected-entity wrote:
>>>> On Monday, 29 October 2018 at 22:24:22 UTC, Bastiaan Veelo wrote:

>> Friends don't let friends use unsigned types for counting.
>
> My experience is exactly the opposite. I inherited a code base of ~200K lines of C written over 3 decades by several developers of varying skills. You can not imagine how many bugs I found thanks to replacing int and long by size_t and uint32_t/uint64_t.
>
> int i = 0;
> ints[--i];  // look ma, no errors or warnings! indeed
>
> with size_t i at least you get segfault or a bus error.

I'm interested in knowing how you don't get a segfault with a signed integer. I'm guessing a big block of pre-allocated memory?

> The worst offense is using int on 64 bit machines when working on big datasets, overflows are really more common than people expect.

The problem there is using `int`, not the fact that `int` is signed.

> When using unsigned, it requires indeed to be careful when interacting with other variable, but since when is sloppiness a virtue?

In programming? Laziness is always a virtue. If I wanted to be careful when I write code, I wouldn't be on this forum.

Besides, even if *I'm* careful, my colleagues might not be, and it'll be me paying the gdb price.

> The thing is, all the code that used int as a default was code that was not thought through concerning the range of values and limits of the used variables.

I learned C using 16-bit Borland, which meant `int` was the same as `short`. Every time I wrote a for loop back then I had to consider if I needed `long` instead.
November 02, 2018
On Friday, 2 November 2018 at 00:54:43 UTC, Adam D. Ruppe wrote:
> On Thursday, 1 November 2018 at 23:23:55 UTC, unprotected-entity wrote:
>> It's about clean architecture.
>
> If you use interfaces correctly, there will be no private members accessible regardless of privacy and D's module system.
>
> interface I {}
> class B : I {}
>
> void workWithIt(I i) {
>     // nothing in B is accessible without ugly casts!
> }

Yeah, if you're doing OOP and you're not passing interfaces around, you're doing it wrong.
November 02, 2018
On Friday, 2 November 2018 at 11:43:13 UTC, Atila Neves wrote:
> On Thursday, 1 November 2018 at 17:59:35 UTC, Steven Schveighoffer wrote:

>> So... don't test private functions?
>
> Precisely.
>
> Caveat: test them if you *really* want to, but be prepared to delete the tests with extreme prejudice.
>
> I never do, implementation details are just that.

Sometimes you need to, even if you don't want to. Say you're implementing a container, for simplicity let's say an Array!T (akin to Vector from your automem library). Because it's D, the author needs to be aware of GC implications. Namely, when removing elements from the array, or reserving additional storage, and `T` may have indirections, the Array should wipe unused storage (or appropriate bits) to eliminate false pointers. This isn't a part of public interface at all, but still something that should be tested against.
November 02, 2018
On Friday, 2 November 2018 at 11:50:05 UTC, Atila Neves wrote:
> On Thursday, 1 November 2018 at 18:30:33 UTC, 12345swordy wrote:
>> On Thursday, 1 November 2018 at 17:58:34 UTC, Atila Neves wrote:
>>> [...]
>> Not the point. We talking about encapsulating code which involves creation of another modules which always involved in creation of another file. Which is not always good solution if your code is remarkably small.
>
> That wasn't my point either. My point is that if your code is "remarkably small", you don't need _any_ good engineering practices. You don't need encapsulation, abstraction, maintainability, anything. It's like killing an ant with a bazooka.
When I said, "small code" I wasn't referring to the entire program itself, I was referring to the code being encapsulated.

-Alex


November 02, 2018
On Thursday, 1 November 2018 at 17:59:35 UTC, Steven Schveighoffer wrote:
> However, I would *love* to be able to specify unit tests that *can't* access private internals for testing purposes. IIRC, it was proposed at some point to require this for documented unittests.

How about public and private unittest?

As a unittest is not a symbol, public and private cannot apply in the usual manner. In that context, a public unittest -- even in the same module -- is meant to test the public interface of something and therefore cannot access private state. A private (the default) unittest, on the other hand, tests private state.
As another consequence, public (and private) with colon or braces do not apply to unittest; unittests must be marked directly. We could introduce "public unittest:" or even require syntactically that public (and private) are written after "unittest", i.e. "unittest public { ... }" to reduce confusion with visibility attributes.

I once whished for that feature, too, and forgot about it.