Well, I want Go to have refcounting instead of current GC, so my programs could guaranty latency. Single-threaded runtime, without all the locks, slow channels, races and so on, because there is no point in so much overhead and complexity for the majority of programs. More consistency couldn't hurt, so I wouldn't have to assign anonymous function to a variable just to return it. Fast regular expressions compiled by the language compiler into a native code could improve matching, parsing and validating consistency, instead of writing lots of loops everywhere. Compiler warnings instead of errors on unused variables, imports, etc. to allow faster prototyping. Better testing culture with meaningful test names and line numbers with actual failed tests. Table testing suggested by Golang team doesn't even support that with the means of standard library, you have to use your own runtime.Caller(1) wrapper.
But generics? "Safer" type system? No, that's unnecessary complexity. As others pointed out, we already have Haskell and Rust for all those things.
You don't like locks, but you want refcounting that requires a large number of atomic ops for acquire/release semantics and thus scales like crap? Ah, you really mean, single threaded as in no other threads? Well... ok. But that'd make Golang a lot less useful.
For compiled regular expressions: just use PCRE library for compiled regular expressions. I bet there's already some library that does it for you.
Maybe you should take a look at Lua and especially LuaJIT [1]. You might like it. Lua(JIT) is single threaded, but provides co-routines [2] as a language construct. Performance is about same as Golang, sometimes faster, sometimes a bit slower. Lua has GC, but you can control latency by controlled GC invocations. It can be made pretty predictable, a lot of current AAA games use Lua internally.
LuaJIT's FFI [3] is excellent, calling native C libraries is a breeze, very easy and requires no bridge libraries or code.
Mmmm. Threads + mutable data. What a disaster this industry has unleashed upon itself. Blech.
I think that threads are easily up there with null/nil as one of the worst CS mistakes. Communicating via shared variables at the application program level, vs an IPC function / channel, seems like a noose that should be designed away from reach.
Refcounting and a single threaded runtime, instead of GC and a multithreaded one.
By compiled regexpes, I meant replacing things like bytes.Equal(foo, "qwe") with things like foo.m(`^qwe$`) or even foo.m/^qwe$/ that have the same performance. All the loops that scan through slices could benefit from it, golang has a lot of them. Plus more overall matching/scanning consistency, that should lead to fewer mistakes.
Well, if you're happy to run them only over byte arrays, then you should be able to use PCRE and satisfy your performance requirements. Your regular expressions will get compiled into native code at runtime.
Unused import cleanup has been a standard part of all the major Java IDEs for quite some time. Further, checkstyle and other static analysis tools can easily replicate the check.
The majority of the programs do not really need to guarantee latency.
That being said, it is well known that Golang's present GC performs poorly. It presently fails to free memory in certain cases, and has pretty high overhead. There is work done on improving the GC to be fully concurrent, but that is still probably still 2-3 major versions away.
The concurrent GC is planned for version 1.5 and is only 6 months away. There is also work being done on a compacting GC, but I don't know when that is supposed to land.
Actually, the Go team is making very good progress on all the prerequisites to real-time garbage collection. Who knows if they will manage to get all the way there, but I know there's been some discussion about it on the mailing list.
If you look at how fast the GC has improved over the years, it's kind of ridiculous that anyone bothered to criticize it at all, as if it was not really the temporary solution the devs said it was, and was in fact going to stay shitty forever.
Where does it fail to free memory? As of 1.4 the GC is fully precise. Concurrent GC is in the works, and is scheduled to be in 1.5 (August of this year).
For one, it fails to handle memory fragmentation. The effect is that your application seems to grow and grow. It is not very common to cause real problems, but compression is something JVMs learned a long time ago. There are also afaik a few corner cases with stack, I've seen a few discussions about those on Stackoverflow lately.
I'm not sure if this is sarcasm or not, but I will assume not. If they made the changes you suggest golang would be come useless to me. That isn't to say what you want isn't valid, only that it gets to the heart of all these arguments. Every design decision comes with trade offs and you can't please everyone.
No, it's not a sarcasm, but I didn't mean they need to replace those things, runtime and GC could be a choice, or it could be a completely different golang compiler. I've been itching to write one myself.
"real-time guarantees" is not a particularly useful requirement as you can just set the minimum time very high to accomplish it. Real-time and low latency on the other hand would be a game changer, and I have pretty serious doubts about their ability to accomplish this.
I consider 10ms pauses to fall into the "set the minimum time very high" branch of my statement. That is, if you can handle pauses of that magnitude there are already lots of GC options for you and golang is not adding much (that said 10 ms pause guarantees are much better than the current so more power to them).
Even 1ms pause ceilings drive people to non-GC options, so I think the "game changer" number is much lower than that.
Think of a computer game. 60 FPS. So 16 ms time per frame. Assume you're running comfortably within 14 ms per frame, so you get nice and smooth 60 FPS. A 10 ms GC here means you'll definitely miss at least 1 frame, a good chance you'll miss more, because the simulation code (or something else that needs to run whether or not a frame was on time) will need to catch up.
For interactive desktop applications, the pause should be adjustable or at most a few milliseconds. Say, maximum 5 ms.
For hardware devices... well, you just don't use GC there in the first place. Microsecond is a pretty long time in that area.
But generics? "Safer" type system? No, that's unnecessary complexity. As others pointed out, we already have Haskell and Rust for all those things.