
Go 2, here we come - mdelias
https://blog.golang.org/go2-here-we-come
======
joppy
I’m hoping that
[https://github.com/golang/go/issues/19623](https://github.com/golang/go/issues/19623)
will come through, and we’ll get a native “true integer” type (and hopefully a
rational one as well, though maybe this is pushing it a bit). This is really
something that should be implemented at the language level, so that “int” can
become a true integer, yet still remain efficient in many cases.

It is bizarre to me that languages boasting built-in language-level data
structures like lists, hashtables, etc are content to just leave us with the
bare minimum support of _numbers_ , being basically whatever the hardware
thinks a number is. The semantics of integers and fractions are perfect, and
everybody already knows them. On the other hand, overflows in int32’s are
weird, and if your idea of a fraction is a floating-point number, then you can
never have something like (5/3)*6 evaluate to 10 exactly.

To be clear, I think fixed-width integers and floating-point numbers have
their place, I just see no reason why they should be the default.

~~~
tigershark
I am misunderstanding or really go is using the ‘int’ type that can be 32 or
64 bit depending on the system that it runs on??? If this is the case I think
that is crazy and I can’t think of any useful use case for it. If it’s not the
case then please explain me what that proposal is really about...

~~~
Sharlin
It may be crazy but it's not exactly without precedent. Neither C nor C++ fix
the sizes of the fundamental integer types, although for backward-
compatibility reasons popular 64-bit platforms still have 32-bit `int` and
even `long`. But yeah, there's a reason eg. Rust has no `int` and friends but
`i32` etc. instead.

~~~
user5994461
C only defines char, short, int has having a minimum size of 8, 16 and 32
bits.

~~~
mrb
Actually C defines the minimum size of "int" as 16 bits, because it defines
the minimum range it should support as [-32768 .. 32767]

See
[https://en.wikipedia.org/wiki/C_data_types](https://en.wikipedia.org/wiki/C_data_types)

~~~
shric
Nit: [-32767 .. 32767] C permits ones' complement and sign-and-magnitude as
well as two's complement.

------
glangdale
I'm pretty excited by the idea of Go getting generics. This has always been my
deal-breaker issue with Go and I'm glad that what appeared to be a
disingenuous "let's pretend to be hunting for the truth until people go away"
stance was actually really a hunt for the truth! Goes to show that you
shouldn't make snarky snap judgments.

As for all the folks claiming they'll leave Go if it gets generics, it's
faintly reminiscent of Mac fanboys claiming PowerPC chips were the Very Best
right up until this was obviously not true. C++ generics are a PITA in many
ways, but you can be insanely productive in the STL without having to hand-
roll everything and with good type safety.

Despite the pain, I've been amazed at how easily you can build up some really
complex data structures as pretty much one-liners ("Oh, I need a vector of
maps from a pair of Foo to a set of Bar") that would either take a
preposterous amount of code (or be a type-unsafe disaster waiting to happen)
without generics.

Hopefully the final Go 2 generics proposal will capture some of this goodness
without some of the horrifying C++ issues (error messages, bloat, sheer brain-
numbing complexity).

~~~
ryeguy
I really don't get the people opposed to generics. Is there actually a cross
between experienced developers who have come from languages that have generics
and understand them, yet don't want them in go? If so, why, and what do they
use instead? Because go has no compromise-free answer for generics. You either
lose type safety, maintainability, or performance.

I suspect a lot of the generics hate is due to a large chunk of the community
coming from dynamically typed languages. In which case they're just have a
negative reaction to unfamiliarity.

~~~
IshKebab
It's people that have seen the abuses of C++ templates. They're very powerful
and therefore people tend to want to use them for really complicated things.

Look up things like SFINAE and compile time metaprogramming. Templates were
not intended for those things. When they work they're ok, but if they go wrong
good luck following the 10 line error message.

Here's an example from Rust:

[https://www.reddit.com/r/rust/comments/5nifpm/they_said_rust...](https://www.reddit.com/r/rust/comments/5nifpm/they_said_rust_error_messages_with_generics_are/)

That's what people don't want.

~~~
johncolanduoni
That's not compile time metaprogramming at all, it's just series of wrapped
closures. It's basically the sequence of function call names preceding that
call backwards, with different capitalization.

------
Waterluvian
As a newcomer to Go, by an immensely wide margin, the hardest, most
frustrating thing, which soured the language for me, is whatever the heck
package management is in Go.

There's like three or four different angles, all of which overlap. Some are
official. Some aren't. The unofficial ones seem more popular. They're all kind
of incomplete in different ways. And it was all such a frustrating migraine to
try and figure out. I haven't felt so viscerally aggressive about software
like that whole experience made me feel in a long time.

I hope Go2 makes something concrete from the start and sticks with it, for
better or worse.

~~~
SwellJoe
I just started learning Rust for a small project, and I found its "one clear
path" model very appealing (I don't know if it is a formal goal, or if it's
just a happy accident based on a smaller, more focused, community). It doesn't
just apply to the package manager, but that's one of the first bits a beginner
sees. Rust has a single, easy-to-find, "pretty good" answer for nearly every
question a beginner asks, at least, it has, so far, for me. Cargo is that
answer for packages and for building, and it's pretty good, and there's no
debate about how to install or build Rust tools and libraries.

I didn't really find that to be the case with Go, so even though Go is a
simpler language, I have been more productive, much more quickly, in Rust.
Within a couple of hours of starting my project (with only a cursory glance
over the docs and tutorial) I had my project daemonized, had options parsing
working, had system calls working, got logging working, etc. It was shocking
how quickly I was up and running.

I'd been hesitant to try Rust, because it looks _big_ , and I'm kinda tired of
big languages. I just don't have enough time/motivation to study a bunch of
nuanced syntax and such; I'll never be a great C++ programmer, though I can
muddle through and usually understand other people's C++ code. But, so far,
Rust is proving to be one of the easier languages I've learned lately, partly
due to the holy path being well-defined, and partly due to strong libraries
that overlap my particular project perfectly (being a systems language built
by very smart people, it has some very good systems libraries).

I don't mean to imply Go is a hard language, it's not. I picked it up pretty
quickly, too. Both are easier to learn than, say, JavaScript, because they're
much smaller. But, I agree that there isn't a super clear path forward for a
beginner with Go, including with installing and building. You just have to
acquire more tribal knowledge to work in Go than in some other languages (but,
much less than many others...older languages tend to have tons of that kind of
thing).

~~~
bulldoa
As a beginner, I really like rust.

It has excellent package management, robust compiler messages, pattern
matching... etc. But once I start trying to build non trivial data structures
it becomes a nightmare. For example, doubly linked list, any sort of graph is
extremely hard for me to build in rust but extremely easy to build in golang.

I am still learning the full capability of rust, hopefully as I do more
practice it gets easier. In the worst case I think I would still use it to
build data pipelines since I really enjoyed the syntax and the safety check as
long as I don't get into smart pointers or raw pointers.

Also another annoying point is that some libraries use nightly.

~~~
amelius
You're not the only one having trouble writing basic data structures in safe
Rust: [1]

[1] [https://rcoh.me/posts/rust-linked-list-basically-
impossible/](https://rcoh.me/posts/rust-linked-list-basically-impossible/)

~~~
int_19h
Of course, if you're comparing with Go, you need to compare apples to apples -
since Go doesn't have ownership tracking, the equivalent Rust would
necessarily have to be unsafe.

~~~
amelius
Yeah but Go has garbage collection. Rust's ownership model makes up for not
having GC.

~~~
int_19h
I think that heap-allocating everything and using Rc<T> and Weak<T> would be a
closer comparison to what Go does, than using idiomatic Rust with borrow-
checked locals etc.

------
asien
I tried Go a while ago. I was hooked by the performance , the community around
it and vendors support ( AWS , Heroku , GCloud etc...) but I got quickly fed
up by the awkward package management system, the weird syntax and the horrible
idea of $GOPATH, especially on Windows.

Haven’t tried it since.

Hope lots of this change to make the language more welcoming for Newcomers to
the language.

~~~
simfoo
Same here. For me it was primarily the syntax. So many people think that
syntax is something you get used to, but I don't. Syntax matters a lot for me,
and the way Go does it just isn't compatible with my brain.

Regular grammars are great for parsers. But really, having an easy to read
(conceptually!) language is way more important imho.

But call me crazy when I say that I like C++ and can read it effortlessly :)

~~~
elcomet
Well of course you get used to it, like you did get used to C++ (unless you
were born that way which I doubt).

It just takes time, you don't want to spend that time getting used to Go and
that's perfectly understandable.

~~~
PavlovsCat
I can get used to something and still dislike it.. with Go it's mostly the
bracket style, or put differently, the inability to turn off automatic
addition of semicolons before parsing. I'd actually rather "have to" put
semicolons manually, but no, I have to suffer so others don't have to put an
additional line into their style guide.

~~~
elcomet
Yeah I completely agree. Though I think when you really get used to a language
and understand it deeper, you tend to understand the trade-offs that were
made, if the language is well designed. Then you can still think that the
trade-off don't match your requirements.

------
ilovecaching
Well I must say the Go team is certainly putting in the work to avoid a
catastrophic major version bump (e.g. Python).

That said, any major additive change to Go, especially generics and/or
try/catch will push me away from the language. If I need a well designed
language, I have Rust. Go's sell for me is it's so naively simplistic it's
actually useful when your team members are idiots.

If they bolt on type variables, well that's just a different language, and
we'll just end up on the hedonistic treadmill towards another Java. No thank
you.

~~~
bdamm
Isn't the premise of Go that a team sufficiently large enough will eventually
act as a collective idiot in terms of code maintenance? I'm looking forward to
some real research on the question of whether Go's design choices have had
real world results in improving productivity with supersize code bases.

~~~
EricBurnett
(Disclaimer: at Google)

My team has ~200k lines of Go code and I'm exceedingly happy with the state of
the codebase. Having previously maintained a C++ codebase of similar size, I
can say that the pace of changes is higher, the effort necessary for large
scale refactorings is lower, and our ability to reason about the system is
similar.

A few examples:

\- Refactorings are simpler due to the use of consumer-side interfaces. Say
you want to inject an in-memory cache above a backing store. To do that you
probably have to change the constructor and provide an implementation matching
the 2-4 relevant methods. That's it.

\- Tracing code is slightly worse, due to having to track callers through said
duck-typed interfaces, but on the flip side multi-threaded code is
sufficiently simpler to reason about that I call it a wash. Having previously
had to do threading in the form of "control flow" state machines, and then
fibers (which were better but not perfect, and still aren't widely available),
Go constructs are great. Locks where appropriate, channels where appropriate,
overall very fast and clean code.

\- Performance is good, and reliable. Not as good by cycle-count as C++ - and
e.g. the comparable RPC libraries are definitely less mature than Google's
very-well-kicked C++ libraries - but on the other hand it scales almost
linearly. We started a system at ~5 cores/task under AutoPilot, and then when
we next got around to adding more tasks it was peaking at ~60 cores/task at
essentially the same per-core throughput. I've never managed to write a C++
server that can accidentally scale concurrency by >10x without hitting _some_
bottleneck.

\- We use Go for ~everything. Server code, definitely Go. Client tools, also
Go. Simple scripts, bash until they need their first 'if' or flag or loop,
then Go too.

\- I'd prefer real generics to interface{}, but the number of places it comes
up is minimal enough that it's no more than a minor annoyance.

I can't speak to the issues of package management - we dropped compatibility
with Go's native package structure fairly early on and went all in with
blaze/Bazel ([http://bazel.io](http://bazel.io)) to coordinate builds and
dependencies and whatnot, and haven't had reason to try modules yet.

~~~
jniedrauer
> Simple scripts, bash until they need their first 'if' or flag or loop, then
> Go too.

If you don't mind, can you give a little insight on what this looks like in
practice? I'm not sure how to use a compiled language as a script. I've played
with executing go as a script using a shebang hack, but I somehow don't think
this is how others are doing it.

For reference, the shebang hack I was using looked like this:

    
    
        //usr/bin/env go run $0 $@; exit $?
        package main
    
        import "fmt"
    
        func main() {
            fmt.Println("i am a script")
        }

~~~
EricBurnett
It looks more like Go code than a bash script - the tradeoff we settled on is
that pretty much as soon as you need to add any sort of logic it's no longer
really a simple "script" and you _know_ it's just going to grow into a
monstrosity. Better to use a language with real functions, real error
handling, that you can actually unit test, etc. In that sense, I guess you
could say we write lots of little tools moreso than we write scripts.

For something of this form, if the standard library has the functionality, we
us it - os.Mkdir() instead of `mkdir` and so on. But to simplify shelling out,
we have a little library that includes the interface

    
    
      type Runner interface {
    	Execute(dir, name string, args ...string) (*CmdOutput, error)
      }
    

so it's easy enough to call miscellaneous programs and get the exit code /
stdout / stderr. It also supports printing and executing a command, etc.

Iteratively executing a program of this form looks like `go run whatever
--flag=value`, though your shebang hack looks like it'd also do nicely.

------
infogulch
I really really hope Go 2 can do something about `context`. Context is the
biggest hidden wart of Go. We need the capabilities of context in different
packaging.

~~~
atombender
This doesn't seem to be a popular opinion, but I agree. It's such a pervasive
functionality in concurrent programs that it really should be a built-in
aspect of a goroutine.

The problem with context isn't necessarily the interface, it is that it is
"viral". If you need context somewhere along a call chain, it infects more
than just the place you need it — you almost always have to add it upwards (so
the needed site gets the right context) _and_ downwards (if you want to
support cancellation/timeout, which is usually the point of introducing a
context).

Context's virality also applies to backwards compatibility. There have been
discussions of adding context to io.Reader and io.Writer, for example, but
there's no elegant way to retrofit them without creating new interfaces that
support a context argument. This problem applies to _any_ API; you may not
expect your API to require a context today, but it might need one tomorrow,
which would require a breaking API change. Given that it's impossible to
predict, you might want to pre-emptively add context as an argument to all
public APIs, just to be safe. Not good design.

Cancellation/timeout is arguably so core to the language that it should be an
implicit part of the runtime, just like goroutines are. It would be trivial
for the runtime to associate a context with a goroutine, and have functions
for getting the "current" context at any given time. (Erlang got this right,
by allowing processes to be outright killed, but it's probably too late to
redesign Go to allow that.)

(I'm ignoring the key/value system that comes with the Context interface,
because I think it's less core. It certainly seems less used than the other
mechanisms. For example, Kubernetes, one of the largest Go codebases, doesn't
use it.)

~~~
nathanaldensr
Forgive me since I've never used Go, but this sounds similar to having to add
the async keyword to methods in C# all the way up the stack once you attempt
to use an async method, as well as having to pass CancellationTokens down the
stack to support cancellation. I've noticed it pollutes code with a lot of
ceremony that I wish had been added to the runtime itself. Is this what you're
talking about?

~~~
atombender
Absolutely. Contexts are similar to your CancellationToken; a context contains
a channel you can listen to, just like CancellationToken's WaitHandle. They're
slightly simpler in that I believe CancellationToken supports registering
callbacks, which contexts don't.

Go doesn't actually have async support in the sense of promises/futures (as
seen in C#, JavaScript, Rust, etc.). The entire language is built around the
idea that I/O is synchronous, and concurrency is achieved by spawning more
goroutines. So if you have two things that you want to run simultaneously, you
spawn two goroutines and wait for them. (Internally, the Go runtime uses
asynchronous I/O to achieve concurrency.)

~~~
Groxx
> _Go doesn 't actually have async support_

I usually phrase this part of Go as: no async/await, it only has threads. But
no thread handles. Everything is potentially parallel under the hood and all
coordination requires external constructs like WaitGroups / chans / etc.

async/await has major complications like changing call syntax through the
whole chain, so I actually prefer it this way. the lack of thread handle
objects (e.g. a return value from `go func()`) is strange IMO tho.

~~~
int_19h
The main advantage of the async/await model is that it's just syntactic sugar
on top of CPS, so you can bolt it onto any language that is capable of
handling callbacks (even C!). For a good example of that, consider WinRT - you
can write an async method there in C#, the task that it returns can pass
through a bunch of C++ frames, and land up in JS code that can then await it -
and all that is handled via a common ABI that is ultimately defined in C
terms.

Conversely, goroutines require Go stack to be rather different from native
stack, which complicates FFI.

~~~
Groxx
it's true that it's "just syntactic sugar", but in _most_ languages it has
call-site contracts that are either part of the signature (`await x()` to
unpack the future/coroutine) or implicit (`x()` in an event loop host). and to
change something deep in the stack means changing every call site everywhere.

that's a _huge_ burden on a library (and thus the entire language ecosystem).
it splits the world.

to avoid that, you basically need language-level support, so everything is
awaitable... at which point you're at the same place as threads (but now
they're green), where you cannot know if your callees change their behavior.
which is both a blessing and a curse.

\---

tl;dr yes but no. do you want your callee's parallelism to be invisible? you
can't have both. (afaik. I'd love to see a counter-example if you know of one.
there was one very-special-case language that made parallelism a thing _you
did to code_ rather than the code doing, but I can't find it at the moment. it
only worked on image convolutions at the time.)

~~~
int_19h
Right. You can have callee's parallelism be invisible - but only by adding it
to your _language_ (can't be done as a library) and making it be similarly
invisibly parallel. And even that only works so long as everybody adopts the
same system - goroutines don't play well with Ruby fibers, for example.

With the async/await model, you can immediately use it with any language that
has callbacks, and then the languages can gradually add async/await on their
own schedules.

I would dare say that the async/await model has proven far more successful in
practice. It came to the table later than green threads etc (if you consider
syntactic sugar a part of it - CPS itself was around for much longer, of
course). And yet it was picked up surprisingly fast - and I think the way in
which you can bolt it onto the existing language is precisely why. Conversely,
every language and VM that has some form of green threads, seems to insist on
doing their own that aren't compatible with anything else out there - and then
you get insular ecosystems and FFI hell.

Maybe if some OS offered green threads as a primitive, it would have been
different. But then again, Win32 has had fibers since mid-90s, and nobody
picked that up.

~~~
Groxx
thread interop may be a major contributor to "far more successful in
practice", because yea - I agree, it's far more common. I don't know that side
of things all that well :|

having spent a fairly significant amount of time in an event-loop system with
async/await tho (python coroutines): I don't know if that's a good thing.
getting your head around "thou must never block the event loop, lest ye
unceremoniously bring the system to its knees" / never using locks / never
confusing your loops / etc requires both significant education and and
significant care, and when you get it wrong or performance degrades it can be
_truly horrific_ to debug.[1] it's nice that it tends to have fewer data races
though.

green thread systems though are trivial - your stack looks normal, your
tracing tools look normal, your strategies are basically identical (since they
tend to context switch at relatively fine-grained points, so your only real
concern is heavy func-call-less computation, which is very rare and easily
identified). since I don't have to deal with thread interop[2] I'll take that
_every single time_ over async/await.

\---

[1] I've helped teams which had already spent weeks or _months_ failing to
make progress, only to discover what would be an obvious "oops" or compile-
time error elsewhere. some languages do this much better, from what I've seen,
but CPS javascript and python coroutines and other ones I've used have been
awful experiences. basically, again, language-level support is needed, so I
broadly still disagree on "just syntactic sugar" for it to be even remotely
acceptable.

[2] ....though cgo has been a nightmare. nearly everyone uses it wrong. so I
100% believe that I could switch sides on this in time :)

------
wpietri
I really like the humility in this part of the statement:

> After almost 10 years of exposure, we have learned a lot about the language
> and libraries that we didn’t know in the beginning, and that was only
> possible through feedback from the Go community.

It's so tempting to hold one's project back until it seems perfect. And then,
even worse, to defend it as perfect in the face of real-world feedback. I
really appreciate it when smart people do their best, but in full recognition
that a lot of things will be learned once real use happens.

------
twoodfin
Rob Pike had a good talk on the Go 2 process and a few of the proposals that
went up on YouTube a few days ago:

[https://youtu.be/RIvL2ONhFBI](https://youtu.be/RIvL2ONhFBI)

------
jonathanstrange
I hope they keep the changes reasonable and do not introduce any breaking
changes. I like the language as it is now and I'm very productive in it.

~~~
jsmith45
Well for the first round they are looking at: 1\. Allowing generalized unicode
identifiers. That is hardly likely to break anything except possibly some
crazy edge cases that dont happen in real code. 2\. Binary integer literals.
(unlikely to break things) 3\. allowing seperating groups of digits in a
number with _ like 1_000_000 (unlikely to break anything) 4\. Permit signed
integers as shift counts (no need to cast ant int to a uint to use it in a
shift expression. This won't break any existing code).

So at least this first round is quite unlikely to break anything in real use.

~~~
bryanlarsen
For the first round they are testing the GO 2 selection process by applying it
to proposed changes for 1.13, which limits it to non-breaking proposals. It
won't get interesting until they start selecting breaking proposals.

~~~
stcredzero
_It won 't get interesting until they start selecting breaking proposals._

From what I see in the past couple of decades in popular languages, is there
really a justification for breaking changes, from the POV of project
maintainers?

~~~
copperx
That's a good question because they ostensibly do it to get more users aboard,
but in most cases, the result is the opposite (e.g., the Python 2/3 disaster).

~~~
hhmc
C++11 introduced breaking changes
([https://stackoverflow.com/questions/6399615/what-breaking-
ch...](https://stackoverflow.com/questions/6399615/what-breaking-changes-are-
introduced-in-c11)) but is widely regarded as a boon to the language.

~~~
stcredzero
Yes, but in large part, those changes were quite obscure, in comparison to
things like how to define classes.

------
nickcw
I've been reading this proposal

> #19113 Permit signed integers as shift counts: An estimated 38% of all non-
> constant shifts require an (artificial) uint conversion (see the issue for a
> more detailed break-down). This proposal will clean up a lot of code, get
> shift expressions better in sync with index expressions and the built-in
> functions cap and len. It will mostly have a positive impact on code. The
> implementation is well understood.

The proposal as far as I can make out says allow signed integers for shifts
but panic if they are negative.

This seems like a step backwards to me pushing checking which the compiler
made you do to runtime.

Personally I'd expect a negative shift to shift the other way, but that
doesn't seem to be a popular option with the team.

~~~
infogulch
> This seems like a step backwards to me pushing checking which the compiler
> made you do to runtime.

No that means this operation is currently _unchecked_ by the compiler:
[https://play.golang.org/p/nJmaEOkObk1](https://play.golang.org/p/nJmaEOkObk1)

------
icholy
> Go 2 will be much more community-driven.

Please no ...

~~~
bsaul
There must be some very angry people downvoting on this comment section today.
Go is very opinionated and it's quite obvious that its original design being
so radical (no class, no inheritance, no generics, no macro) was only possible
because it was designed by a few very experimented people with a very specific
goal in mind.

I'm also worried about how being "community driven" will change the philosophy
of the language.

~~~
AnimalMuppet
I think "community driven" means less than you fear. I think it means that
community feedback is used to push the language in directions that scratch
some of the major community itches. That seems perfectly reasonable to me -
more reasonable than making changes in a vacuum, in fact.

But I don't think that they're going to let the community run wild and
completely change the character of Go. I think they're looking for wins that
matter to users, but wins that are possible within the framework of what Go
is.

~~~
icholy
I hope you're right

------
curiousDog
I haven't been keeping up with Go much these days but is there proper debugger
support now? Or is it still a half-broken experience?

~~~
org3432
If you use Goland 2018 it's pretty seamless, there are a few things missing
like being able to get ptr addresses and view values in hex, and it's a little
laggy compared to VS but not bad.

~~~
copperx
Is Goland's debugger written by Jetbrains?

~~~
org3432
Yes, it uses delve under the hood and acts much the same way as VS.

------
rqs
One question: As far as my knowledge told me, anything (or most?) interface{}
in Go will be put to heap instead of stack. Will generics change that?

I really want to utilize those 2~4K stack spaces for the routines.

------
dunpeal
> We are constrained by the fact that we now have millions of Go programmers
> and a large body of Go code

Are there really "millions" (plural) of Go programmers?

Sounds like a bit of an overestimate, no?

~~~
DougBTX
Vague estimate is that there are 18 million programmers in the world[1] and
that 4% of them use Go[2], so 0.7 million would be a starting point guess as
the total number.

Note that these were the first two Google search results I found for "number
of programmers in the world" and "percentage of programmers in different
languages" so... being off by a factor of 10 or more is likely.

[1] [https://www.computerworld.com/article/2483690/it-
careers/ind...](https://www.computerworld.com/article/2483690/it-
careers/india-to-overtake-u-s--on-number-of-developers-by-2017.html) [2]
[https://www.statista.com/statistics/793628/worldwide-
develop...](https://www.statista.com/statistics/793628/worldwide-developer-
survey-most-used-languages/)

~~~
dunpeal
These numbers seem pretty accurate, and I wouldn't expect that they're off by
anywhere like a factor of 10.

Think about it: the number of programmers in the world is certainly not off by
10 factor - no way there are 180 million programmers in the world, only 18 of
which are visible.

Similarly, there's no way that 43% of programmers in the world are Go
programmers, that's again quite clearly off.

I think an estimate of 700k Go programmers makes a lot of sense, maybe with a
factor of x2. I would very strongly doubt that there are more than 2 million
Go programmers in the world.

~~~
dvlsg
Kind of depends on how "go programmer" is defined, too. I've used go, but I
certainly wouldn't call myself a "go programmer" at this point.

~~~
dunpeal
For the their purposes, the people who would care are those who are currently
maintaining a significant Go codebase.

So even if you did Go full-time for 5 years, but then switched to Rust and now
work full-time in Rust, you would not mind at all if the language added some
backward-incompatible changes.

In fact you'd probably welcome them, since often you moved away because of
features the language was missing.

------
systemBuilder
When I was young I thought Dijkstra published a paper called, "go2's
considered harmful!'. I think the next version of Go should be Go3.

------
ThorinJacobs
I know the comments aren't meant for silly jokes but I'm very disappointed
that there's no "Go 2 Considered Harmful" jokes here

~~~
idle_zealot
There's this[0] one from 10 hours ago, but it's pretty buried by actual
discussion at this point.

[0]:
[https://news.ycombinator.com/item?id=18561684](https://news.ycombinator.com/item?id=18561684)

------
isuckatcoding
Non-go user here. So what are the most desired fratures from Go 2 in the
community?

I remember something about generics not being supported.

~~~
nine_k
Helpful link from the text:
[https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+l...](https://github.com/golang/go/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal+label%3AGo2+sort%3Areactions-%2B1-desc)

These are Go2 proposal PRs, sorted by upvotes.

------
leshow
It seems Go wants to have a more open development process, but it looks like
all the decisions are ultimately under the purview of the "Go team". Does the
Go team include any community members? Or is this "open process" still
essentially up to whims of a small group working at Google?

------
johnvega
"... keeping the language small and clean" \+ Go Modules is the sweet spot for
me.

~~~
klodolph
That’s 1.12 though, isn’t it? I’m not disagreeing that it’s the sweet spot, I
just think we already have it, or close enough.

------
sidcool
I am torn apart between investing the next one year between Go and Rust. I
want to do some cool systems level programming. Both seem to be very good at
it. Go has additional advantages of being older (and may be wiser).

What does the hivemind think?

~~~
zbentley
> some cool systems level programming.

What projects did you have in mind? I think the answer to your question
depends on what you mean by "systems level programming" and what you plan on
doing/trying.

------
JulienSchmidt
This blog post doesn't answer likely the biggest of all questions: Will there
be breaking changes? If so, how will those be handled?

"As a rule of thumb, we should aim to help at least ten times as many
developers as we hurt with a given change" sounds like there might be breaking
changes, but on the other hand Robert still talks about including new features
in the Go 1 compatibility guarantee.

I'd love if the compiler would stay backwards compatible and packages /
modules could be pinned to a certain version, either during import or in the
package / module itself. Then one could write Go 2 code but still use packages
which are not yet updated to Go 2. Personally I think that making breaking
changes is a good idea, as it allows to clean up previous mistakes. However,
Go should at all cost avoid incompatibilities like between Python 2 and 3.

~~~
austeane
It is very clear that there are breaking changes for Go 2. However, they are
testing out their new proposal-review system using non-breaking changes
included in Go 1.

------
ausjke
I'm learning Go, just a naive question, why does Go put the variable type at
the end of declaration, is this an absolute need? no other widely usage
language does that, and it just feels odd to me.

~~~
mmastrac
Pascal did it:

    
    
         procedure SetColor
             (const NewColor: TColor; const NewFPColor: TFPColor); virtual;
    

Rust does it too:

    
    
       fn do_twice(f: fn(i32) -> i32, arg: i32) -> i32
    

Go is similar, but less symbols:

    
    
       f func(func(int,int) int, int) func(int, int) int

~~~
matt_kantor
Also Scala, Haskell, TypeScript, Swift, Kotlin, Visual Basic, Python (PEP
526), and many others.

------
mempko
I'm curious if making go an ISO standard was ever considered.

~~~
remus
Given that go is already pretty well specified (and, perhaps more importantly,
has 2 mature implementations) it's hard to see what advantages having it
formally standardised would bring.

[https://golang.org/ref/spec](https://golang.org/ref/spec)

~~~
mempko
With Go 2, they are moving to a community run project. ISO is a process for
that. I guess, why reinvent the wheel unless they think they can do
substantially better.

------
smudgymcscmudge
Am I reading this right that the list in the #Proposals header are the only
proposals from the Go2 bucket that are being considered for 1.13?

I was hoping "check" would make the cut.

~~~
austeane
Yup. Specifically because they are backwards compatible and well known
problems being used to test their proposal feedback system.

------
gauravphoenix
I really wish Go 2 can make dependency management easier.

~~~
nerdwaller
Have you tried go modules since 1.11? It's significantly simpler now than it
was before.

~~~
gauravphoenix
I haven't yet. I hope a good eco-system develops around them. My biggest gripe
is that there are just too many approaches in Golang when it comes to the
dependency management.

~~~
nerdwaller
Definitely true, the hands-off approach they took seemed strange to me - as
others make that one of the core tenants of the community early on. Since I
have been in the ecosystem it's been `go get`, `vendor` directory, the various
community ones, and now modules.

------
openbasic
Will we finally get a normal module implementation?

~~~
icholy
What's wrong with packages?

------
akuji1993
With that naming practice, it will probably become as hard to google problems
as with AngularJS and Angular 2.

------
gBecks
I've yet to see any mention of immutable data types, which I find I would use
more than even generics.

------
dingle_thunk
Awaiting obligatory "go 2 considered harmful" YNews article.

------
pc2g4d
So generics are in?

------
tromp
Wasn't Go2 considered harmful :-?

------
sova
Throw Semver OuT THE WINDOW!

------
revskill
GOPATH is the ugliness of Go. Can't imagine that overhead for a modern PL.

~~~
emersion
Go modules will replace GOPATH, they're available since Go 1.11.

------
gnarbarian
Go 2 Considered Harmful:

[https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.p...](https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf)

~~~
Zenst
When I started work in the early 80's as a COBOL analyst programmer, I
encountered ideology vs reality of GOTO. When I learned COBOL, I was taught
Jackson Structured Programming. No use of GOTO at all, even exception
handling. Fast forward in my first week into work and having done a nice JSP
program for the task at hand a senior came over with my code and had a chat.
Then took me to the system developers who did all the dirty low level
assembler code (for sorts and other area's in which speedup was huge over
COBOL). Was shown how my approach was far more wasteful of CPU resources and
why others would not be able to maintain such code as all the rest used
GOTO's. I will admit, it was nicely explained and this is in a time in which
mainframes offered the only computer solutions for business of this scale and
not cheap.

I will say GOTO's work well for exception handerling, but still doable
without. But for speed, though less of a factor today, it still translates as
faster code at the low level of CPU runs.

But then, things move on and you will always have that wave of what students
are taught being cutting edge compared to what is actualy in use in work. A
friction many would have encountered in one form or another, even today. Be it
style, design or language/tools choice. What is the best today, may well be
outdated tomorrow, but you have to maintain that legacy investment and it is
often too costly/risky to rewrite that legacy for something that itself could
be legacy the next day.

So as for harmful, well they can spagetti up code if used badly, yet that
comes to many approaches and if they are that bad, why do CPU's still have
JUMP instructions you could counter-argue.

Oh and well played on the humour.

~~~
goto11
> why do CPU's still have JUMP instructions you could counter-argue

Machine code is linear and executed one instruction at a time. It does not
have the concept of blocks, so there is no way to have structured programming.
Jumps are the only way to create a loop or conditional.

~~~
Phrodo_00
> Machine code is linear and executed one instruction at a time.

Only conceptually. In reality, it's executed out of order and branches are run
in parallel.

------
glenrivard
Big fan of both Go and also Rust. It is time we move beyond C and C++

~~~
freedomben
I apologize for asking a question that will likely lead to a flame war
regardless of your answer, but which is better? I've used Go for a while for
certain apps, but as a primarily functional programmer I find my way of
thinking often clashes with the language (and I also don't like the
verbosity).

So, do you do functional programming, and is Rust a better (with all the
subjectivity that word implies) language than Go?

~~~
13415
This 'question' is bound to go up in flamewars, but here is an honest and
unbiased answer by someone who has taken a look at nearly every language on
the planet (a hobby) and thinks that both languages are a bit crappy from a
general programming language perspective but quite usable in practice.

Go is good to get things done quickly. It has a vast ecosystem and super-fast
compilation. It's like a modern BASIC, but more performant and fun to use.
It's fast enough for most everyday tasks except for real-time audio processing
and high end gaming. It's good for writing CLI tools and server backend
software.

Rust is good for writing libraries and CLI tools that replace existing C or
C++ solutions with inherently safer versions and when speed matters a lot,
though not as much as what would make you use Fortran or hand-optimized C. It
is not suitable for high integrity systems and solid engineering where you'd
normally use Ada/Spark, because of low maintainability, an unprofessional
'language aficionado' user base converted from C++, and being a fast moving
target. Maybe later, though.

~~~
wishinghand
> It's fast enough for most everyday tasks except for real-time audio
> processing and high end gaming

Have any new languages popped up in either of those spaces or does C++ still
reign supreme?

~~~
christophilus
Zig seems like a possible contender.

------
throwaway487549
I would love to have type-clases a-la Haskell (implicits with parametric
polymorphism, which is dead-simple and well understood) and universal pattern
matching everywhere, but this is, of course, just a dream.

I would love to have ML/Scala-style syntax for curried functions and function
definition via pattern-matching with guards, which is also, it seems, out of
questions.

Actuall, the more of ML a strict language gets in - the better.

What is really funny is that Bell Labs did a lot of ML research, especially on
stdlib, but Go team is ignoring everything which is not of the C flavour.
Pity.

Again, ML is absolutely wonderful, and type-classes are the biggest single
major innovation since Smalltalk.

It is better to lean towards ML instead of heading towards Javascript.

------
olafure
I smell the second coming of the Python 3 fiasco.

~~~
remus
I'd be surprised if something similar to python 2/3 happens. The go team have
been very explicit in saying that all go 1 code must continue to compile, and
transitioning to go 2 needs to be as seamless as possible (most likely using
tooling to automatically migrate code across, a la go fix from the early
days).

~~~
zhengyi13
Google had Guido working there for a very long time; there's probably a lot of
institutional memory built up around the 2->3 transition, and likely a lot of
lessons learned, and a strong desire not to repeat the experience.

------
RickJWagner
What's that famous tag line? Oh, yes:

"Use of Go 2 Considered Harmful".

------
komali2
Hahah oh no, I literally started learning Go last night. Now what?

~~~
T-A
Finish learning it tonight. It's not that big.

------
rjplatte
I'll be very sad if this goes the way of Perl 6

~~~
meddlepal
Honestly that would be great if it took the momentum out of Go and killed the
language.

I loathe working in Go.

~~~
AsyncAwait
Then don't, but actively wanting to see something gone that other enjoy is
beyond tasteless.

~~~
meddlepal
I would love to completely avoid it, and I do when I can, but it has started
to creep into every job out there now and especially in areas I spend a lot of
time. So just avoiding it is not possible.

I maintain it has been shoved down the industries throat for no good reason
other than Google. It does nothing better than any of the existing mainstream
languages and in many cases is a large step backwards.

So no, I will not stop railing on Go and my hope it goes away sooner rather
than later. Nor will I stop railing on how I think macOS is a cancer in the
Unix ecosystem and also needs to die, how JavaScript deserves to be relegated
to the trash heap, how Android has fucked the Java-ecosystem, and how Chrome
has ruined the internet.

~~~
kbd
> It does nothing better than any of the existing mainstream languages...

Why say this? Even if you don't like Go it's objectively false. What languages
are you comparing it to, Java? C++?

~~~
meddlepal
Java and Python. It's two closest peers.

Go does not compete with C or C++ in my mind because of GC.

The _ONLY_ thing it does better is packaging because of its standalone native
binaries. But most folks using Go are writing software for servers and those
are predominantly Linux x86_64... so ¯\\_(ツ)_/¯

~~~
AsyncAwait
> Java and Python. It's two closest peers.

See, I don't particularly enjoy Go, but that's because of its weak type
system, which Python is no better at. Still, I understand that a lot of people
enjoy Python, so good that it exists.

Java is too verbose. I'd had understood if you have said Kotlin, but Java is
not that much better, (yes, it has generics, but I myself prefer the way
they're implemented in Rust/Swift).

I feel like your examples are not much better than Go and in some ways may be
worse, (concurrency?). If you have said Rust, Swift, Scala, Kotlin...I still
wouldn't want Go to die, but at least could get behind the argument.

~~~
meddlepal
I like Kotlin and I write a lot of Kotlin for personal stuff, but I think it
is a niche language in the backend/server space and hardly qualifies as
mainstream outside Android.

Python with PEP484 is pleasant.

The concurrency story in Java is great already and it is going to improve once
Project Loom is integrated.

I fail to see how Java is significantly more verbose than Go. At least not the
core libraries. The ecosystem is a mess but getting better. Java 11 with `var`
for local variable inference is pretty much on par with Go in terms of
verbosity.

Rust brings a lot of new things to the table but its main competitor IMO is C
and C++. I've done very little Rust but what I have seen I like (though there
are some things I dislike too... like lack of keyword args... a minor nit I
suppose).

Scala is a shit show to maintain with some teams.

~~~
AsyncAwait
> Python with PEP484 is pleasant.

Not yet, I use types as an important form of documentation, so the vast
majority of the library ecosystem would need to adopt optional types before
I'd consider it so.

> Java 11

Not may people actually write Java 11 at work, most are stuck with 8, or even
6. Java 11 is basically even less mainstream than Kotlin right now, as not
even Android supports it.

> is pretty much on par with Go in terms of verbosity

Yeah, but _on par_ is not good enough, it has to be _significantly better_ for
your argument to work. Yet I don't see you calling for the eradication of
Java. Also, gofmt makes it significantly easier to get familiar with a foreign
Go codebase. Not a thing in the Java world. And not having to suffer the JVM
startup time + having static binaries is indeed a real win for some.

> Scala is a shit show to maintain with some teams.

Yeah, it's a kitchen sink. Kotlin I like a lot better in this regard. But then
everything can be a shit show with some teams.

P.S. Rust is getting rather good for writing web servers and with things like
rocket.rs & aync/await, I think it'll be a real contender.

~~~
meddlepal
> significantly better for your argument to work.

No you misinterpreted my point. It has to be significantly better than what
already exists at the time of creation. Java was this to C++ in the 90s and
early 2000s. Go is not that language.

~~~
AsyncAwait
Go can serve as a sort of Java to people who don't want the JVM. There's no
rule that says only one language is allowed in a particular space. Go has
several strong points and several weaknesses, which are to be addressed in Go
2.

Java didn't have lambdas until 8 and now it does. Its generics implementation
is not what I'd like to see. Still, it certainly has its place.

Go has been used to implement widely used technologies like Docker & k8, so it
seems to have found its justification for existing as well.

------
coldtea
>* 1. Allowing generalized unicode identifiers.*

I'm all for full support for unicode string manipulation.

But when ever are "unicode identifiers" a good idea? All kinds of BS decisions
(normalization etc) for no good reason at all. Would you share code with
identifiers written in RTL language? Chinese? Hieroglyphics?

And I'm saying this as someone who's not a native English speaker.

If it was an APL dialect I'd see some reasoning, but what good does it do for
Go?

