Hacker News new | past | comments | ask | show | jobs | submit login

> I havent tried go or dart yet

Well Go uses shared-memory concurrency and no other so...

Rust still looks more interesting there, though they still have to deliver the language (it's still heavily in flux)




Go allows you to share memory between goroutines (i.e. concurrent code).

It doesn't force you to do so.

In fact, the Go team explicitly tells you not to do that: "do not communicate by sharing memory; instead, share memory by communicating." (http://blog.golang.org/2010/07/share-memory-by-communicating...) i.e. they tell you to use the Erlang model.

But as everything, there are trade-offs. Even Go team uses shared memory protected by locks in some cases (see Go standard library) because it's faster or easier that way.

Every good idea (sharing memory between threads is dangerous and therefore should be avoided) taken to extreme becomes cargo cult programming.

Yes, it is dangerous, but at the same time there are plenty of successful projects that do it because there are programmers that can contain that complexity despite the somewhat popular view that this approach dooms you to failure.


An important side effect of not permitting sharing memory is that you can always recover sanely.

An Erlang process has its own heap, so when it blows up, its state just goes away, leaving your remaining program's state untouched. With Go, there is no way to recover sanely; even if your goroutines are designed to copy memory, Go itself has a single heap.

Now, this is a very odd design decision for a language that claims it's designed for reliability. Perhaps Go's authors thinks it's better just for the entire program to die if a single goroutine falls over; well, that's one way, but it's a crude one. Erlang's design is simply better.

I wonder if Go can ever adopt per-goroutine heaps, or whether it's too late at this stage. I was happy to see that Rust has chosen to follow Erlang's design by having per-task heaps, even if all the pointer mechanics (three times of pointers, ownership transfer, reference lifecycles and so forth) result in some fairly intrusive and gnarly syntax.


> Go allows you to share memory between goroutines (i.e. concurrent code).

Go will share memory, by default, and special attention must be taken preventing or avoiding it. It's not an allowance.

> In fact, the Go team explicitly tells you not to do that

And yet they have refused to implement a correct model, even though they have no problem imposing their view when it fits them (and having the interpreter get special status in breaking them, see generics).


> Go will share memory, by default, and special attention must be taken preventing or avoiding it.

Not really. If you use channels to communicate between goroutines, then the concurrency model is that of sequential processes, even if channels are implemented using shared memory under the hood.

That is, the default concurrency model militated by Go is not shared memory, but that of CSP. It's disingenuous to affix Go with the same kind of concurrency model used in C.

> And yet they have refused to implement a correct model

What is a correct model? Erlang's model isn't correct. It's just more safe.

> (and having the interpreter get special status in breaking them, see generics)

What's your point? Purity for purity's sake?


> Not really. If you use channels to communicate between goroutines, then the concurrency model is that of sequential processes

Except since Go has support for neither immutable structures not unique pointers, the objects passed through the channel can be mutable and keep being used by the sender. Go will not help you avoid this.

> That is, the default concurrency model militated by Go is not shared memory, but that of CSP. It's disingenuous to affix Go with the same kind of concurrency model used in C.

It's not, go passes mutable objects over its channel and all routines share memory, you get the exact same model by using queues in C.

> What's your point? Purity for purity's sake?

That the Go team has no issue breaking the rules they impose on others, so that point is irrelevant.


> since Go has support for neither immutable structures not unique pointers, the objects passed through the channel can be mutable and keep being used by the sender. Go will not help you avoid this.

Channels are pass-by-value. If you pass a struct, it's copied, and both sides can mutate their own copies as much as they want.

You can get still bugs if you make channels of pointers (or have pointers in your message structs etc).


> You can get still bugs if you make channels of pointers (or have pointers in your message structs etc).

Confirming that

> the objects passed through the channel can be mutable and keep being used by the sender. Go will not help you avoid this.


> Except since Go has support for neither immutable structures not unique pointers, the objects passed through the channel can be mutable and keep being used by the sender. Go will not help you avoid this.

I never claimed otherwise. But I do think you underestimate the utility of idioms.

> you get the exact same model by using queues in C.

No, you don't. C doesn't have lightweight threads, which means it can't support a useful CSP model of concurrency.

Just because Go allows shared memory doesn't mean its main concurrency model isn't CSP. Go doesn't force CSP on you, but that is nevertheless the primary concurrency model of the language.


> No, you don't. C doesn't have lightweight threads, which means it can't support a useful CSP model of concurrency.

Well there are a few libraries available for it.

And Windows C developers can make use of fibers.


>> (and having the interpreter get special status in breaking them, see generics)

>What's your point? Purity for purity's sake?

I assume the point is that the Go developers are saying "purity for thee, but not for me" (if you think generics are impure or unnecessary), or "generics for me, but not for thee", which is just annoying.


> which is just annoying

I got that. I'm asking, why?

The decision to use generics or not has nothing to do with purity. It's about trade offs. If a decent balance can be struck with special privileged functions built into the language, I don't see how that is intrinsically bad.


It's not a decision about whether or not to use generics, it's a decision about whether or not to make it possible to use generics.

The developers have decided that they should make it possible for themselves to use generics, but impossible for you to use generics. Do you really not see why that's annoying? That's not a matter of tradeoffs, because they've already made generics possible---for themselves. At best they might be thinking something like "only WE are capable of grokking when generics are appropriate; everyone else would abuse them", which is rather arrogant, no? Lots of people have been saying that go is "missing" generics. The official response seems to be "no it isn't, you don't really need them." The unoffical response (evidenced by the use of generics in the compiler) is apparently "you're right, go is missing generics, so we'll include them, but just for ourselves".


> It's not a decision about whether or not to use generics, it's a decision about whether or not to make it possible to use generics.

Fine. That's what I meant.

> Do you really not see why that's annoying?

I can if you believe in purity over all else.

> That's not a matter of tradeoffs, because they've already made generics possible---for themselves.

Sorry, but what? Are you really trying to claim that adding generics for the entire language has exactly the same trade offs as adding a few built in functions that are generic?

> At best they might be thinking something like "only WE are capable of grokking when generics are appropriate; everyone else would abuse them", which is rather arrogant, no?

I think you've significantly misunderstood the issue. I believe my initial characterization is right: you think this is about purity. It's not.

Please read Russ Cox's short blurb on the "Generic Dilemma." [1] No part of it has anything to do with "we know better than you."

> The official response seems to be "no it isn't, you don't really need them."

No. The official response is "we don't know of an implementation that we're happy with." It's not a philosophical stance. It's a practical stance.

[1] - http://research.swtch.com/generic


Honestly, I don't know what you even mean by purity.


The context of this discussion started when people were complaining about the language designers being able to build in special functions that are type parametric. The implication was: if the language designers can do it, why won't they allow me to do it?

i.e., purity for purity's sake. It ignores legitimate trade offs between allowing a few special functions and building an entire generics system into the language.


I still don't know what you mean by "purity". Saying "i.e., purity" doesn't help, since I already knew that you think purity has something to do with generics being definable by people other than the language designers.

"If the language designers find it useful to occasionally use type-parametric functions, why won't they recognize that other people might also find it useful, too, and for other functions?" doesn't strike me as a demand for purity in any sense. Consistency, maybe; recognition that the designers are giving themselves special treatment, sure. What's pure about the desired state of affairs, or impure about the present?

Honestly, sometimes it seems as if someone who wants to defend Go against a criticism immediately claims that the critic is just obsessed with purity. Why else would you criticize Go?


This was the original comment that I responded to:

> and having the interpreter get special status in breaking them, see generics

It's a whine that the interpreter gets "special status." It's implicit in the complaint that special status is somehow bad. It ignores any trade offs that go into the design decision.

Purity in this context means: the language gets no extra special power that users of the language can't tap into themselves.

> Honestly, sometimes it seems as if someone who wants to defend Go against a criticism immediately claims that the critic is just obsessed with purity.

And sometimes it seems as if someone criticizes Go just because they are obsessed with stuffing as many features as possible into a programming language. Shit happens.


>What's your point? Purity for purity's sake?

If go couldn't even implement its own interpreter in vanilla go, that's a sign that it's going to be a bad language.


Is it that they couldn't or haven't? It's obviously capable of compiling code, but with the state of compilers today (impressive backends, etc.) does it make sense to have a three-stage bootstrap (minimal C → mini-go → full-go → optimized-full-go) at this point?


It would be nice if Go provided for immutable variables.


for i:= range list { go func() { foo(i) } }

(This is a bug in the spec, but will not be fixed before Go 2 because Go 1.0 is frozen.)

Shared memory by default.


You've completely missed my point. I wasn't claiming that Go did anything to stop you from sharing memory. I was claiming that its concurrency model is CSP, not shared memory.

> (This is a bug in the spec, but will not be fixed before Go 2 because Go 1.0 is frozen.)

Could you kindly link me, please?


In fact, the Go team explicitly tells you not to do that: "do not communicate by sharing memory; instead, share memory by communicating."

Sadly, that doesn't mean what you think it means. It really means: don't organize your IPC around shared state. The juxtaposition in the second half is not directly related to the first half (except poetically), though it does do a good job of completing the their picture of CSP. Also note: it is explicitly talking about shared (sadly mutable) state.

You can always opt not to share memory, but there's no facility to prove or enforce it. It's not dire, with practice you can send values, or never mutate referenced objects. It is very natural for the most part. I've done it, but not in Go.

Finally, it's not doom. Even C can do threading after all, and somehow these things don't blow up too much. But there's value in eliminating the pitfall entirely. When people criticize Go for being imperfect, they're not saying it's not going to work, they're contrasting with a more effective solution or lamenting that some design decisions weakened the effort.


I guess the Go authors decided that for the sake of performance, you have to risk hurting your foot at least a little bit?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: