Re: We need an internal keyword.

2018-10-22 Thread 12345swordy via Digitalmars-d
On Monday, 22 October 2018 at 11:06:42 UTC, Jonathan M Davis 
wrote:
On Monday, October 22, 2018 2:30:21 AM MDT Basile B. via 
Digitalmars-d wrote:
On Monday, 22 October 2018 at 08:25:17 UTC, Andrea Fontana 
wrote:
> Moreover: you're the author of the module so you're supposed 
> to know how it works and which members you should call or 
> not.


- team
- maintainer of a module written by someone that works 
elsewhere

now.

that's two cases where strict privacy can be optionally a 
thing avoiding wrong usage of private members within the scope 
of a module.


Part of the point is that if the module is large enough that 
the folks working on the code can't actually keep track of 
what's in it, then it's too large, and as such, if you need to 
protect your class or struct members from the rest of the 
module, then it really should be in a separate module for the 
code to be properly maintainable anyway. Yes, having multiple 
people involved makes the problem worse (especially when some 
of them join the team later), but it doesn't fundamentally 
change the issue. If it changes anything, it simply makes the 
argument stronger for preferring smaller modules so that 
they're easier to digest.


Personally, I've found that larger modules have worked just 
fine for me without having to worry about these sort of 
encapsulation issues. It simply isn't a problem, and I don't 
recall ever seeing a bug because of it. But anyone who's 
worried about it always has the option of simply going for 
smaller modules, and the encapsulation problem is already 
solved without making the language any more complicated. Plenty 
of folks already think that it's best practice te prefer 
relatively small modules anyway, and if you need a way to 
protect your private member variables from the module when the 
module isn't large, then you're definitely doing something 
wrong.


Given the D philosophy that the module is the primary unit of 
encapsulation and that you should at least roughly understand 
the entire module when working on it (or it's almost certainly 
too large), having an access level to protect member variables 
from the rest of the module simply makes no sense. Anyone who 
feels the need for such an access level think about what 
they're doing with their code and why they feel the need for it 
- whether it's simply because they're used to it from other 
languages, or because they're organizing their code in a manner 
which is detrimental to maintainability.


- Jonathan M Davis


Here is the intial dip draft: 
https://github.com/12345swordy/DIPs/tree/Encapsulation
If Walter Bright insist that the module is the unit of 
encapsulation then I propose we get rid of the "one module per 
file" restriction, by introducing sub modules.


-Alex


Re: We need an internal keyword.

2018-10-22 Thread Jonathan M Davis via Digitalmars-d
On Monday, October 22, 2018 2:30:21 AM MDT Basile B. via Digitalmars-d 
wrote:
> On Monday, 22 October 2018 at 08:25:17 UTC, Andrea Fontana wrote:
> > Moreover: you're the author of the module so you're supposed to
> > know how it works and which members you should call or not.
>
> - team
> - maintainer of a module written by someone that works elsewhere
> now.
>
> that's two cases where strict privacy can be optionally a thing
> avoiding wrong usage of private members within the scope of a
> module.

Part of the point is that if the module is large enough that the folks
working on the code can't actually keep track of what's in it, then it's too
large, and as such, if you need to protect your class or struct members from
the rest of the module, then it really should be in a separate module for
the code to be properly maintainable anyway. Yes, having multiple people
involved makes the problem worse (especially when some of them join the team
later), but it doesn't fundamentally change the issue. If it changes
anything, it simply makes the argument stronger for preferring smaller
modules so that they're easier to digest.

Personally, I've found that larger modules have worked just fine for me
without having to worry about these sort of encapsulation issues. It simply
isn't a problem, and I don't recall ever seeing a bug because of it. But
anyone who's worried about it always has the option of simply going for
smaller modules, and the encapsulation problem is already solved without
making the language any more complicated. Plenty of folks already think that
it's best practice te prefer relatively small modules anyway, and if you
need a way to protect your private member variables from the module when the
module isn't large, then you're definitely doing something wrong.

Given the D philosophy that the module is the primary unit of encapsulation
and that you should at least roughly understand the entire module when
working on it (or it's almost certainly too large), having an access level
to protect member variables from the rest of the module simply makes no
sense. Anyone who feels the need for such an access level think about what
they're doing with their code and why they feel the need for it - whether
it's simply because they're used to it from other languages, or because
they're organizing their code in a manner which is detrimental to
maintainability.

- Jonathan M Davis





Re: We need an internal keyword.

2018-10-22 Thread Basile B. via Digitalmars-d

On Monday, 22 October 2018 at 08:25:17 UTC, Andrea Fontana wrote:
Moreover: you're the author of the module so you're supposed to 
know how it works and which members you should call or not.


- team
- maintainer of a module written by someone that works elsewhere 
now.


that's two cases where strict privacy can be optionally a thing 
avoiding wrong usage of private members within the scope of a 
module.




Re: We need an internal keyword.

2018-10-22 Thread Andrea Fontana via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


As just said by others, if you need it probably your module is 
too big and you have to split.


Moreover: you're the author of the module so you're supposed to 
know how it works and which members you should call or not. 
Anyway since they're private you can name them in particular way 
to remember yourself not to use them eg: int internal_A;


Andrea


Re: We need an internal keyword.

2018-10-22 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 23:50:57 UTC, 12345swordy wrote:
If the cost out way the benefits then I simply introduce the 
"strict" keyword to avoid code breakage, or introduce the 
optional module scoping.


-Alex


Looking at the dlang.org page about visibility attributes, the 
`package` keyword can have an argument specifying which package 
has access to the symbol.
What if `private` could have an argument dictating which other 
symbol could have access to that private symbol ?
Setting this argument to the private symbol's own class would 
effectively make it strictly private. This wouldn't require a new 
keyword, and that syntax is not valid D code so it wouldn't break 
any existing code.
Though it would look a bit weird, and it would also basically 
introduce a sort of "friend" feature.


I don't know, that was just a random thought that crossed my mind 
just now.


Re: We need an internal keyword.

2018-10-22 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 23:50:57 UTC, 12345swordy wrote:
On Sunday, 21 October 2018 at 21:48:22 UTC, Laurent Tréguier 
wrote:

On Sunday, 21 October 2018 at 17:09:05 UTC, 12345swordy wrote:

[...]


It's not "my" solution. It's D's solution. I perfectly 
understand why you'd want this and I would probably make use 
of a private/internal difference myself if it was available.


If you already know about this solution however, I don't even 
know why you're starting this thread; since changing the 
behavior of private would be a major language change breaking 
tons of existing codebases, plus it would require adding yet 
another keyword.


Given that this conversation has happened before and things 
haven't changed, I'm very doubtful that it could happen at any 
point in time, sadly.


If the cost out way the benefits then I simply introduce the 
"strict" keyword to avoid code breakage, or introduce the 
optional module scoping.


-Alex


Technically, introducing any new keyword is also a potentially 
code breaking change. Any symbol named "strict" would have to be 
changed. This is why I'm doubtful that such a change would be 
accepted.


Re: We need an internal keyword.

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/20/18 11:17 PM, 12345swordy wrote:
So that classes can share some of their variables but not others in a 
module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


I've always felt the same.

I certainly don't intend this as a way to say "just accept it and forget 
about it", but FWIW, I've learned to live with it: I just regard 
accessing such privates from outside their class/struct to be bad style. 
I mean, I agree it's not ideal, but at least it doesn't prevent me from 
getting things done. Again, FWIW.


That said though, it *can* sometimes be helpful for tests and debugging 
to be able to reach into a class/struct and muck about with the 
privates. (tee hee). But FWIW, I do agree. If D were my own language, 
I'd probably have done it a little differently: I would've taken the 
current "private" behavior and called it something like "module", and 
made "private" behave the way it does in other languages.




Re: We need an internal keyword.

2018-10-21 Thread 12345swordy via Digitalmars-d
On Sunday, 21 October 2018 at 21:48:22 UTC, Laurent Tréguier 
wrote:

On Sunday, 21 October 2018 at 17:09:05 UTC, 12345swordy wrote:

[...]


It's not "my" solution. It's D's solution. I perfectly 
understand why you'd want this and I would probably make use of 
a private/internal difference myself if it was available.


If you already know about this solution however, I don't even 
know why you're starting this thread; since changing the 
behavior of private would be a major language change breaking 
tons of existing codebases, plus it would require adding yet 
another keyword.


Given that this conversation has happened before and things 
haven't changed, I'm very doubtful that it could happen at any 
point in time, sadly.


If the cost out way the benefits then I simply introduce the 
"strict" keyword to avoid code breakage, or introduce the 
optional module scoping.


-Alex


Re: We need an internal keyword.

2018-10-21 Thread 12345swordy via Digitalmars-d
On Sunday, 21 October 2018 at 19:53:35 UTC, Jonathan M Davis 
wrote:
On Saturday, October 20, 2018 9:17:23 PM MDT 12345swordy via 
Digitalmars-d wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


Well, if you feel strongly enough about it, you can always 
create a DIP to try to change things, but I think that I can 
quite safely say that you have pretty much no chance of it 
getting accepted. Walter has been quite clear on this topic 
when it has been discussed previously (and there was a major 
discussion on it not very long ago). It is very much on purpose 
that access is controlled at the module level, and if your 
module is large enough that it is actually causing problems for 
a class or struct to not be able to disallow access of its 
members to other symbols in the module, then the module is too 
large, and the class should be put in a separate module. We 
already have full control of who can access the members of a 
class or struct by controlling which module or package its in 
and what else is in that module or package with it. If you want 
greater control without splitting up your modules more (at 
least as far as importing goes), you can always take advantage 
of public imports to split the code itself into more modules 
while making it possible to get all of the symbols with a 
single import statement.


Certainly, if we had internal or friend or other mechanisms for 
more fine-grained control without doing it at the module-level, 
it would eliminate the need to put code into separate modules 
in some cases, but it would also complicate the language, and 
what we have works quite well in general.


If you don't like the fact that member access is done at the 
module level, then I'm sorry, but overall, this really seems to 
be a philosphical complaint and not a practical one, and Walter 
has made his stance on it very clear. Based on what he's said 
previously, you would need very strong, practical arguments for 
why it's causing actual bugs in programs and why the current 
approach is not cutting it to stand any chance of convincing 
Walter. And honestly, I have never seen anyone come up with an 
argument that was particularly good in that regard. It mostly 
seems to come down to folks simply objecting to the idea that 
anything inside a module would have access to a class' private 
members rather than that it's actually caused bugs. In 
practice, it's usually either actually useful, or it doesn't 
matter.


Either way, simply making post stating that you think that we 
should have the feature isn't going to get you anywhere. If you 
want it, you'll need to find a way to convince Walter.


- Jonathan M Davis
I do plan to write a DIP on this, no question about it. However 
walter have been shown to change his mind unexpectedly. (Remember 
the "mangle symbol only" discussion that manu had argue in favor 
of, which we all thought he sternly opposed to, only to changed 
his mind at the last minute, when a pull request shown up?)


Yes I am aware of the previous discussion regarding this. How can 
I forget about it as that guy who complain about it resort to 
imposter other people including me.


https://forum.dlang.org/thread/vpxoidaqfbfrnnsep...@forum.dlang.org?page=1


However that guy didn't property explain why this was an issue. 
The issue is encapsulation and the traditional get and set 
functions for security checking and value checking, etc, before 
setting the value, retrieving the value and after setting the 
value. Programmers such my self sometimes find it easier to 
maintain classes if they are put in the same file, rather than in 
each own file.
The "package" solution brought up by another user risk the 
possibility of making things more complicated and harder to 
maintain than it should be, when working with code that is 
considerably small spread across multiple files.


I have two solutions in mind:
A.)Introduce the keyword "strict" for the other keywords private 
and protected  only class and structs to prevent being accessed 
from outside the class in the same module by accident.

Example:
class A
{
strict private int x;// This can't be shared in module
strict protected int y; //ditto
private int x; //This can be shared in module
protected int y; //ditto
}
B.)Get rid of the "one module per file" restriction by 
introducing optional module scoping to allow multiple modules in 
a file to allow easy package creation for code that is consider 
to be small without having to maintain multiple files.

Module C;
Module A // Module A in the C package
{

}
module B // AKA B.A
{

}

-Alex


Re: We need an internal keyword.

2018-10-21 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 17:48:08 UTC, Neia Neutuladh wrote:

On Sun, 21 Oct 2018 08:40:36 +, Laurent Tréguier wrote:
This is by design; the D way of dealing with this would be to 
split the module into a package with multiple modules.


This is often a usable way of doing things, but sometimes not 
so much. If you're writing a script for use with dub --single 
or rdmd, you lose a lot of convenience if you use multiple 
files. It might also take a lot of time to split things up once 
static constructors get involved.


As far as single file scripts go, I don't think something like 
100% perfect encapsulation is always required. A single file 
script is usually a quick way to do a specific thing once or 
twice, and not a persistent project demanding the best code 
quality.


Re: We need an internal keyword.

2018-10-21 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 17:09:05 UTC, 12345swordy wrote:
I know what the current design is!! You have zero tools in 
regarding to allowing class to share certain variables but not 
others in the same module! Create a module for every class is 
taking all or nothing approach, when there is a reasonable 
middle ground.
Your package solution just make things more unnecessarily 
complicated then warranted


It's not "my" solution. It's D's solution. I perfectly understand 
why you'd want this and I would probably make use of a 
private/internal difference myself if it was available.


If you already know about this solution however, I don't even 
know why you're starting this thread; since changing the behavior 
of private would be a major language change breaking tons of 
existing codebases, plus it would require adding yet another 
keyword.


Given that this conversation has happened before and things 
haven't changed, I'm very doubtful that it could happen at any 
point in time, sadly.


Re: We need an internal keyword.

2018-10-21 Thread Jonathan M Davis via Digitalmars-d
On Saturday, October 20, 2018 9:17:23 PM MDT 12345swordy via Digitalmars-d 
wrote:
> So that classes can share some of their variables but not others
> in a module.
>
> IE.
>
> class A
> {
> internal int A; //This is shared in the module
> private int B; // But not this.
> }
>
> No need to reintroduce the "Friend" feature from cpp.

Well, if you feel strongly enough about it, you can always create a DIP to
try to change things, but I think that I can quite safely say that you have
pretty much no chance of it getting accepted. Walter has been quite clear on
this topic when it has been discussed previously (and there was a major
discussion on it not very long ago). It is very much on purpose that access
is controlled at the module level, and if your module is large enough that
it is actually causing problems for a class or struct to not be able to
disallow access of its members to other symbols in the module, then the
module is too large, and the class should be put in a separate module. We
already have full control of who can access the members of a class or struct
by controlling which module or package its in and what else is in that
module or package with it. If you want greater control without splitting up
your modules more (at least as far as importing goes), you can always take
advantage of public imports to split the code itself into more modules while
making it possible to get all of the symbols with a single import statement.

Certainly, if we had internal or friend or other mechanisms for more
fine-grained control without doing it at the module-level, it would
eliminate the need to put code into separate modules in some cases, but it
would also complicate the language, and what we have works quite well in
general.

If you don't like the fact that member access is done at the module level,
then I'm sorry, but overall, this really seems to be a philosphical
complaint and not a practical one, and Walter has made his stance on it very
clear. Based on what he's said previously, you would need very strong,
practical arguments for why it's causing actual bugs in programs and why the
current approach is not cutting it to stand any chance of convincing Walter.
And honestly, I have never seen anyone come up with an argument that was
particularly good in that regard. It mostly seems to come down to folks
simply objecting to the idea that anything inside a module would have access
to a class' private members rather than that it's actually caused bugs. In
practice, it's usually either actually useful, or it doesn't matter.

Either way, simply making post stating that you think that we should have
the feature isn't going to get you anywhere. If you want it, you'll need to
find a way to convince Walter.

- Jonathan M Davis





Re: We need an internal keyword.

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sun, 21 Oct 2018 08:40:36 +, Laurent Tréguier wrote:
> This is by design; the D way of dealing with this would be to split the
> module into a package with multiple modules.

This is often a usable way of doing things, but sometimes not so much. If 
you're writing a script for use with dub --single or rdmd, you lose a lot 
of convenience if you use multiple files. It might also take a lot of time 
to split things up once static constructors get involved.


Re: We need an internal keyword.

2018-10-21 Thread 12345swordy via Digitalmars-d
On Sunday, 21 October 2018 at 08:40:36 UTC, Laurent Tréguier 
wrote:

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


This is by design; the D way of dealing with this would be to 
split the module into a package with multiple modules. The A 
class would be in its own module, and use `package` where you 
used `internal` so that other modules in the same package can 
have access to it.
Using a package.d package module 
(https://dlang.org/spec/module.html#package-module), you can 
still use the multiple modules just as if they were a single 
module.


Instead of a source tree like this:

source
|
+-some
  |
  +-thing.d

You'd end up with a source tree like this:

source
|
+-some
  |
  +-thing
|
+-package.d
|
+-a.d
|
+-rest_of_the_stuff.d

Where package.d publicly imports a.d and rest_of_the_stuff.d, 
so `import some.thing` would still work.
I know what the current design is!! You have zero tools in 
regarding to allowing class to share certain variables but not 
others in the same module! Create a module for every class is 
taking all or nothing approach, when there is a reasonable middle 
ground.
Your package solution just make things more unnecessarily 
complicated then warranted





Re: We need an internal keyword.

2018-10-21 Thread luckoverthere via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


I feel like if this is a problem your Module has too much in it 
and you should refactor it into more than 1 module. If you need 
to protect a module from itself then I feel like there is too 
much in it, essentially.


Re: We need an internal keyword.

2018-10-21 Thread Basile B. via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


I partially agree because Object Pascal uses `strict private` for 
this. IIRC they needed at some point to make this for their 
Objective-C compatibility. I find it occasionally useful for 
example to enforce the usage of the getters method over their 
matching fields (if they do lazy update, lazy init, or such 
things). So far in D the way to do this is to put the stuff that 
has to be strictly private (or internal if you prefer) in a 
dedicated module.


This suggestion comes semi-regularly on the forum and last time 
it did, the whole topic got very unfriendly so while i partially 
agree i have to say that i don't really care. It's a small 
sympathetic feature, but i can live without.


Baz.


Re: We need an internal keyword.

2018-10-21 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


This is by design; the D way of dealing with this would be to 
split the module into a package with multiple modules. The A 
class would be in its own module, and use `package` where you 
used `internal` so that other modules in the same package can 
have access to it.
Using a package.d package module 
(https://dlang.org/spec/module.html#package-module), you can 
still use the multiple modules just as if they were a single 
module.


Instead of a source tree like this:

source
|
+-some
  |
  +-thing.d

You'd end up with a source tree like this:

source
|
+-some
  |
  +-thing
|
+-package.d
|
+-a.d
|
+-rest_of_the_stuff.d

Where package.d publicly imports a.d and rest_of_the_stuff.d, so 
`import some.thing` would still work.