Hacker News new | ask | show | jobs
by ploxiln 1511 days ago
Let's not pretend that some flagging of this article represents all or most developers who use Go, and also not pretend that this post represents all or most developers who use Rust.

What kinda gets me from this genre of post, is that it sounds like writing good software in any language besides Rust is impossible, or even impractical. Like 10 years ago it was impractical for anyone to enjoy writing good software. (Or maybe Haskell or Ocaml would be acceptable?)

I've written a fair bit of Go, lots of Python and C, lots of bash and posix sh ... and I've written good and reliable-for-purpose software in all these languages, and I've enjoyed it much of the time. (In college I also wrote a chess playing engine in java, a malloc implementation and a trivial unix-like OS kernel with fork and threads in C of course, also a mips and z80 cpu implementation in verilog for fpga ... does that make me a "blub" programmer?)

Is it really an unacceptable flaw to have a program that only works with printable paths, and only makes sense to run on one's own files? Or which runs fine on both unix and windows, but doesn't do anything with file permissions? Or which only operates on file permissions on unix, but only runs on our servers and VMs?

I like high quality software, I really do. But I think that people writing these blog posts want something more, something impossibly pure. They want a messiah, and if everyone just believed, the world would be perfect. I like high quality software which has been possible and practical for 20+ years.

2 comments

I didn't get that desire for purity that you gleaned from it.

The fact is that (as the author pointed out) Golang is missing basic language features that other languages have adopted since the creation of C that eliminate whole classes of errors, and it's pretty easy to accidentally do the wrong thing as a result.

Nil pointer exceptions, for example, don't have to exist anymore.. and yet they do in Go because they couldn't be bothered to add sum types. Its type system is barely a step above a dynamic language. You have to write the same imperative looping code over and over because Rob Pike would rather just use a for loop than something mildly expressive like map or filter (https://github.com/robpike/filter). Every function that does meaningful work is littered with if err != nil { return err }. Etc.

It is easy to write code in Go, but IMO it's not easy to write and maintain a production grade system with any amount of complexity in Go because you _have_ to be careful, you can't encode invariants explicitly and let the compiler find problems for you, and you have to repeat yourself so often.

> I didn't get that desire for purity that you gleaned from it.

'Folks who develop an allergic reaction to "big balls of mutable state without sum types" tend to gravitate towards languages that gives them control over mutability, lifetimes, and lets them build abstractions.'

This mutability argument is present throughout the article. Seems like nothing sans Rust or niche functional languages is enough.

> Nil pointer exceptions, for example, don't have to exist anymore..

The language most notorious for those is Java due to almost everything being passed via a nullable reference. When everything can be nullable, how can you know where to check for it? Go addresses this to an extent by explicitly separating pointers from values. Values are the default and cannot be nil, so the opportunity for null dereferences is greatly diminished. It's not a perfect solution, but it's not nothing either.

> and yet they do in Go because they couldn't be bothered to add sum types.

Damn those lazy Go devs!

> Its type system is barely a step above a dynamic language.

Turns out even a basic type system is a huge improvement over none. Just being able to restrict values to concrete types goes a long way.

> You have to write the same imperative looping code over and over because Rob Pike would rather just use a for loop than something mildly expressive like map or filter (https://github.com/robpike/filter).

There are arguments to be made either way, but I definitely agree generics (along with iterators) should have been there since day 1.

> Every function that does meaningful work is littered with if err != nil { return err }.

One big positive of this that I don't see in other languages is every `return` in a function must be on the start of a line. That is, every single exit path of a function is easily findable by visually scanning the start of each line for `return`.

> you can't encode invariants explicitly

I'm curious, are there any limitations here besides enums/sum types?

> What kinda gets me from this genre of post, is that it sounds like writing good software in any language besides Rust is impossible, or even impractical. Like 10 years ago it was impractical for anyone to enjoy writing good software. (Or maybe Haskell or Ocaml would be acceptable?)

I think what we are seeing here is that the expectations are growing and people demand more from their tools.

This is a good thing, even if some languages cannot keep up with the higher standards and fall behind.