9 ms·
I'e been writing my first production-sized Go app over the last few months, and really enjoy it. Some observations: - The standard library is solid, and I was
by wiremine 12y ago
I'e been writing my first production-sized Go app over the last few months, and really enjoy it. Some observations:
- The standard library is solid, and I was surprised how well-rounded and mature the third-party library support it. Coming from a Python/Ruby background, that was nice to see.
- I totally agree with the comments on this thread about dependency management. Godep [1] is nice, but it would be great to see a canonical dep management tool for go.
- The tooling for Go is excellent: More languages need something like "go fmt".
- In general the document is solid, but I've found the usability of the generated docs to be poor. You think they could bribe a few Google designers to spend some time fixing that...
- I've noticed a lot of Rust lovers commenting about how great Rust's type system is. It probably is, but I haven't run into any problems with Go's type system. I've found it to be practical and easy to use. The only issue is parsing JSON when you're not marshalling it to struct. They need to fix that (although there are some nice third-party tools to make it easier).
- Go is a minimal language and has been called boring. [2] I don't claim to be an expert yet, but I don't think I've reached this level of productivity with a language this quickly before.
[1] https://github.com/tools/godep https://github.com/tools/godep
[2] http://stevebate.silvrback.com/go-is-boring http://stevebate.silvrback.com/go-is-boring
- TheCoelacanth 12y ago> I've noticed a lot of Rust lovers commenting about how great Rust's type system is. It probably is, but I haven't run into any problems with Go's type system. I've found it to be practical and easy to use. Go doesn't have generics. To someone coming from a language like Rust, saying that your type system doesn't have generics is like saying your car doesn't have wheels. It's just considered non-negotiable.
- chimeracoder 12y ago> saying that your type system doesn't have generics is like saying your car doesn't have wheels. To overburden an analogy, it'd be more like complaining that your tank doesn't have wheels[0], or your hovercraft. Go takes a different approach to the same problem (in this analogy, getting from point A to point B). But really, this is a rather tired flamewar that gets beaten to death literally every time a post about Go makes the front page, and there's really nothing more that can be said about it. Either program in idiomatic Go, which means using the language as it's designed (ie, without generics, at least in its current form), or don't, but it's very tiresome to see this argument rehashed again and again. [0] https://en.wikipedia.org/wiki/Continuous_track#mediaviewer/File:Caterpillar_track_shingle.JPG https://en.wikipedia.org/wiki/Continuous_track#mediaviewer/F...
- khyryk 12y agoThis happens because almost every time there's someone who more or less asks what in the world generics are for since they can do everything they want to with Go's type system. Sure, it's possible, but it's missing the point.
- mitchty 12y agoI always saw it as the classical: why do you want a screwdriver to put the screw in place? The hammer should be good enough! Well, sure, I guess you can pound a screw into things with a hammer but you're missing the point.
- pekk 12y agoOr just build your furniture without using screws, like in Japanese carpentry. When people are already having a decent time building things using the tool, it looks pretty stupid to tell them they've done it all wrong for years in all the decent products they made.
- ufo 12y agoParametric polymorphism gives safety guarantees that you can't easily obtain without language support. For example if you have a function typed "forall a . a -> a" you know it has to be the identity function (or something that bypasses the typesystem, like infinite loops or a runtime exception).
- 4ydx 12y agoAnd in Go since there is no parametric polymorphism you would end up writing either: 1) Methods with names that indicate the parameter types. 2) Method calls on objects to convert some internal struct data from one type to another. 3) Something I haven't thought of that doesn't involve losing a handle on your type. So there is certainly a loss in convenience, but if you use the type system it can be just as safe as a functional language as far as I can tell. So, yeah, it isn't as intellectually elegant, but it also isn't really that hard to deal with.
- engendered 12y agoTo someone coming from a language like Rust, saying that your type system doesn't have generics is like saying your car doesn't have wheels. It's just considered non-negotiable. Analogies are almost always useless diversions, but this one is particularly ridiculous. People are building real, working, successful solutions in Go with rather surprisingly regularity (which, if the comparison needs to be made, they don't seem to be doing with Rust). It is obviously working pretty well, and that "non-negotiable" point turned out to not be a showstopper. A car without wheels? If we have to abuse analogies, more like a car with a manual transmission. People can have hysterics about how will they ever eat their burger while they drive, but somehow some people manage.
- pcwalton 12y ago> People are building real, working, successful solutions in Go with rather surprisingly regularity (which, if the comparison needs to be made, they don't seem to be doing with Rust) I have written hundreds of thousands of lines of Rust code for Servo, the Rust compiler, and other projects. Of course it's a less mature language, but people are building plenty of solutions, including production solutions, in Rust.
- f2f 12y ago<snark> had to be hundreds of thousands because you didn't come out of the gates with a decent design and you had to wing it for the last 6 years </snark> ;)
- wwweston 12y agoIf being able to get things out the door anyway is the standard for "well, guess this language is nice enough!", there goes any argument against JavaScript, or for that matter Go over Java. I'm one of the people who is currently making a working solution in Go. Are generics the equivalent of missing wheels? Probably not, but I am absolutely finding it a present and persistent pain point that I don't have something like that or even just overloaded function/method signatures, and instead have to frequently repeat a lot of rewritten code scattered full of lots and lots of if/else cases. Life could be worse. But the fact that people are shipping doesn't mean it's a language in which people aren't finding a specific missing features to be a problem.
- shurcooL 12y agoThere are two types of people.
- istvan__ 12y agoThis was one of my main complaint against Go. However, I still think the out of the box performance is great and for problems that don't require generics it is a very good option. I especially like the static compiling feature that makes deployments more straightforward. Handling HTTP requests and performing routing, dispatching requests to other services reliable async way is the biggest use case for me using Go. It can totally be written in any other language(Rust), if using generics is a must.
- Animats 12y agoHaving written in both Go and Rust, I can see the arguments. Go has a relatively simple, easy to use type system. The problem is that whenever you need to do anything generic, you have to use Go's "any" type, "interface{}", and the reflection system. This results in doing stuff over and over at run time that could have been done once, preferably at compile time. For much web back-end stuff, though, you don't need a really fancy type system with generics. Mostly you're pushing strings around, which Go does quite well. Rust's type system has most of the bells and whistles of C++, plus some new ones. It's clever, well thought out, sound, and bulky. Rust has very powerful compile-time programming; there's a regular expression compiler that runs at compile time. I'm concerned that Rust is starting out at the cruft level it took C++ 20 years to achieve. I shudder to think of what things will be like once the Boost crowd discovers Rust. The lack of exception handing in Rust forces program design into a form where many functions return "Result" or "Some", which are generic enumeration/variant record types. These must be instantiated with the actual return type. As a result, a rather high percentage of functions in Rust seem to involve generics. There are some rather tortured functional programming forms used to handle errors, such as ".and_then(lambda)". Doing N things in succession, each of which can generate an error, is either verbose (match statement) or obscure ("and_then()"). You get to pick. Or you can just use ".unwrap()", which extracts the value from a Some form and makes a failure fatal. It's tempting to over-use that. The lack of exception handling in Go yields too many "goto" statements. There's also a tendency to turn the panic/recover mechanism into an exception system. This has roughly the problems of C's" longjmp". As a practical matter, Go now has most of the libraries you need for server-side programs. (Not GUI programs, though.) Rust has only very basic libraries, and they're not stable yet. The language hasn't quite settled down. People are writing and porting libraries at a good pace, and this problem will be solved.
- skj 12y ago> I'm concerned that Rust is starting out at the cruft level it took C++ 20 years to achieve. That is the core reason why there are no generics in Go. Not because the Go team thinks they're a terrible idea, but because they think cruft is a terrible idea. The default answer to a new feature is "no". When everything seems to be going fine without generics (except for internet flamewars), the answer stays "no".
- Kiro 12y agoI've never used a typed language at all (only PHP, JS, Python etc). Why is it a big deal? I read the Wikipedia article but didn't understand why.
- drapper 12y agoSay you have a function that can operate on various types, for example you'd have a function in JS like: function addKey(input, key, value) { input[key] = value; return input; } this will work on either Objects or on an Array. But if you have static typing and no generics to make it work you have to either: - create two versions of the same function, one for Objects, 2nd for Arrays - use any as a type of input - this will work, but you will loose most of the benefits of type checking, e.g. you will be also able to pass Number as an input and compiler won't complain, it will be detected as error only on runtime and other things (your function will also return any so further on in the program you won't know what type is used). With generic it's easy, you write the function once and when you call it you tell what types are used: // definition: function addKey<X,Y,Z>(input:X, key:Y, value:Z):X { ... } // call: var a = addKey<Array<string>,Number,string>([],0,"fubar"); With this particular example there are probably other ways as well (sum types, common interface) and also compiler may actually detect passing Number as an error (depends how smart it is), but there are more complex cases, where lack of generics will lead to a lot of copy/pasting and boilerplate.
- Kiro 12y agoThanks a lot. That was a really good explanation which instantly made me understand generics. In fact, I think this is an awesome way to learn new languages and concepts. You start with an example in a language you know and reason about the functionality from that.
- je42 12y agoGuarantees at compile time: Array<double> means the only element you will encounter is a double. Array<ISomeInterface> means the only element you will encounter is of type ISomeInterface. hence, you can express part of some code's requirements via the types that a function,class exposes and/or requires. these requirements can then be checked at compile time. without this you have to defer the "checking" to runtime.
- rogpeppe1 12y agoFWIW Go does implement a significant subset of generics in a type-safe way. For any parametric type P[T], if P has no public methods or fields that mention T, then Go can implement it by allowing an interface (not necessarily interface{}) type for T. As long as the implementation of P does not upcast T values (something which is generally frowned upon, although tolerated in some circumstances), this will be as type-safe as in any language with parametric polymorphism. For example, bufio.NewReader would probably, in a language with generics, be phrased as a type with respect to a type parameter. Something like (in bastard Haskell) class Reader a where Read :: a -> [Char] newReader :: (Reader a) => a -> BufioReader a In Go, it's: package bufio func NewReader(r io.Reader) *Reader The interface argument is implicitly a type parameter here. This subset of generics covers a wide range of software components, even if it doesn't include the usual container types.
- skj 12y agoI think it's important to think of these features in terms of their smallest possible descriptions. One mistake with Java, I think, is that "inheritance" is how you do both polymorphism and composition (I know you can do either without inheritance, but it's especially a pain to do composition without). With Go, polymorphism is done with interfaces. Composition is done with embedded fields (and the very convenient method promotion).
- burntsushi 12y ago> To someone coming from a language like Rust, saying that your type system doesn't have generics is like saying your car doesn't have wheels. It's just considered non-negotiable. That's ridiculous. Plenty of people can appreciate the trade offs between "no generics" and "generics." There's nothing "non-negotiable" about it.
- bsg75 12y agoIf its not-negotiable, then get over it, and use a language that meets your requirements.
- chimeracoder 12y ago> - Go is a minimal language and has been called boring. [2] I don't claim to be an expert yet, but I don't think I've reached this level of productivity with a language this quickly before. I was drawn to Go initially because of its promises around concurrency, but this is why I stayed. Within less than a month, I was as productive in Go as I was in Python, despite the fact that I had been programming in Python for several years at that point. > - I totally agree with the comments on this thread about dependency management. Godep [1] is nice, but it would be great to see a canonical dep management tool for go. For what it's worth, Docker has more or less replaced this need for me. I know it doesn't actually do "dependency management" in the traditional sense, but by the time that ad-hoc vendoring no longer works, I've found it's already time to start using Docker for deployment for other reasons anyway. At this point, it's just as easy to use Docker to manage the dependencies at the application level while developing as well.
- neurosnap 12y agoAs someone who has recently ventured into the world of Docker, I have been questioning if there is a need for virtualenv anymore, especially in production.
- objectified 12y agoI do believe the need for virtualenv stays, in development as well as in production. Even when using a Docker container, you will still want to pin your dependencies strictly to specific versions and not risk any interference of Python modules that happen to be on the OS. I think it's important to not make assumptions in that area (dependency management) when wanting to create stable software.
- Sphax 12y agoI'm curious, how does Docker help with that ? You still need to include the dependencies somehow, either by vendoring or using something like Gom, or straight go get.
- aninhumer 12y ago>Within less than a month, I was as productive in Go as I was in Python That's not really surprising. Go is actually pretty similar to Python in a lot of ways, the most obvious being the set of built-in data structures.
- threeseed 12y agoMost languages have an equivalent of go fmt. They are just third party tools that aren't integrated into the language. Which for me is perfectly acceptable. There are sometimes legitimate reasons for formatting code different to what the language creators believe.
- acdha 12y agoI used to agree with you more strongly but I think it's easy to forget just how much time and confusion is saved by having a single standard format which anyone can trivially check and apply. It's not just about avoiding unnecessary bike-shed arguments but also things like the cognitive cost of having to dealing with each project / developer's style quirks. I'm now inclined to believe that a basically free way to avoid bugs and make things like code review easier and more productive is worth the minor cost of people having to break out of old ruts.
- threeseed 12y agoAgain. Third party tools will have exactly the same benefits. People have been using standard code formatters in Eclipse/IntellIj for what decades now ?
- zevyoura 12y ago> a single standard format
- spronkey 12y agoindeed. Pretty sure there's some cognitive load involved for developers who come onto a team who uses a style that's different to what that developer is used to. Languages with strict style standards remove this problem.
- Gurkenmaster 12y agoUnless you change the settings it'll default to the Java Conventions.
- eklavya 12y agoActually languages with stronger/more capable type systems are a feature and like all features they are wanted by some people who find that it makes their life easier. Not having a strong type system is not a fault per say it's just that I need a strong type system as a feature(indispensable for me). For me choosing between Go and Rust is mostly because of the type system. If Go works for you then it's fine. Although if you want to find out how type system can help you, it's a different story.
- insertnickname 12y ago>- In general the document is solid, but I've found the usability of the generated docs to be poor. You think they could bribe a few Google designers to spend some time fixing that... Please elaborate. What exactly do you mean?
- gnuvince 12y ago> I've noticed a lot of Rust lovers commenting about how great Rust's type system is. It probably is, but I haven't run into any problems with Go's type system. I think it depends on the kind of things people write. Most people I see writing Go code seem to be writing programs, a piece of code that performs a specific function for a user. In those cases, you very often know exactly the domain types, and Go's type system is perfectly adequate there. Other programmers write libraries, functionality that is meant to be used by other programmers to build their code upon. In this case, you rarely know the context in which a user of your library will use it, therefore you cannot really make any decision about types. This is a big reason why people like having parametric polymorphism. The constant arguments that we see online probably comes from people writing programs and people writing libraries arguing with one another without understanding the context in which the other writes code.
- liotier 12y ago> Other programmers write libraries, functionality that is meant > to be used by other programmers to build their code upon. > In this case, you rarely know the context in which a user of > your library will use it, therefore you > cannot really make any decision about types. Uh ? Even for a library you certainly can make decisions about types, document them and enforce them. Who wants to accept unspecified data types ?
- lumpypua 12y agoLiterally everyone who's ever written a container.
- omega_rythm 12y agoThat doesn't mean no decision has been made: in a typed language with subtyping, this amounts to choose the "top" type of the type hierarchy, and without subtyping, you're choosing not to enforce structural constraints. In untyped languages with structured values (like any usable language), you make those decisions in the way your code checks for this or that value attribute or runtime structure. I guess unspecified and specified as "any" is often the same, but for me the former is a design mistake.
- fit2rule 12y ago>- Go is a minimal language and has been called boring. [2] I don't claim to be an expert yet, but I don't think I've reached this level of productivity with a language this quickly before. Tried Lua? Your opinion interests me ..
- tmaly 12y agoI will give Rust a try when it has a solid library like Go