Why D is not popular enough?

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Sat Aug 13 13:45:16 PDT 2016


On 8/12/16 7:22 PM, Andrei Alexandrescu wrote:
> On 8/12/16 6:58 PM, Steven Schveighoffer wrote:
>> On 8/12/16 2:04 PM, Andrei Alexandrescu wrote:
>>> On 08/12/2016 01:21 PM, Steven Schveighoffer wrote:
>>>> On 8/12/16 1:04 PM, Jonathan M Davis via Digitalmars-d wrote:
>>>>>
>>>>> Honestly, I don't think that shared is broken.
>>>>
>>>> Yes. It is broken.
>>>>
>>>> shared int x;
>>>> ++x; // error, must use atomicOp.
>>>> x = x + 1; // OK(!)
>>>
>>> How is this broken and how should it behave? -- Andrei
>>>
>>
>> It's broken because it's inconsistent. If the compiler is going to
>> complain about races in one case, but not in other equivalent cases,
>> then the feature is useless.
>
> But ++expr and expr1 = expr1 + expr2 are fundamentally different.

It's not expr2, it's 1.

And no they aren't fundamentally different. Don't think like a compiler.

>> If all I have to do to avoid compiler complaints is rewrite my
>> expression in an equivalent way, then what is the point of the
>> complaint? At that point, it's just a style guide.
>
> A bunch of rewrites to seemingly identical behavior to avoid type errors
> are de rigoeur in so many situations. This is no different.

It's not a type error. We have const, and pure, and @safe, which require 
you to write code in a way that enforces a guarantee.

shared does this in a half-assed way. It's not effective. It's like C++ 
const is not effective at guaranteeing anything stays constant.

>> What should it do? If I knew that, then I'd have proposed a DIP by now.
>> It's not an easy problem to solve. I don't think you can "solve" races
>> because the compiler can't see all interactions with data.
>
> ++expr contains a low-level race that is worth removing. Extending that
> to a variety of sub-patterns of expr1 = expr2 + expr3 seems a terrible
> idea to me.

I agree that in general races cannot be detected and prevented. ++expr1 
is an obvious race, and it is detected and prevented. But it gives the 
impression that the compiler isn't going to let you make races. It gives 
the impression that the language has some level of guarantee about 
avoiding multi-threaded mistakes. It doesn't. It doesn't guarantee 
anything. It's just a helpful trick in one specific case.

I don't know what the right way to handle shared is. My opinion is 
simply that shared needs special handling from the user. The compiler 
isn't going to help you make thread-safe code, but at least allows you 
to mark where the unsafe code could be (by using shared type modifier).

>> At first glance, it seems that shared data shouldn't be usable without
>> some kind of explicit usage syntax. x = x + 1 is too innocuous looking.
>> It's not going to "solve" the issue, but it makes the code easier to
>> pick out.
>
> We discussed this at a point (some 10 years ago). It was:
>
> atomicReadRef(x) = atomicRead(x) + 1;
>
> But it's painfully obvious that yes the intent is to read the address
> and read the thing... so why need these anyway? So we left things as
> they are.
>
> I agree shared needs work, but this is not it. We're wasting our time here.

Hey, that's fine. I'd rather work on other things too. Shared just seems 
like an unfulfilled promise, with half-implemented protections.

I'd like to just see shared be unusable, and make people cast away 
shared to do anything. That at least is an attempt at preventing races 
without intention. The allowance of certain things that are obvious 
races, whereas other things that are obvious races are prevented makes 
one assume the worst.

-Steve


More information about the Digitalmars-d mailing list