5 ms·
One of Go's major features is that any particular function is very easy to reason about. The code is very straightforward, there's very little magic, and the c
by NateDad 13y ago
One of Go's major features is that any particular function is very easy to reason about. The code is very straightforward, there's very little magic, and the code usually does exactly what you expect it to do, even if you're not an expert in the language.
Rust seems nice, but its multitude of different pointers and mutable versus non-mutable data really makes for complicated code.
I work on Juju. It's over 200k lines of code spanning several applications that coordinate across multiple machines. The number of times generics would have helped the codebase I can count on a single hand... and none of it is huge stuff, just some very minor parts of the code.
- wyager 13y agoHow is go easier to reason about than competing languages?
- NateDad 13y agoFor one thing, it's just a simpler language. There are fewer keywords, there's only one kind of pointer (and no pointer arithmetic). Everything is just pass by value. There's very rarely anything going on "behind the scenes". The code does what it says it does. There aren't any dense one liners that do a whole bunch of stuff. Values are very easy to reason about. You know exactly how values will be initialized, how much memory they take to copy, when they'll be copied. There's no operator overloading, macros, or monkey patching, so you don't have to know about the entire state of the universe to know what one little function will do. There's no destructors or finalizers that magically get called sometime in the future. There's no exceptions, so you never have to worry that the control flow of your program is going to jump all over the place. There's multiple returns, so you almost never have null pointer exceptions, because you always just check the error before using the value returned. And of course, channels and goroutines make modern multithreaded code very easy to reason about, because they're just functions and a little pipe primitive. They don't do a lot of fancy schmancy stuff, and that's good. It means it's very easy to tell what go Foo() will do. There's probably more I can't think of right now.
- wyager 13y ago>For one thing, it's just a simpler language. In what way? It's not a very featureful language, but that doesn't necessarily mean that using it is simpler. It's certainly not simple to set up! Most languages, I can put my projects wherever I want. It took me a while to find out that I had to put my projects in my Gopath for them to properly compile with third party libraries. There are lots of weird restrictions like that. >Everything is just pass by value. Not entirely true. Goroutine capture is by reference, which is why a lot of new people have trouble with goroutines in for loops. >There's no operator overloading, macros, or monkey patching, so you don't have to know about the entire state of the universe to know what one little function will do. True, those things are gone, but the things that cause confusion most of the time are still very much present. Go, like most imperative languages, can suffer from global variable overload. Lots of Go code is also so badly typed that it's impossible to tell what things are supposed to be. I can't tell you how many times I've seen `x := poorlyNamedFunctionWTFIsThis()` or `foo(x {}interface){... x.bar()}` >There's no exceptions There are `panic()`s. > There's multiple returns, so you almost never have null pointer exceptions Rust also has multiple return (because Rust returns via hidden out-param), so I wouldn't really say this makes Go particularly competitive. Rust also doesn't even have null pointers at all, at least in `safe` code blocks. Rust uses `Option` instead. (Like I said, lots of good features from Haskell/ML.) >channels and goroutines make modern multithreaded code very easy to reason about I agree, Go does this well, but let's be fair; a lot of modern languages have primitives like this.
- kibwen 13y ago> Rust also has multiple return (because Rust returns via > hidden out-param) Not quite. Rust does have multiple returns, but that's just the obvious result of supporting tuples in the language (to say nothing of tagged unions). The hidden out-param you speak of is just there to guarantee return-value optimization, allowing the compiler to construct return values in higher stack frames to avoid the overhead of copying.
- wyager 13y ago>Rust does have multiple returns, but that's just the obvious result of supporting tuples in the language (to say nothing of tagged unions). Yes, but it's (from a user standpoint) practically the same thing! >The hidden out-param you speak of is just there to guarantee return-value optimization Yes, which allows for the efficient return of arbitrary-sized structs, i.e. multiple return.