As a veteran Java programmer, I like that Go is a handicapped Java. Please force all of my coworkers to use delegation rather than implementation inheritance and make CSP-style concurrency easier to code than synchronized-style.
In that case, wouldn't you also want a more thorough and thought-out solution to concurrency like Erlang and Clojure offer? And if you prefer the familiarity of a C-like syntax, Kotlin is just what you're looking for. It won't force you to use delegation, but Go also leaves the door open for a a whole class of problems (especially concerning concurrency).
Communicating sequential processes is pretty thought out, I haven't used much Erlang but I was under the impression it uses a similar model to go (green threads, message passing between them).
Can you explain what you mean by 'more thought out'? If you're talking about STM or pmap and friends, then I'm very, very unimpressed by them (see Amdahl's law for why). I can do shit really slowly in one thread just fine.
Then why not both CSP and immutability? You can't really have serious concurrency without giving serious thought to managing state.
Erlang is really all about managing, and isolating, state. Clojure, too, has great support for CSP (with care for state) in core.async[1] and Pulsar[2].
Immutability's great, I pass around Callables of final variables in Java all the time to accomplish CSP and immutability.
That's not to say you can only have immutability, though, we're humans here and capable of reasoning about happens-before relationships. I wouldn't implement a parallel linear algebra library, for example, that didn't use mutable just-plain-arrays of floating point values..
Clojure doesn't 'just' (I don't know how to do italics) have immutability. It has really good reference types for managing mutable state when you need it, as well as easy interop to just use plain arrays if you need them. Immutability is strongly encouraged, but mostly at the interface level. If a function is referentially transparent, most people don't mind if it's internally bashing on a mutable array.
It's great to have the vast majority of your stuff be immutable and have it clear when you're using mutation. I think avoiding mutable state is more important for maitenance than dynamic vs static typing personally (though I'm recently becoming more interested in static typing).
Yeah, I read the clojure book back in like 2009 and used it a little. I thought it had a lot of neat ideas but when it comes to just getting a job done, if it's not a problem where pure functional programming brings a lot of value (things that really benefit from code-as-data), I'd rather just write boring old procedural code. Easier to read, easier to reason about.
I strongly disagree with procedural code being easier to read and particularly easier to reason about. I haven't run into many (any) problems in the last few years that I thought functional programming didn't bring a lot of value. The code-as-data is kind of an orthogonal issue, most functional languages aren't homoiconic.
Code-as-data is actually a win that you can't get from procedural languages, which is why I brought it up. It makes solutions to complex configuration spaces possible that aren't even conceivable in procedural languages. Everything else is just syntax.