Hacker News new | ask | show | jobs
by hsn915 1734 days ago
I regularly write Go code and I mostly enjoy programming in the language, but this post captures nothing important about what makes writing code in Go pleasurable.

Having biultin library features is nice but is not the reason. Python also has a lot of builtin library features, but I don't enjoy working with it.

Static typing matters a great deal, but Java is also statically typed yet I don't enjoy working with it.

For me I think what makes Go pleasurable to write in is that it has structs with value semantics and it also has pointers, and it also has none of the recent (incorrectly labeled "modern") ideas such as enfoced null-checking or enforced error handling.

I can write the code in a very direct and straight forward way. I can decide myself how much abstraction to introduce. I can decide myself which errors are worth handling and which are not.

I can write functions that take complicated arguments as structs without worrying about how it will degrade performance. Because structs have value semantics, creating an instance of a struct will not trigger a heap allocation unless you return a pointer to it or let it escape the current scope via other means.

This matters a lot because a lot of performance degradation in other languages comes not only from being interpreted but from the model of programming that requires lots of tiny allocation.

Another thing that makes go pleasurable is that a package is well defined and you can import packages written by other people. But that's only secondary IMO.

Go's performance is reasonable but it's far from C/C++ level. I think a well written server in C/C++ can outperform a go webserver by a factor of 10. That said, Go is about 40x faster than Python so that's great, and it means you can write a program in Go and run it on a single machine to get the same performance to a website written in Python and hosted on 40 web servers with an insane infrastructure and requires an entire team to manage.

That said, the language also has some warts, such as lack of real typed enums that can be introspected. For example, there's currently no way to dynamically introspect an enum type and find out all the defined values/constants. You must resort to code generation.

Also the lack of generics, but hopefully those will land soon (within a year from now, if nothing goes wrong).

But, what the language lacks in features, it compensates for in tooling.

No where else have I seen a language that makes it such a breeze to cross compile. I can write code on my macbook and compile it for linux to get a valid linux executable binary that I can then `scp` to a server and have it running right away.

The compiler speed is not the greatest but it's reasonable compared to pretty much everything else out there.

2 comments

I'm always slightly confused by the language speed comparisons for I/O heavy applications like networked services. On the one side you are taking in, for example, HTTP requests, on the other you are talking to a database, maybe some other networked APIs. A caching layer picks up plenty of load - how often is the program really cpu-bound here?

For me fastAPI [0] and async Python call the performance statements into question; good to run some benchmarks with real world use cases

[0] https://fastapi.tiangolo.com/async/

In my experience, the performance of carefully written Go is not far from the performance of C. Perhaps between a factor of 1.5x and 2x slower, if that. Otherwise, I agree with your comments.
Carefully written Go vs uncarefully written C? Sure.

Carefully written Go vs carefully written C? I still think C would win by a factor of 10.

Like I said, most slowness comes from memory access and fragmentation. In C you can use strategies like arena allocations. In Go you cannot turn of the GC.

If you want to build a custom allocator (use freelists and vectors of types) you can do all of that in Go and C. There's nothing stopping you from writing custom memory allocators in Go.