It was added to the FAQ in 2010: https://web.archive.org/web/20101123010932/http://golang.org...
Ian has been thinking about the problem for the past 7+ years, since even before Go1 was out, when the language was frozen.
I think this is about the seventh generics design doc that Ian has written. (This time he wrote it with Robert.) They keep getting better. Hopefully this one holds up.
You should read less is exponentially more by Pike. He made it clear back then that he didn't see a need for generics and Go was explicitly written to be a replacement for C++ without all the unnecessary features. Not having generics was at least initially a core part in justifying the existance of Go, just like not having any form of exception handling ( they had to add panic recover quite early ).
No, I'm saying that the person you are replying to has no need of you reminding him of Pike's words, given that he actually knows Pike, unlike you.
I point to Pikes blog which clearly said A.
So given these two points I should implicitly discard evidence (in form of a blog entry by one of the Go creators) in favour of a statement that is clearly at odds with it? His connection to Pike or Go does not change the text on the blog, unless you disavow Pikes role in the creation of Go his distaste of generics and his clear classification of them as unnecessary remains a fact.
However, ever churning dependency management, cumbersome error handling and the lack of generics were all huge drawbacks, that kept me reaching for Scala and Python for backends of personal projects. When Go 2 comes out, I think it’ll be my clear #1. It’ll bring the language to the level of power I like, while maintaining Go’s unique set of strengths (listed above).
I expect it’ll be similar to Python, which supports generics, very powerful reflection, many programming paradigms, etc., but the popular libraries tend to have simple, easy to understand APIs, because that’s just the culture of the community.
Basically, I find that though it’s possible to do all sorts of crazy shit in Python, most popular libraries have simple APIs, because simplicity is part of Python’s culture. There are certainly exceptions though.
At the end of the day, I notice a significant difference in wanton magic between the Go and Python communities, and it's big enough to make me prefer Go over Python when given the choice (despite that I've used Python far longer and more regularly).
The point was creating a language without them after they had become a common language feature across all major static languages.
Not that Go ever planned to not have generics. It was always simply a question of how to implement them in a non-ridiculous way. They were warned early on by members of the Java team to tread carefully and not make the same mistakes they did.
The team has crafted many generics proposals over the years, but they all fell short one way or another.
Objective-C merges C's type system with the dynamism of Smalltalk. Generics are only meant as a mechanism to ease interop with Swift.
Dynamic languages naturally don't require generics due to their semantics.
The team always handwaved the remarks of many of us as they now themselves recognise.
"In retrospect, we were biased too much by experience with C++ without concepts and Java generics. We would have been well-served to spend more time with CLU and C++ concepts earlier."
Just "check" would be preferable, with an implicit handler of "if err != nil { return err }"
Although I still would prefer something leaner like the "?" operator from Rust.
Proof: Any exception system that lacked the ability to catch exceptions from lower frames would be called a defective exception system.
This check keyword does not implement an exception handling system.
That’s very different behaviour and along with using the error interface avoids the main objections to exceptions ( unexpected throws handled far from the error location, unexpected errr types).
This is just a small change to make it easier to annotate and easier to return without comment.
Is that a good thing?
Yes, because instead your program won’t compile if you forget to handle an error ( except in the case of a function which only returns error, which you can ignore by mistake - I would like to see that fixed in go 2 as well).
Sure. It's explicit error handling that just so happens to look exactly like a form of exception handling, c.f., the zero-overhead exceptions proposal in C++land.
This is how you say, in language-design-ese, "I want to do what my critics have been saying for years is the right thing without admitting that they've been right all along".
I saw a talk by James Gosling (of Java fame) a few months ago in which he said one of the most important things he's glad he did throughout the development of the language is "Decide... not to decide".
The purpose of this "deciding not to decide" should sound familiar by now: once you commit to something, it's hard to backtrack. And once it's hard to backtrack, you have lost your ability to look for more optimal solutions than the one you've fixated on.
This is why generics in Java took so long. And to this day, the developers of those generics do not regret taking their time to do so. I think that's interesting to note, don't you?
It's okay to make decisions after deliberation.
Deliberation does not imply a fight.
---
Tone police aside, did you... read... the proposals? I don't think it's correct to dismissively say that the proposed handle/check syntax is identical to other checked exception syntaxes; it doesn't compose in the same way as traditional try-catch blocks; and it doesn't have the power to create arbitrary longjumps across multiple stack frames as exceptions do. In short, it's very little like traditional exceptions at all.
If you just feel like snarking, then sorry for spoiling.
And to work around that problem, you need some kind of generics that lets you define error signatures in terms of other signatures - e.g. for map(), you want to say that it can return an error if and only if the function it maps can return an error (and ditto for error types).
handle err {
cleanup1()
return 42, nil
}
handle err {
cleanup2()
}
check dostuff()
into try {
try {
dostuff();
} catch (Exception e) {
cleanup2();
throw e;
}
} catch (Exception e) {
cleanup1();
return 42;
}