5 ms·
The lesson Go seems to have learned is that, since C++ and Java burned their fingers, clearly fire is too dangerous for humans. The thing that makes it painful
by aninhumer 11y ago
The lesson Go seems to have learned is that, since C++ and Java burned their fingers, clearly fire is too dangerous for humans.
The thing that makes it painfully obvious to me that Rob Pike hasn't bothered to learn anything from the PL community is that Go has nil. That just shouldn't happen in a modern language.
- justinlardinois 11y agoWhat's wrong with nil? Just legitimately curious, and I've never used Go at all.
- reycharles 11y ago> I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years. https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retractions https://en.wikipedia.org/wiki/Tony_Hoare#Apologies_and_retra...
- nostrademons 11y agoIt means that every single type in the language has one extra value it may contain, 'nil', and your code will crash or behave erratically if it contains this value and you haven't written code to handle it. This has caused billions of dollars in software errors (null dereferences in C/C++, NullPointerExceptions in Java, etc.). See "Null References: The Billion Dollar Mistake" by Tony Hoare, the guy who invented it: http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare http://www.infoq.com/presentations/Null-References-The-Billi... A better solution is an explicit optional type, like Maybe in Haskell, Option in Rust, or Optional in Swift. Modern Java code also tends to use the NullObject pattern a lot, combined with @NonNull attributes.
- sythe2o0 11y agonil in Go doesn't work that way. Most types cannot be nil.
- nostrademons 11y agoInteresting, because (reading up on this) value types can not be nil. How often does typical Go code use values vs. interfaces or pointers? It seems like the situation is pretty similar to modern C++, which also does not allow null for value or reference types (only pointers) and encourages value-based programming. Nil is still a problem there, but less of one than in, say, Java, where everything is a reference.
- sythe2o0 11y agoIn my own experience, nil basically only shows up when I've failed to initialize something (like forgetting to loop over and make each channel in an array of channels), or when returning a nil error to indicate a function succeeded. I've never run into other interfaces being nil, but I also haven't worked with reflection and have relatively little Go experience (~6 months). The code that I've written regularly uses interfaces and pointers, but I'd guess 80% works directly with values.
- lobster_johnson 11y agoBut a bunch types you do expect to work can: Slices, maps and channels. var m map[string]bool m["foo"] = 1 // Nil, panic var a []string a[0] = "x" // Nil, panic var c chan int <-c // Blocks forever This violates the principle of least surprise. Go has a nicely defined concept of "zero value" (for example, ints are 0 and strings are empty) until you get to these. The most surprising nil wart, however, is this ugly monster: package main import "log" type Foo interface { Bar() } type Baz struct{} func (b Baz) Bar() {} func main() { var a *Baz = nil var b Foo = a fmt.Print(b == nil) // Prints false! } This happens is because interfaces are indirections. They are implemented as a pointer to a struct containing a type and a pointer to the real value. The interface value can be nil, but so can the internal pointer. They are different things. I think supporting nils today is unforgivable, but the last one is just mind-boggling. There's no excuse.
- thegenius2000 11y ago> The lesson Go seems to have learned is that, since C++ and Java burned their fingers, clearly fire is too dangerous for humans. I think that's a little bit unfair, since Go introduces many powerful ideas not (traditionally) available in Java or C++: namely first class concurrency and functional primitives. Its handling of typing, the ability to define types not necessarily based on structs, the excellent design of interfaces are other examples. Go is an extremely powerful and expressive language that opens up the doors for programming in new paradigms, while making it easy to maintain readability and simplicity. Fair point with the nil issue, I think that's one of Go's other weaknesses. But it does make up for that with its excellent error handling paradigm.
- prodigal_erik 11y agohttps://golang.org/doc/faq#nil_error https://golang.org/doc/faq#nil_error is not an excellent design. It's a serious bug that converting nil to an interface sets the type field to a meaningless value (nil doesn't have a type!) and ridiculous that the interface doesn't compare equal to nil (if it's not nil, what does it point to?)