October 19, 2018
On 10/17/2018 4:29 AM, jmh530 wrote:
> Isn't that also true for isolated data (data that only allows one alias)?

That's colloquially called "unique" data. And yes, it is also true for that. That's why casting the return value of malloc() to 'shared' is safe. It's just that the language has no way to semantically identify unique data with its current type system.

October 19, 2018
On 19/10/2018 9:02 PM, Walter Bright wrote:
> On 10/17/2018 4:29 AM, jmh530 wrote:
>> Isn't that also true for isolated data (data that only allows one alias)?
> 
> That's colloquially called "unique" data. And yes, it is also true for that. That's why casting the return value of malloc() to 'shared' is safe. It's just that the language has no way to semantically identify unique data with its current type system.

Actually we kind of have a way to do this (I think). Scope. It can't cross the thread boundary and it has a pretty clear owner as far as the stack is concerned. Given a bit of time and empowering of scope, we could do a @scopeonly type attribute for functions.

October 19, 2018
On 10/17/2018 12:20 AM, Manu wrote:
> What does it mean 'aliased' precisely?

Aliasing means there are two paths to the same piece of data. That could be two pointers pointing to the same data, or one pointer to a variable that is accessible by name.

> It doesn't really give us
> anything in practice that we don't have in C++.

It provides a standard, enforced way to distinguish shared data from unshared data, and no way to bypass it in @safe code. There's no way to do that in C++.
October 19, 2018
On Friday, 19 October 2018 at 06:25:00 UTC, rikki cattermole wrote:
> On 19/10/2018 7:09 PM, Norm wrote:

> [0] https://github.com/rikkimax/DIPs/blob/shared/DIPs/DIP1xxx-RC2.md

This document provide no reasoning about what usecases it supports:

Is it possible to create objects that are shared just for short periods during their livetime and guarantee that they can be used threadsave like Manu want it to be?

Does it prohibit misuse any better than Manus proposal (that requires the "Expert" to implement all theadsave API)?

Is the "normal" User still enforced to do some unsave casts?

Has the normal User to have high knownledge of how a threadsave API is to be used or can the compiler provide any guarantees that using them can only fail if the implementation behind the API has bugs (e.g. provide some encapsulation)?

Or any other usecases why and how this design is better than what we have now?

And also some ideas how to implement some useacases (examples) are completely missing.
October 19, 2018
On 10/18/18 9:09 PM, Manu wrote:
> On Thu, Oct 18, 2018 at 5:30 PM Timon Gehr via Digitalmars-d
> <digitalmars-d@puremagic.com> wrote:
>>
>> On 18.10.18 23:34, Erik van Velzen wrote:
>>> If you have an object which can be used in both a thread-safe and a
>>> thread-unsafe way that's a bug or code smell.
>>
>> Then why do you not just make all members shared? Because with Manu's
>> proposal, as soon as you have a shared method, all members effectively
>> become shared.
> 
> No they don't, only facets that overlap with the shared method.
> I tried to present an example before:
> 
> struct Threadsafe
> {
>    int x;
>    Atomic!int y;
>    void foo() shared { ++y; } // <- shared interaction only affects 'y'
>    void bar() { ++x; ++y; } // <- not threadsafe, but does not violate
> foo's commitment; only interaction with 'y' has any commitment
> associated with it
>    void unrelated() { ++x; } // <- no responsibilities are transposed
> here, you can continue to do whatever you like throughout the class
> where 'y' is not concerned
> }
> 
> In practise, and in my direct experience, classes tend to have exactly
> one 'y', and either zero (pure utility), or many such 'x' members.
> Threadsafe API interacts with 'y', and the rest is just normal
> thread-local methods which interact with all members thread-locally,
> and may also interact with 'y' while not violating any threadsafety
> commitments.

I promised I wouldn't respond, I'm going to break that (obviously).

But that's because after reading this description I ACTUALLY understand what you are looking for.

I'm going to write a fuller post later, but I can't right now. But the critical thing here is, you want a system where you can divvy up a type into pieces you share and pieces you don't. But then you *don't* want to have to share only the shared pieces. You want to share the whole thing and be sure that it can't access your unshared pieces.

This critical requirement makes things a bit more interesting. For the record, the most difficult thing to reaching this understanding was that whenever I proposed anything, your answer was something like 'I just can't work with that', and when I asked why, you said 'because it's useless', etc. Fully explaining this point is very key to understanding your thinking.

To be continued...

-Steve
October 19, 2018
On Fri., 19 Oct. 2018, 6:10 am Dominikus Dittes Scherkl via Digitalmars-d, < digitalmars-d@puremagic.com> wrote:

> On Friday, 19 October 2018 at 06:25:00 UTC, rikki cattermole wrote:
> > On 19/10/2018 7:09 PM, Norm wrote:
>
> > [0] https://github.com/rikkimax/DIPs/blob/shared/DIPs/DIP1xxx-RC2.md
>
> This document provide no reasoning about what usecases it supports:
>
> Is it possible to create objects that are shared just for short periods during their livetime and guarantee that they can be used threadsave like Manu want it to be?
>
> Does it prohibit misuse any better than Manus proposal (that requires the "Expert" to implement all theadsave API)?
>

No, a key misunderstanding. My proposal is @safe. The only thing an expert
must do is write the few @trusted implementations that live at the very
bottom of the stack.
That would always be in a lib. When was the last time you rewrote std::map
because you thought you could do better?

The whole stack from there on up (the user stack) is safe, and you can have
confidence in the @safe-ty.
My goal is to make it safe, clearly communicate how a user interact with
the API, and mechanically confirm that users do the right stuff.
My proposal is specifically structured to not require *any* unsafe
interactions at the user level. Only core machinery that is @trusted needs
expert attention.

I don't think it's possible to invent a proposal with a higher degree of verifiable safety.


October 19, 2018
On Thursday, 18 October 2018 at 19:04:58 UTC, Erik van Velzen wrote:
> On Thursday, 18 October 2018 at 17:47:29 UTC, Stanislav Blinov wrote:
>> On Thursday, 18 October 2018 at 17:17:37 UTC, Atila Neves wrote:
>>> On Monday, 15 October 2018 at 18:46:45 UTC, Manu wrote:
>>>> Assuming the rules above: "can't read or write to members", and the understanding that `shared` methods are expected to have threadsafe implementations (because that's the whole point), what are the risks from allowing T* -> shared(T)* conversion?
>>>
>>> int i;
>>> tid.send(&i);
>>> ++i;  // oops, data race
>>
>> Doesn't work. No matter what you show Manu or Simen here they think it's just a bad contrived example. You can't sway them by the fact that the compiler currently *prevents* this from happening.
>
> Manu said clearly that the receiving thread won't be able to read or write the pointer.

Not directly - but obviously there must be *some* way to using it, in this case since it's an int with one of the core.atomic functions. At that point the spawned thread will be accessing it correctly, but the parent thread can modify the int in a non-atomic fashion.

> Because int or int* does not have threadsafe member functions.

https://dlang.org/phobos/core_atomic.html



October 19, 2018
On Thursday, 18 October 2018 at 21:24:53 UTC, jmh530 wrote:
> On Thursday, 18 October 2018 at 17:17:37 UTC, Atila Neves wrote:
>> [snip]
>>
>>> Assuming this world... how do you use shared?
>>
>> https://github.com/atilaneves/fearless
>>
>
> I had posted your library before to no response...
>
> I had two questions, if you'll indulge me.
>
> The first is perhaps more wrt automem. I noticed that I couldn't use automem's Unique with @safe currently. Is there any way to make it @safe, perhaps with dip1000?

Yeah, I punted on making anything there @safe. I have to go back and fix it. At least I wrote Vector from scratch to be @safe.

> Second, Rust's borrow checker is that you can only have one mutable borrow. This is kind of like Exclusive, but it does it at compile-time, rather than with GC/RC. Is this something that can be incorporated into fearless?

Well, Rust's version of Exclusive is Mutex, and that's pretty much always used with Arc. The closest we have to a borrow checker is DIP1000 and that's what fearless relies on.



October 20, 2018
On 20/10/2018 2:07 AM, Dominikus Dittes Scherkl wrote:
> This document provide no reasoning about what usecases it supports:

It was a basic idea of mine... It was never meant to be PR'd.
October 19, 2018
On Friday, 19 October 2018 at 18:00:47 UTC, Atila Neves wrote:
>> Because int or int* does not have threadsafe member functions.
>
> https://dlang.org/phobos/core_atomic.html

Atomic and thread-safe are two very different concepts. Thread-safe is more of an ecosystem thing - if there are ways to do non-thread-safe operations on something, atomic operations are not enough to make things thread-safe. This is what core.atomic does:

https://i.imgur.com/PnKMigl.jpg

If you close the other openings, atomics are fantastic building blocks to making something thread-safe, but on their own they are not enough.

--
  Simen