October 22, 2018
On 10/22/2018 2:31 AM, rikki cattermole wrote:
> As I've said previously, it doesn't need to be a good DIP or anywhere near complete. It just needs code examples comparing current and proposed behavior with some text about semantics changes.

That's right, and it can be evolved so everyone involved can easily see what the latest is, and not get mired in and distracted by resolved issues.
October 22, 2018
On 10/22/2018 2:44 AM, Manu wrote:
> It hasn't changed. Not one single bit. I haven't changed a single
> detail in this thread.

A reader would not know that. Reposting the same thing over and over in a thread is not how threaded discussions work. You've indicated previously you're not even using a threaded newsreader.


> And you STILL ignored my post >_<

I'm going to until you post a DIP. The way this discussion is going is incredibly inefficient of your time and mine, and everyone else's who tries to engage constructively. It's exactly why we have a DIP process.

It's really not hard. You can even use Markdown to make it look much nicer.

https://github.com/dlang/DIPs

https://github.com/dlang/DIPs/blob/master/PROCEDURE.md
October 22, 2018
On 22.10.18 21:29, Manu wrote:
> On Mon, Oct 22, 2018 at 7:10 AM Simen Kjærås via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>>
>> On Monday, 22 October 2018 at 13:40:39 UTC, Timon Gehr wrote:
>>> module reborked;
>>> import atomic;
>>>
>>> void main()@safe{
>>>      auto a=new Atomic!int;
>>>      import std.concurrency;
>>>      spawn((shared(Atomic!int)* a){ ++*a; }, a);
>>>      ++a.tupleof[0];
>>> }
>>
>> Finally! Proof that MP is impossible. On the other hand, why the
>> hell is that @safe? It breaks all sorts of guarantees about
>> @safety. At a minimum, that should be un-@safe.
>>
>> Filed in bugzilla: https://issues.dlang.org/show_bug.cgi?id=19326
> 
> Yeah, that's shockingly dangerous for all sorts of reasons!
> I mean, is this really an argument to destroy my proposal,

It was a way to satisfy Simen's (imho, arbitrary) constraint that the @safe code should be in a different module.

> or are you just destroying @safe in general?
> 

It is likely that there is @trusted code in the wild that is currently broken because of the assumption that private data cannot be modified by untrusted actors. I think if we can have e.g. @trusted data that cannot be manipulated at all from @safe code (including taking addresses), a lot more is possible. shared on variables/fields could then imply @trusted.

It is then however still not clear that it makes sense to allow implicit conversion from unshared to shared. It may still be error prone, or even impossible to realize. For example, it could hypothetically be the case that each processor has its own address space and there is additionally some shared address space, in which case allocation would differ for data that is shared and data that is unshared.

So I would again like to ask: why can't classes that want to be able to have their references implicitly converted to shared and then be sent to other threads not just make all members 'shared'? Under your proposal, they can never know that they have not already been implicitly converted to 'shared' anyway, so any unshared code already needs to take into account the possibility that there are other, concurrent accesses.
October 22, 2018
On Monday, 15 October 2018 at 18:46:45 UTC, Manu wrote:
> Okay, so I've been thinking on this for a while... I think I have a pretty good feel for how shared is meant to be.
>
> [...]

I don't understand how you can safely have simultaneously shared methods that can modify data and unshared references that can modify data.

struct S {
    int* x;
    void incX() shared { ... }
}

auto x = new int;
auto s = shared S(x);

Now I have two references to x, one shared, one unshared, both can be written to.

What am I missing?
October 22, 2018
On 10/22/2018 6:40 AM, Timon Gehr wrote:
>      ++a.tupleof[0];

Yes, tupleof is known to break through the private access barrier. This is an issue, not sure if there's a bugzilla for it.

October 22, 2018
On 10/22/2018 7:31 AM, Timon Gehr wrote:
> Even if this is changed (and it probably should be), it does not fix the case where the @safe function is in the same module. I don't think it is desirable to change the definition of @trusted such that you need to check the entire module if it contains a single @trusted function.
> 
> If I can break safety of some (previously correct) code by editing only @safe code, then that's a significant blow to @safe. I think we need a general way to protect data from being manipulated in @safe code in any way, same module or not.

One possible workaround is to use PIMPL. Another is to put the @trusted privates in a separate module.

The rationale behind module access to privates is:

1. avoid the whole ugly C++ "friend" complexity

2. presumably someone with privileges to edit a module can be trusted to behave

3. the module is the level of encapsulation
October 23, 2018
On Monday, 22 October 2018 at 23:39:37 UTC, Walter Bright wrote:
> On 10/22/2018 7:31 AM, Timon Gehr wrote:
>> [...]
>
> One possible workaround is to use PIMPL. Another is to put the @trusted privates in a separate module.
>
> The rationale behind module access to privates is:
>
> 1. avoid the whole ugly C++ "friend" complexity
>
> 2. presumably someone with privileges to edit a module can be trusted to behave
>
> 3. the module is the level of encapsulation

Quick question, if a class import a module in its scope, does it carry its own copy when creating multiple objects with it?

-Alex
October 23, 2018
On Tue, 23 Oct 2018 00:08:04 +0000, 12345swordy wrote:
> Quick question, if a class import a module in its scope, does it carry its own copy when creating multiple objects with it?

Importing a module doesn't make a copy of any code. Each module contains only its own code. Importing modules makes it so you can access their code, nothing more.

Instances of a class don't contain private copies of their own code. There's only one copy per executable. So even if importing a module made a copy of the code, you'd still only have one copy per type, not per object.
October 23, 2018
On Tuesday, 23 October 2018 at 01:21:32 UTC, Neia Neutuladh wrote:
> On Tue, 23 Oct 2018 00:08:04 +0000, 12345swordy wrote:
>> Quick question, if a class import a module in its scope, does it carry its own copy when creating multiple objects with it?
>
> Importing a module doesn't make a copy of any code. Each module contains only its own code. Importing modules makes it so you can access their code, nothing more.
>
> Instances of a class don't contain private copies of their own code. There's only one copy per executable. So even if importing a module made a copy of the code, you'd still only have one copy per type, not per object.

Huh, that what I figured. Though it not easy to test it as you literally have to create two files for this.
October 23, 2018
On Mon, 15 Oct 2018 11:46:45 -0700, Manu wrote:
>>From there, it opens up another critical opportunity; T* -> shared(T)*
> promotion.
> Const would be useless without T* -> const(T)* promotion. Shared suffers
> a similar problem.
> If you write a lock-free queue for instance, and all the methods are
> `shared` (ie, threadsafe), then under the current rules, you can't
> interact with the object when it's not shared, and that's fairly
> useless.

Somehow I lost track of your reason behind the promotion.

Why not just ask to be able to call shared methods on a thread-local variable? No implicit casting; you need to take positive action to share anything. And if there's a non-shared overload, that's still preferred.

Would that be enough? Or do you have use cases that wouldn't fit there?