I often wonder if one of the reasons Go is more "simple" or approachable to some is because you can, to a large extent, ignore pointers and interfaces and "just write that weird little * or & in some places" and get away with it. Whereas, I believe in other languages, this is much less possible (e.g. in Java or Rust you need to learn about less "just logic" traits of the language earlier on (class inheritance, generics or Options, borrow checking, etc.)
I'm not saying the above is a good thing, but I often wonder if there aren't ways to make this more of an incremental learning curve in other languages in a similar way that you can largely ignore pointers in Go for a long time and be productive without understanding them. What would a similar incremental learning curve for generics be?
Slices are hard to grasp, you can modify them within a function (without ever touching that weird little * and his & cousin) and they are still modified when you exit the function, but you can't do that with other values (all of them need the star operator if you want to modify them).
Plus, appending a value to the end of a slice is very cumbersome and unusual with something like
arr = append(arr, val)
Oh, and do you remember when i said you could modify slices within functions and they are still modified in the end? This is not true with append. If you append to a slice, the new values won't be appended when you return from the function.This thing doesn't really make sense unless you've been a C programmer in fact, and understand the concept of fixed-size arrays and reallocating memory to grow them. Otherwise, even if you can work around that weird part, it will always seem a little magical and tricky.
type Foo struct { ... }
func (f *Foo) Bar() { ... }
And go "Aha, that's an object and a method, I get it!" but when asked whether they should be using a pointer there or not, have no idea what that even entails.In other words, it's possible to neglect the details of pointers easily and have things generally work
#!/bin/bash
cd $HOME
# Create project directory
mkdir hellogo
cd hellogo
# Init project modfile
go mod init example.com/hellogo
# Create the main source file
# Uses bash's heredoc
cat << EOF > ./main.go
package main
import "fmt"
func main() {
fmt.Print("Hello world")
}
EOF
# Build it
go build
# Run it
./hellogoThen, go get -v will download your dependencies to GOPATH, and (re)generate go.mod, go.sum. For info on how to update dependencies, read `go help get`.
When using modules (presence of a valid go.mod file), GOPATH won't be used for resolving imports. So you don't have to actually work in GOPATH anymore, dependencies are just stored there.
Go's main advantage, IMO, is that is both simple and opinionated to the extreme. It's a language that makes a lot of choices for you (from "no while loop" through "no exceptions" to where the brackets go formatting the file). Those choices might be the best choice or not, but the point is that they're already made and they're enforced.
The result is that in a big company, all projects made in go are very similar to each other in a lot of ways (much more than the average language) and so it is as easy as possible to have people contributing in each other's projects or moving between teams. There's no arcane syntax, no discussion about linters, nothing like that.
It's basically an amazing language to make programmers interchangeable. Whether that's good or not is a different discussion, but at the very least it looks that it's gonna make it very attractive for employers and so be a highly demanded skill in the near future.
My main quip with Go is that its rather more of the same but more poorly done in the name of minimalism. Extreme minimalism is as bad as extreme richness. The entire art of language design is achieving just the right balance for a specific audience and set of goals.
It purposefully leaves out lots of features and cutting edge design philosophies because many Of those make things difficult when sharing code between multiple developers Spread over a long length of time.
Go’s philosophy has always been close to KISS. Don’t provide all these cutting edge tricks and tips because you can accomplish the same thing in a far clearer and maintainable way by doing it simpler.
They certainly got some things wrong (null for example, and errors aren't great, generic collections would be nice), but it's quite interesting just how much they left out while making a very usable (IMO) language.
I don't want advances and progress in a programming language, I want it to get out of the way and let me think.
It will then run way faster and be completely bug free.