February 07, 2018
I was reading https://github.com/rikkimax/stdc-signatures/blob/master/stdc/graphic/image.d#L54 as part of https://github.com/rikkimax/DIPs/blob/master/DIPs/DIP1xxx-RC.md and it struck me that the duplication of `IFoo` and `ISharedFoo` might be made redundant `with inout(shared)` as `inout` (->`inout(const)`? so that one can write `inout(shared,const)`. obviously no need to deprecate plain inout) is to mutable/const/immutable.

I think this would work for "declarations" like interfaces/signatures/contraints, I'm not so sure about implementations as the acquisition of ownership needs to occur to take place in order to avoid data races.

Maybe inout(shared=(T t){...}) where (T t){...} is a lamda (or some other builtin) that ensures that t (or this) is owned by by the executing thread. could also have inout(shared=synchronized), inout(shared=synchronized(a)) where a is a variable in scope (e.g. parameter, member,...), inout(shared=atomic) or some wrapper that atomically loads t or this. Just throwing out ideas.

I don't think this would work on the return value of functions.

Thoughts? Worthy of a DIP?

Nic
February 07, 2018
On 2/7/18 5:19 AM, Nicholas Wilson wrote:
> I was reading https://github.com/rikkimax/stdc-signatures/blob/master/stdc/graphic/image.d#L54 as part of https://github.com/rikkimax/DIPs/blob/master/DIPs/DIP1xxx-RC.md and it struck me that the duplication of `IFoo` and `ISharedFoo` might be made redundant `with inout(shared)` as `inout` (->`inout(const)`? so that one can write `inout(shared,const)`. obviously no need to deprecate plain inout) is to mutable/const/immutable.
> 
> I think this would work for "declarations" like interfaces/signatures/contraints, I'm not so sure about implementations as the acquisition of ownership needs to occur to take place in order to avoid data races.
> 
> Maybe inout(shared=(T t){...}) where (T t){...} is a lamda (or some other builtin) that ensures that t (or this) is owned by by the executing thread. could also have inout(shared=synchronized), inout(shared=synchronized(a)) where a is a variable in scope (e.g. parameter, member,...), inout(shared=atomic) or some wrapper that atomically loads t or this. Just throwing out ideas.
> 
> I don't think this would work on the return value of functions.
> 
> Thoughts? Worthy of a DIP?

I'm thinking it doesn't work.

Not because it wouldn't be sound from the standpoint of the type system, but because there is no "possibly shared" type constructor similar to const. If you are inside an inout(shared) function, how do you properly deal with the data? At the moment it's custom based on what your overall structure looks like. Sure, there are atomics for small shared data types, and at that level, you could conservatively just atomically load and store data. But what about shared aggregates? Those require locking at the right places, and there is no compiler-defined way to do it -- you have to write it yourself. There's just no way to do a "maybe shared" implementation for it.

-Steve