notes-computer-programming-programmingLanguageDesign-prosAndCons-typeSystemsForConcurrency

" To define sharing without races, D has a coherent model for immutability (via the immutable qualifier) and a model for lock-free sharing (via the sharing qualifier). The system is simpler than that of race-free academic languages (i.e. Cormac Flanagan's or Boyapati/ Rinard's work on Java extensions) and also less powerful, but we believe that message passing + immutability + limited sharing form a very compelling proposition.

Go is simpler in that it doesn't formalize sharing, but also wants to be expressive, which exposes it to data races. If you create a channel of *int, my understanding (and please correct me if I'm wrong) only convention can help you from having two threads access the same integer. It only gets worse with pointers to more elaborate data types, and history has shown that convention is a poor mechanism for ensuring thread safety of any kind. For my money that's simply not an option. " -- Andrei Alexandrescu

--

On Aug 13, 9:30 am, Ian Lance Taylor <i...@google.com> wrote: > Andrei Alexandrescu <iro...@gmail.com> writes: > > At the same time we believe that low- > > level races are the worst kind of weakness in a type system. > > That's an interesting perspective. I agree that low-level races are a > serious problem in modern programming. But phrasing in terms of a > problem in the type system seems odd to me.

Here are some starting points that could be helpful:

Object types against races, by Flanagan/Abadi http://tinyurl.com/3xf798g

Type inference against races, by Flanagan/Friend http://tinyurl.com/2uzm729

A parameterized type system for race-free Java programs, by Boyapati/ Rinard http://tinyurl.com/34mvbb8

The papers are rather involved but the introductions tend to give a good overview of the gist of the work.

> I wasn't able to find the docs on the sharing qualifier (the docs > suggest that it is called shared, but I couldn't find any docs on that > either). Can you point me to a description of how it works?

As I mentioned, the entire chapter on concurrency in TDPL is available for free online:

http://www.informit.com/articles/printerfriendly.aspx?p=1609144

> You're quite right: Go does permit data races, and does currently rely > only on convention to avoid them. Go's advantage over C++, and it is a > significant advantage, is that the rules for valid sharing are fairly > simple, and the language makes it much easier to do valid sharing.

How does Go simplify the rules for valid sharing? Far as I can tell it can only simplify if it renders undue aliasing undefined. Does Go have something equivalent to Java's volatile and C++0x's atomic?

> In Go it's natural to think of sending a pointer on a channel as a > transfer of ownership. That suggests a model in which the compiler > warns about cases where sending a pointer on a channel is followed by a > write through the pointer. Go's package system makes it possible to do > this reliably inter-procedurally, but of course it's possible to write > complex looping code, or code that changes behaviour based on user > input, that defies analysis.

I'm afraid things are much more complicated than just rejecting a write through the passed pointer. Interprocedural alias analysis has known and well-understood challenges. To date, no language I know relies on interprocedural alias analysis for semantic checking.

> It also suggests a "safe" compilation mode in which pointers are > annotated with ownership information. Sending a pointer on a channel > changes ownership. Writing through a pointer checks ownership. This is > problematic in that it only detects races which actually occur, not > races which could theoretically occur. > > I really don't know how feasible these ideas are.

This is well-trodden ground. The brief answer is - it is possible (by formalizing uniqueness within the language) but out the window goes simplicity.

--

Ian Lance Taylor 8/13/10 Re: [go-nuts] Re: GO Vs D Andrei Alexandrescu <iro...@gmail.com> writes:

>> I wasn't able to find the docs on the sharing qualifier (the docs >> suggest that it is called shared, but I couldn't find any docs on that >> either). Can you point me to a description of how it works? > > As I mentioned, the entire chapter on concurrency in TDPL is available > for free online: > > http://www.informit.com/articles/printerfriendly.aspx?p=1609144

Thanks. As you know, this approach is clearly different from the one in Go, which is a transfer of ownership model, where the transfer of ownership is enforced only by convention. And, of course, Go doesn't use the type system, which follows Go's general guideline of keeping the type system light weight.

>> You're quite right: Go does permit data races, and does currently rely >> only on convention to avoid them. Go's advantage over C++, and it is a >> significant advantage, is that the rules for valid sharing are fairly >> simple, and the language makes it much easier to do valid sharing. > > How does Go simplify the rules for valid sharing? Far as I can tell it > can only simplify if it renders undue aliasing undefined. Does Go have > something equivalent to Java's volatile and C++0x's atomic?

The rules for valid sharing are encapsulated in the slogan "don't communicate by sharing memory; instead, share memory by communicating." That is, always use channels to communicate between goroutines. Always ensure that a single goroutine owns shared data, and use an explicit channel send to transfer ownership to a different goroutine.

This approach can be used in other languages also, of course; the advantage I see in Go is that the language makes it simple and easy.

Ian

---

 	Ian Lance Taylor 	8/13/10 Re: [go-nuts] Re: GO Vs D Andrei Alexandrescu <iro...@gmail.com> writes:

> I understand. So what we have now is: > > (1) Pass-by-bitblt through channels for value types (i.e. no > indirections, which means dynamic arrays are unduly shared). There is > no checking that a value type being passed actually does not have > indirections. > > (2) Pass of ownership by unchecked convention for data with > indirections. > > (3) Everything else is undefined. > > If that's true, parts 1 and 2 are of limited expressiveness but it's > part 3 that's really problematic, and I'm not sure a putative > programmer understands the implications. Essentially that means even > lock-based programming relies on implementation-level vagaries because > without a memory model the compiler and the processor are relatively > free to hoist data around rather freely. We're back to the reorderings > hell often showcased as motivators of Java's and C++0x's memory > models.

Go does have a memory model: http://golang.org/doc/go_mem.html . The memory model does define mutexes. They are stylistically discouraged for use in most Go code, but they are available and well-defined when required.

Ian

Andrei Alexandrescu 8/13/10 > Go does have a memory model:http://golang.org/doc/go_mem.html. The > memory model does define mutexes. They are stylistically discouraged > for use in most Go code, but they are available and well-defined when > required.

Thanks, I'd missed that. Will take a look.

---

Jessta 8/14/10 Re: [go-nuts] Re: GO Vs D On Sun, Aug 15, 2010 at 2:54 AM, ⚛ <0xe2.0x...@gmail.com> wrote: > Imagine, you have some program that reads a configuration file when it > is started. I think you will agree with me that the program would not > start properly if in the middle of the process the file was > overwritten by some other process. It would be nice if the type system > could reject programs in which this kind of concurrent modification > *might* happen. For example, trying to compile the code > > 1 fd := open(config_file) > 2 option1 := read_int(fd, "option1") > 3 option2 := read_bool(fd, "option2") > 4 close(fd) > > would yield the following compile-time error: > > file "input", lines 1-4: You moron, you cannot do it this way because > there would be some issues related to a possible concurrent > modification of the file. Try to use function "openAndLock" instead of > "open".

Such a type system exists. http://en.wikipedia.org/wiki/Linear_type_system But any language with this type system would have to be purely functional. Which has it's own set of disadvantages.

Everything is a trade off. This kind of checking would be really nice to have, but you can't do it without complicating the language.

--