Home All posts #go# simple# kiss

Go is a good programming language

When I started learning programming, I did it for fun and I didn't know how to make a lot of things well, I knew how to use databases, making e-commerces, business systems and discover libraries which only added weight to the project but I didn't know how to solve technical issues, until I learned C programming language, all changed, I mean, my mindset changed, how any problem can be solved in many simple ways, all with one ideology Keep it simple stupid and since that moment I kept all simple, yk studying computer science + thinking that "simple is better" it was wonderful, C was really a grateful experience.

C is not enough, but why? Well, nowadays the problem requires much more abstraction, and I hate it but that's the new world, so I need to avoid reinvent the wheel but without bloating the system and use the tools that the programming languages offer us, and a plenty of good solutions. I have worked with Java at least 2 years and also I used a wide variety of other langs and tools. But the last year I learned Go. OK, there are a lot of good programming languages, some good, some bad, but Go, Go is special. Why? Go is fun, Go is simple, Go is powerful. Go is amazing cuz it reminded to me that feeling when something is simple and you don't need anything more. Its standard lib, its ecosystem; dude it's really good. My friends love go too, and it motivated me to discover it.

I haven't done much with it on opensource projects (but ungo does btw), but I've had chance to try it out and do a lot of private projects (some for fun, others for my job), the ecosystem is good, its memory management system is lovely, man its awesome. You can use Go wherever you want, its performance is a huge advantage, its a simple language, the error handler is special, it forces you to manage errors and follow good practices.

Learning Go is really easy. But dont underestimate it, it's a simple language, but how to use it depends on you. The programming language is simply a tool to solve computer problems.

Resources I used to understand it

Compilation

Unlike other high level languages, go has to be converted in a binary through compilation process, like C. One of the advantages of this process is the go type checking so go has a strong static type checking because the compiler verifies that every data type/structure, variable, interface, function is strictly correct, then the dependency resolution imports only needed packages defined in go.mod doing that packages are compiled only when needed so build caching avoids recompiling unchanged code. The compiler compiles (that sounds hilarous haha) each package into object code performing several optimizations like dead code elimination, function inlining, escape analysis, and register allocation, then the linking process is performed and all compiled packages are linked into a single executable. Go by default produces statically linked binaries but dynamic linking is possible in some cases. All of this compilation process is too quickly because go was designed for fast builds using strategies like aggressive build caching and a efficient dependency graph traversal. All of this using cross-compilation, go has no problem building for different operating system or CPU architectures.

Memory

The go memory management is similar to other languages, I mean, go has a really good garbage collector system but before running it, an escape analysis process is executed to scan all memory objects and where they will be, so it decides whether each data will lives in stack or heap. About garbage collector, it is so simple that makes it pretty fast that is running in every moment, go makes this using a concurrent, tri color mark sweep algorithm read more here; this algorithm categorize all memory object as white (unvisited), grey (visited but children unvisited) or black (visited and active). So GC walks this object graph concurrently while the program is running.

Memory management experience

Pointers

The pointers are "Safe pointers" you can use it to avoid copying a massive piece of data or mutate a struct directly but you cant perform pointer arithmetic unless you import the unsafe package.

Slices

In go you'll never use raw arrays. You use slices. This isn't a dynamic container holding data. It's a tiny 24-byte header containing 3 things: a pointer to underlying array memory, the length of the elements and the capacity.

slice header example

Image from https://go.dev/blog/slices-intro

memory slice management

Image from https://go.dev/blog/slices-intro

Slicing does not copy the slice’s data. It creates a new slice value that points to the original array. This makes slice operations as efficient as manipulating array indices. (Slices intro, go.dev blog)

Concurrency and Memory

Go handles concurrency via Gorroutines and Channels, a standard OS thread takes up about 1MB memory for its stack, goroutines start whit a tiny 2KB stack, if a gorroutine needs more space, go dynamically grows the stack.

The channels are a smart idea to communicate goroutines sharing memory by communicating. I mean, instead of passing pointers around and protecting them with complex locks and mutexes, channels sends copies of data between goroutines.

Data races are a an inconvenient when you pass a pointer across a channel (or share a variable between goroutines), and one writes as long as another reads. You get a data race which can cause silent memory corruption. So Go includes a built in race detector using go test -race


Thank you for reading this post, I hope you try go and get the most out of it.