7 ms·
One thing that is perhaps counter intuitive is how you do a lot of for loops compared to other languages (Compiled/Statically typed included). Once you let go y
by pothibo 12y ago
One thing that is perhaps counter intuitive is how you do a lot of for loops compared to other languages (Compiled/Statically typed included). Once you let go your previous expectations, Go gets a lot nicer to use.
The amount of for loops you will write will also makes it obvious when you start doing O(n^2) operations in your methods. Same can be said with variables declaration and error verifications in Go. They are annoying at first, but then you understand by reading your code the places where error can occur or where you decided to ignore errors (By using _).
It's a different approach and it's refreshing.
- frou_dh 12y ago> ... error verifications in Go ... you understand by reading your code the places where error can occur or where you decided to ignore errors (By using _) This compiles: package main import "errors" func main() { f() println("hello erroneous world") } func f() error { return errors.New("boo") }
- cjslep 12y agoSure, you can fail to capture any return variable (not just errors) in lots of languages. What is available to Go that isn't in, say, C++ or Java is the "black-hole variable" marked with the underscore _ so its very much a stylistic choice to insert it in Go where errors would be returned. Applied consistently, you can gain a lot of readability. But it is very much a stylistic choice.
- NateDad 12y agoWhich you can catch with a linter like https://github.com/kisielk/errcheck https://github.com/kisielk/errcheck. Errors in Go are just values. There's nothing "more wrong" about ignoring a return value that is an error or one that is file handle, for example. And in cases where a function returns an error and a value (where the error generally indicates the validity of the value), you'll get a compile error if you don't check the error. That's pretty good for basically zero overhead.
- frou_dh 12y ago> And in cases where a function returns an error and a value (where the error generally indicates the validity of the value), you'll get a compile error if you don't check the error. This compiles: package main import "errors" func main() { x, err := f() if err != nil { return } y, err := g() h(x, y) } func f() (x int, err error) { return 1000, nil } func g() (y int, err error) { err = errors.New("boo"); return } func h(x, y int) { println(x/y) } (I do write Go most days and rather like it, but apologists for its weak parts are legion)
- NateDad 12y agoPretty sure errcheck will catch that too. The thing that bugs me is the people that make up problems that are not at all problems in real day to day coding.
- ominous_prime 12y agoThis looks more like a bug. The second err is a valid redeclaration, and so should be checked for usage on it's own. Though the redeclaration through multiple assignment is itself a bit of a wart that the programmer hast to be wary of, so it may not be a big deal. In any case, the go compiler is very helpful in most cases, and better tooling can improve things further.
- NateDad 12y agoFYI the second use is just assignment, that's why it's not caught by the unused variable rule.
- ominous_prime 12y agoAh right. It only shadows if it's a new scope.
- Sharlin 12y agoIMO, the number of imperative-style for loops I have to write in Java (pre-8) is one of the most frustrating things in the whole language, especially after exposure to Scala (and later, to Java 8).
- NateDad 12y agoYeah, it seems like a lot of the criticisms of go boil down to "I don't like writing simple loops".
- rtpg 12y agomaps and filters are things that have existed for a long time, and are extremely commonplace. They are also very representative of common operations in programming. Not having generics means we can't properly build these ourselves, and Go doesn't offer list comprehensions, so instead we're forced to for loop.
- NateDad 12y agoYes, loops, just like we learned in CS101.
- wtf_is_up 12y agoBut writing a loop takes up at least 3 lines in my editor!
- frowaway001 12y agoI used to play with a small plastic hammer when I was in kindergarden thirty years ago! I will be very irritated if people laugh at me for trying to build my new house with this hammer now. -- Golangers
- gnuvince 12y agoLoops are basically just compares + labels + jumps, yet we abstracted away from those, because we saw that it was common to want to execute a block of code a given number of times (for loop) or as long as a condition held (while and do/while loops). In recent years, more languages (C++, Java) have added a construct for doing an operation on every element of a collection (for each). Why then can't we have more abstractions of patterns programmers write over and over again? It makes a lot of sense to have an operation to apply a function to every element of a collection (map) or to remove elements of a collection based on a predicate function (filter). Saying that we can write those with loops is the same as saying we can write loop with jumps: true, but have a specialized construct makes the intent of the programmer a lot more clear.
- rjberry 12y agoIt's not really a different approach. You had to write a lot of vanilla loops in C, too.