20 ms·
Go’s Type System Is An Embarrassment
- letstryagain 13y agoAre we complaining about generics again?
- alok-g 13y agoI see nothing wrong with that. I would like to keep on complaining till they listen! :-)
- kisielk 13y agoIt's not that "they" aren't listening. There's a limited number of developers working on the language, there are many other problems being solved. So far despite all the people lamenting the lack of generics in Go I've yet to have seen someone propose a viable (eg: backwards compatible, realistic to achieve with the current compilers and runtime, etc.) way to implement, nevermind someone who's produced a prototype. Maybe that sort of thing will be easier once more of the toolchain is rewritten in Go later this year. I don't think anyone is denying that generics make writing certain types of code easier, but it's worth getting them right since major language additions are something you need to support for a long time.
- clhodapp 13y agoSo far despite all the people lamenting the lack of generics in Go I've yet to have seen someone propose a viable (eg: backwards compatible, realistic to achieve with the current compilers and runtime, etc.) way to implement, nevermind someone who's produced a prototype. This seems to make it even more of an issue that they weren't included in the first place. Based on your statement, it's likely that when generics are finally added, they will initially cause the community some pain or they will feel tacked on.
- ithkuil 13y ago> So far despite all the people lamenting the lack of generics in Go I've yet to have seen someone propose a viable (eg: backwards compatible, realistic to achieve with the current compilers and runtime, etc.) way to implement, nevermind someone who's produced a prototype. https://github.com/droundy/gotgo https://github.com/droundy/gotgo
- prodigal_erik 13y agoIt's kind of crazy to prioritize anything other than generics and exceptions. If Go never catches on, those will surely be why, and IMHO rightly so, it's just unreasonably hard to write correct code without them.
- frou_dh 13y agoThis masterclass in clickbait titling pulled in 735 comments and counting on /r/programming. Watch and learn, bloggers!
- dkuntz2 13y agoIt did something similar here before the outage.
- jjsz 13y agoWas it cached?
- dkuntz2 13y agoI don't think so. For the most part people were either curious about why Go did what it did (let you export the `NewHidden` while keeping `hidden` unexported: requires `hidden`s to be created using the specific constructor), or defending Go's choice in letting you export functions that return an unexported type.
- deleted 13y ago[deleted]
- thinxer 13y agoWhat's wrong with leaking un-exported element? Your code wants it to be exported. If you care about it, please return an interface type.
- rfw 13y agoAs I posted before the outage, I don't think leaking un-exported elements is actually that broken either -- Haskell gets by fine with it (you can omit the type and its constructor in the module export list and have types "leak" into the code importing said module). It can be a useful way to keep types opaque and not allow users to construct instances directly. The actual issue, in my opinion, is the weird behavior of the reflect package which allegedly cannot reflect on the leaked element despite its members being publicly accessible anyway.
- DrJokepu 13y agoAuthor here. What I’ve written regarding the reflect behaviour isn’t entirely true and I should probably update the article to reflect that. It’s possible to get (but not set) the value of unexported fields as long as they are of a built in type (e.g. int). What’s not possible is to get access to unexported fields as empty interfaces, which means you cannot type assert them to structs or other types. This seems like an arbitrary limitation (although I’m sure there is a reason for it) and somewhat limits the usefulness of the reflect package.
- colin_mccabe 13y agoWhat's embarrassing is that people are still evaluating programming languages like they were bags of features. The more features you stuff in the bag, the better it must be! The reality is that generics aren't free. They result in difficult-to-understand error messages and more cognitive complexity. To quote Yossi Krenin, "You may think it's a StringToStringMap, but only until the tools enlighten you - it's actually more of a... std::map<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > >" Of course, it would be nice to have generics, or something like them, for writing typesafe containers. But there are other goals in the language like fast compilation, easy-to-understand error messages, and overall simplicity. I hope they can come up with an implementation of generics that can keep those good properties of the language. But if they can't, it shouldn't be added just to get a feature bullet point. Use the right tool for the job.
- alok-g 13y agoI am not convinced that C++ examples are valid as a generalization of the failures of generics for other languages. C++ libraries are often overly generalized with means to "configure" the generics by passing additional type arguments. I do not think it has to be like that.
- davidcuddeback 13y agoC++ templates are also latently typed. The bad error messages arise from the fact that C++ templates behave more like a duck-typed language than a strongly-typed language. Look at the error messages that arise from C++ template errors and a lot of them are about missing functions, just like you get at runtime when you have a type error is a dynamically-typed language. I think C++ concepts will improve this when they're standardized, because they will allow C++ compilers to type-check template arguments. (See bounded polymorphism.)
- AnthonyMouse 13y ago
- nostrademons 13y agoMy biggest beef with the Go typesystem is that they didn't get rid of nil. Tony Hoare (the guy who invented null) has acknowledged they were his "billion dollar mistake" [1], common practice in Java and Haskell is moving away from them, and yet Go included them anyway - in a language that's supposed to be robust because you're supposed to handle every case. The Maybe (or @Nullable) type is a much better idea, because it flips the default from "any variable may be null" to "only variables explicitly declared as such may be null". [1] http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare http://www.infoq.com/presentations/Null-References-The-Billi...
- frou_dh 13y agoIt's exacerbated by nil being reused as a value for things that aren't even pointer types, like the slices, channels and especially interface "pairs"[1] [1] (<NoType> . nil) vs (T . nil) is pretty weird: http://play.golang.org/p/fmk-72OYkO http://play.golang.org/p/fmk-72OYkO
- shurcooL 13y agoThere is no such thing as a Go variable with no type. They all have a type (could be interface{}) and a value (could be nil). package main import ( "fmt" "github.com/davecgh/go-spew/spew" ) func main() { var x interface{} var y chan (int) spew.Dump(x) spew.Dump(y) var z interface{} = y spew.Dump(z) fmt.Println(x == z) fmt.Println(y == z) } // Output: (interface {}) <nil> (chan int) <nil> (chan int) <nil> false true
- frou_dh 13y agoDoesn't an interface value have both a static type and a dynamic type and in a case like x its dynamic type is "nothing"? I didn't mean that this is necessarily bad, just that it seems weird for "nil" to be overloaded beyond pointers.
- 13y ago
- kristianp 13y agoGo is designed to be a small, simple language, it's not hard to release that. If you want a fully featured type system, go program in Ocaml, Haskell or another 'big' language.
- TylerE 13y agoThat falls flat on it's face as a cop out when you look at a language like nimrod that manages to be practically as simple as go while including full generics. Oh, it's faster too. http://nimrod-lang.org/tut2.html#generics http://nimrod-lang.org/tut2.html#generics
- rdtsc 13y agoNimrod is a gem. Just needs a big company to host release parties and sponsor it. I am convinced, a good part of Go's popularity is Google. As a language it is ok. Has good stuff in it. Quite often the argument for adoption is "Google is behind it, and it is becoming really popular". Which, is not completely irrational -- it is nice to have a large company throwing away perhaps years of quality full-time dev work at a language.
- pjmlp 13y agoQuite true. I doubt Go would be as talked here if it wasn't for Google. Just check how far Go's ancestors (Alef/Limbo) went.
- ithkuil 13y agoI guess this also means that Go wouldn't have the success it has if it wasn't built and used by a group of engineers who are used to the pitfalls of complexity and value tools that help you to get the job done and yet produce maintainable code. This also means that it's not a good fit for everybody. It's certainly less exciting than most of the things that you find around; that's ok, that's the point. Less focus on the language, less focus on the magic and more focus on what you do with it.
- deleted 13y ago[deleted]
- bsaul 13y agoType system power really is the only question i have left relative to go. I've always seen go being used for low level very technical stuff, where you don't need lots of abstraction, but rather powerful primitives and libs. I've always wondered how it scales to business process modeling, and the lack of generics always worried me. On another aspect, 2013 was the year of Go being unanimously praised, and i've got the feeling 2014 is going to be the year of the backlash. Still, i don't see any other languages able to take the crown back. Rust looks way too unpolished and has not only one but multiple pointer types.
- TheCoelacanth 13y agoRust really doesn't target the same uses that Go targets. Go basically targets people who need a faster Python or a simpler Java. It doesn't have enough low-level control to be used for most of the things that C is still used for. Rust targets the low-level uses where a high degree of control over memory management is necessary. One of it's main goals is to make it possible to statically reason about memory ownership. You would never try to implement something like a modern browser or a production-quality language runtime in Go. On the other hand, Rust is targeted directly at that kind of thing, and the multiple pointer types are absolutely necessary for those use cases.
- pkroll 13y agoNothing I've seen on Hacker News would lead me to the conclusion that 2013 was the year of Go being unanimously praised. It gets flack every time a story shows up.
- pcwalton 13y ago> Rust looks way too unpolished and has not only one but multiple pointer types. This is overstated. There is just one pointer type in the language, the unique pointer, and there are also references. That said, the distinction between unique pointers and references is there for a reason. You need this power for low-level programming. A pervasive global GC is not appropriate for all applications.
- vectorpush 13y agoI love go, but my personal gripe with the type system is that there is no way to pass type information around without using a zero valued (or fully populated, it makes no difference) instance. For example, I have a factory struct with a New method that returns interface{MySignatures()}, but I cannot inform the factory of the concrete type I want it to produce without passing in something like new(ConcreteStructWithMySignatures). Some have suggested I pass in a string, but what is the point of a type system if I have to use strings to reason about my types?
- puppetmaster3 13y agoAre we trying to make Go into Java or JavaScript as it relates to dynamic or static?