Hacker News new | ask | show | jobs
by jchw 2446 days ago
> or making the language unacceptably crippled like Go

Gotta say, I lost a lot of respect for the author at this point. It’s not like I don’t love Rust - quite the contrary - but if the only takeaway from Go for you is that it is “unacceptably crippled” then I feel you have missed a lot of insight. Go has been one of my languages of choice for over half a decade now, and for good reason.

7 comments

> > or making the language unacceptably crippled like Go

> ... if the only takeaway from Go for you is that it is “unacceptably crippled” then I feel you have missed a lot of insight.

Perhaps the author used a poor choice of words and instead could have phrased their intent along the lines of:

Go lacks the semantic density needed to express solutions in both a concise and consistent manner.

Were this the case, it would be hard to disagree as Go does, indeed, lack linguistic capabilities present in other programming languages which enable developers to encode system constraints within the language itself. Some might see this as a benefit, but I do not. YMMV.

A similar philosophy of "keep the language dirt-simple so anyone can code in it" was a driving force behind Java (the language) and JavaScript. What people have discovered is that when a programming language does not assist in expressing intrinsic problem complexity explicitly, it becomes implicitly intertwined within the source itself.

I think it's a syntax problem. ASCII doesn't have enough bracket characters to simply & clearly represent necessary language features. So it's harder for an intelligent human to sort and categorize these aspects.

Pre-generics Java is about the appropriate amount of language complexity for our current lingua franca

> Pre-generics Java is about the appropriate amount of language complexity for our current lingua franca

I am not sure to whom you are referencing as being "our", so I can only say I disagree as there are many developers which are quite adept in languages having more complexity than "pre-generics Java."

Perhaps you meant to reply to a different comment?

It surely isn't mine, otherwise I wouldn't be happily using Java 13 right now.

Also even Google does have more stuff going on Java, C++, Dart, Kotlin and TypeScript than Go, which has more uptake outside Googleplex.

Java is tolerably mediocre now but vintage 1996 Java was awful (and slow). I enjoy Scala, but even I can see why it's more than most of the industry is ready for. If there's a sweet spot, Kotlin seems close to it.
Err, we had 10x times the features of "Pre-generics Java" even in 1970s Lisp and Smalltalk...
I will gladly trade a little bit more language complexity if it means the complexity of the code that I write using that language is simpler.
This. When a platform refuses to solve a problem, that problem doesn't go away. The users are forced to roll their own solutions, none of which have the same test coverage and optimization opportunities.
Generics don't make Java that much more complex for your workaday Java coding.
Speak for yourself.
> Go lacks the semantic density needed to express solutions in both a concise and consistent manner.

That is a difficult statement for a Go user to parse.

It is referring to a lack of language features that result in verbosity or boilerplate?

There's a lack of language features that result in verbosity, boilerplate, less performance and/or less type safety.
It may be an unnecessary dig, but the author may indeed be familiar with Go and still think it's unacceptably crippled for all their use cases. The whole post is just their opinion.
In my anecdotal experience, the type of programmers that evangelize and talk shit about programming languages tend to be on the less informed side of the knowledge spectrum.
I occasionally program Go because it has an amazing amount of libraries - I basically use it for random microservice type things that glue systems together. (Most recently, an HTTP login endpoint that sends and receives XMPP messages to authenticate the user.)

I don't like it. I program Rust the rest of the time. I'm considering learning Perl5 so that at least my type system lets me do vaguely expressive things - I'm utterly fed up of half my code looking like:

    foo, err := something()
    if err != nil {
        return nil, someErr{err}
    }
I got very used to Rust's try!() macro, now ? operator, and being able to map over Results to convert between error types in a single line that feels much less noisy - I have functions in Go that are a dozen or so lines that would've been 3 in Rust, and tbh I struggle to follow what the function actually does when 3 out of 4 lines are to do with the failure case.

I would consider "unacceptably crippled" to be a reasonable description of Go, even if it's the best tool I have for some jobs.

"unacceptably crippled" is a pejorative meant to insult, not a descriptive criticism.
> In my anecdotal experience, the type of programmers that evangelize and talk shit about programming languages tend to be on the less informed side of the knowledge spectrum.

Or maybe they have just expanded their "knowledge spectrum" and are experiencing an effusive moment?

Talking shit isn't effusive. It's possible to enjoy a programming language without openly denigrating others you regard as inferior.
It's apparent you have dealt with negative situations such as you describe. Here is a haiku which may be helpful:

  Those who can will do,
  Those who cannot will seek to,
  Hide that fact from you.
HTH
> Talking shit isn't effusive. It's possible to enjoy a programming language without openly denigrating others you regard as inferior.

Both points you make I agree with. I simply was offering a possible explanation for those whom exhibit overly passionate opinions when they become enlightened.

When people take an epiphany to the point of denigrating those around them, then they likely have issues beyond what any programming philosophy could possibly encode.

Sure, and my opinion is that this is a very shallow takeaway. My whole comment is just my opinion.
> if the only takeaway from Go for you is that it is “unacceptably crippled” then I feel you have missed a lot of insight.

Um, the whole point of Go was to be "opinionated and acceptably crippled". That's why the creators built it the way they did. Go has more than a few things where "Me, but not for thee" rules--the compiler can do X but you cannot. If you find that is an acceptable tradeoff for the other features of Go, great!

Lots of modern languages, however, are trying to go the other way. They are trying to give the programmer every bit of power that the library/compiler programmers have. This has its own failure modes that you may find unacceptable. That's fine too.

I personally dislike the Rust vs Go discussions. Those two languages in particular really don't have domain overlap and are like comparing apples to screws.

Minor nit: would've been better if you'd put 'screws and apples'. 'Rusty screws' and 'Go apples!' sound better then when interchanged :P
It is crippled admittedly by the authors themselves. The error checking pattern, no generics etc. are all to keep it "simple" yet are things most other programming languages have. Have you used Rust ? The borrow checker makes a lot of sense.
I feel like I shouldn’t have to answer this question, but Yes, of course I’ve used Rust. Why do you question this? I said nothing about Rust at all, other than that I like it, and whether Rust is good or not has little to do with Go being “crippled.”

But of course, Rust is not flawless. In fact up until recently it was kind of annoying, before non-lexical lifetimes became a part of the language. It’s also a very large and complex language compared to Go. This is not unilaterally a bad thing, but just as every line of code comes at a cost, so to does every language feature, and if enough language features fail to pay the rent your programming language will end up feeling bloated.

What Go lacks is exactly its strengths. If you criticize C for not having Java-style exceptions, people will look at you funny. There is some divide in the community over error handling but I defend that Go’s verbose and stupid error handling pattern is my favorite part of the language, and changed how I code inside and outside of Go. I also appreciate Go’s simple but effective patterns for composition-based object oriented programming, and for having a decent concurrency model (not that it is without flaws: the limitation of Go’s memory safety is definitely an issue here.)

Everything comes at a cost. The borrow checker brings immense promise for security, but that does not mean other approaches to memory safety or language design are suddenly obsolete. It’s more complicated than that, and I consider failure to understand this to be a sign that someone is not keeping an open mind.

>>What Go lacks is exactly its strengths.

Surely you understand that this is a very self-serving attitude, though?

It's like someone points out that your car is crippled because it has a turning radius of 2 degrees and also has no brakes, and you go, "no but you see, what this car lacks is exactly its strengths! And it's those strengths that I enjoy the most when driving this car!"

“Crippled” has a negative connotation. I’d say it is not crippled but kept self-contained without a multitude of overlapping features.
I work with Rust only these days, it’s really an awesome language and I wish everyone working with system languages would switch to Rust. Yet, I find Golang to be a much clearer language to read (and I read a shit ton of code). I hope they don’t add generics, but I wish they would options, results, sum types in general, redeclaring variables, the ? Operator, etc.
Interesting, I've been reading a lot of Golang of late as we move into k8s world, and I find it hard to read, mainly in terms of package layout - types and their related functions are often in very different places.

But it's certainly less semantically dense compared to Rust or Scala etc.

I doubt that any genetic syntax will significantly impact go readability. The only syntax overhead will be in type definitions, not in type usage, and the later is present a lot more than the former. Couple that with the current need to add extra type assertion on type usage, and you may be looking at overall readability improvement
How would Option<T>, Result<T, E>, and sum types work without generics?
Native support is the answer.
Empty interface perhaps.
Crippled is a good way of describing "use a map[T]struct{} when you need a set of T" in my mind.
Regardless of the merit of his criticism, it clearly derails the whole discussion about this blog post, which was just about a cool feature of Rust.
Go is a fine GC language - in many ways, it's a lot better than the likes of Java! But it's nonetheless way too clunky for many use cases, which is what the OP may have meant by their remark. And the concurrency support comes with a lot of nasty pitfalls, especially compared to Rust or even Pony.
Rust was born as a critique towards C and C++ and putting down other languages is part of the community DNA.

Go is a favorite target, but Python, Ada, Java, C# etc didn't remain unscathed either.