Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Also missing null safety in modern language is weird.


And enums.


You can point out flaws so it's not well designed? By this logic nothing is.

And pointing out missing features in a programming language is just about the weakest criticism possible.

Piling on lots of features is easy and fun. That's why almost all language designers do it. Most popular languages destroy themselves with features.

Rust is in the process of gaining every single feature anyone can imagine. Following C++ right off the complexity cliff.

Go is one of the very few languages to show incredible restraint in adding features because its designers understood the combinatorial complexity problem, among other things.

Not having unnecessary features is one of the best features of Go.


The issue with Enums is that the "unnecessary" feature means that people have to encode the behaviour with things that aren't suitable. E.g. creating a new type that's a thin wrapper over string or integer means it can be set as some non-valid value, even without some sort of explicit cast that says "I know I'm doing something that might fail". I don't see that that is an improvement over any other language. It's not simpler because, as people have shown by the examples trying to prove that you don't need it, they don't have all the (necessary) behaviour that enums do to prevent this sort of problem.


There are some useful features that Go really should add, and enums might be one of them, but lacking a useful feature doesn't mean its not well designed.

The results are in for Go. It's already one of the most successful programming languages in history any way you measure it.

Of course Go should continue to improve and add features where the value outweighs the increased complexity. That's how it eventually got generic functions and other features.


I very much agree. The fewer ways a programmer can become creative, the easier it is to fully understand their code.

In a business environment, this is a obvious win.


Especially when programmers are seen as cogs in the business machine.


The appeal of Go is that it has just the bare minimum feature set to be useful for modern backend engineering. It's a language that you can completely fit within your head within a few months of using it, as opposed to certain languages like C++ (or say C# to a lesser but increasing extent) that most will never know completely even after decades of working with it. It's basically the RISC of programming languages.

And if I had to guess, it doesn't have enums so that it can remain flexible when serializing/deserializing enum-like types over the wire. Imagine you can't parse an incoming payload containing an enum field because your service is one version older than the one that extended the enum type (or the enum type is defined in a package dep... you get the idea). Enums are actually a terrible idea now that I think about it.


> The appeal of Go is that it has just the bare minimum feature set to be useful for modern backend engineering. It's a language that you can completely fit within your head within a few months of

To me, golang symbolizes the shift of philosophy of Google as a company. It changed from "it's a smart nerd company for smart nerd people" to "golang will allow us to hire cheaper devs because golang will prevent them from making mistakes". I mean, this makes sense from business perspective, I won't deny this fact, but it's the programming equivalent of Ferrari making a SUV: tremendously profitable, but sad to see.

BTW

> golang doesn't support overloading because overloading is bad. Having said that, it's 'go', not 'golang', like the verb 'go', which already has a thousand meanings depending on the context

I find that hilarious


Disagree completely. I think by and large Go is a work of genius, the product of lifetimes of deep insight on programming languages and software development.

There are some "design-by-committee" weirdnesses, but if you squint a bit it's perfect.


The law of large numbers says that, the larger the organization, the closer to average the employees will be. Google had no chance of maintaining "a smart nerd company for smart nerd people" at the scale it grew to be.


Sad but true


> The appeal of Go is that it has just the bare minimum feature set to be useful for modern backend engineering

I know that many people love Go, and I respect that, but I was never able to grasp its appeal (despite my two-year stint as a professional Go programmer). To me, the philosophy of Go seems to prioritize simplicity in the language at the cost of making software written in it more complex. Writing in Go often felt like a constant exercise in haveing to reinvent even the simplest things.


I suspect you've only seen poorly written Go, which is actually quite pervasive. The most common sign of it is the overuse of interfaces. You basically shouldn't define your own interface unless you need to export functionality. Interfaces are not a tool for organizing your code. Go is meant to be written in a very linear and naïve way, and it turns out quite good when you just do that.


Maybe I'm missing something obvious but that seemed to be the only option for injecting stub implementations in integration tests.


I prefer the testing libraries that do monkey-patching and consider mock implementations of interfaces to be an antipattern in Go, especially if it's the only reason for putting an interface between the calling code and a type.


Interfaces are one way to inject stubs, and a good way, but not the only way. You can also use function values as callbacks.


In Go you can jump from your IDE into the http server implementation in 3 clicks, and you can read the code easily, it's vastly different from other modern languages that have layers of un-necessary abstraction.

I worked in Java / C# with tons of interfaces all over the place, getter / setter in every files.


That's just bad code, but it's not inherent in the language. You can write bad code in any language.


Within the 90 seconds of thought while writing a Hacker News post, he's discovered that decades of language design and type theory were actually a terrible idea now that he thinks about it.

One of the tools I work on in my spare time is a Poker calculator that uses enums extensively for things like suits and hand strengths (flush, full house, etc.). This program doesn't connect to the internet in any way. But I hadn't considered that someone might come along and force me to serialize these poker hands and send them over the wire and change the number of suits and ranks in a deck of cards so that it creates incompatibilities. I guess I should go back and rewrite my code to remove those enums, since that's going to be a problem.


Go actually has enums in the basic way that you're thinking of them, but they're just constants of a custom type based on int.

So you'd define `type Suit int` and have constants of type Suit that are `const DIAMONDS Suit = 0` ... `const SPADES Suit = 3`.

Go just doesn't have first-class enums with cardinality less than an int, like Java would. Which means you could have a Suit type variable with a value of 4 or 9000, because Suit serializes/deserializes as an int, not some custom string representation as in other languages.


For a language to be useful for modern backend engineering, I'd expect it to at least have proper enums and union types with pattern matching. Let alone features like structured concurrency, advanced observability, records, good error handling, etc.

The constant gotchas in golang indicate that it does not fit in people's heads within a few months.


It doesn't even have mmap in the standard library. Let alone setns and all this new stuff.


It was explicitly written to be used by people who couldn't be trusted to mmap


Even python can mmap.


Modern backend with yesterday's technology.


The appeal of Go is goroutine.


Java has virtual threads with better and safer ergonomics.


package main

import "fmt"

// Define an enumeration for status type Status int

const ( Pending Status = iota InProgress Completed Failed )

func (s Status) String() string { return [...]string{"Pending", "InProgress", "Completed", "Failed"}[s] }

func main() { var s Status = InProgress fmt.Println(s) // Output: InProgress }


I see this suggested all the time as though it’s supposed to be a replacement. It isn’t sufficient, it’s a poor emulation of what enums can be used for and doesn’t offer the same protections, since Status can be set to any integer value without casting or any knowledge that it’s broken.

In your suggested method it doesn’t even catch that case and provide an error if the value isn’t in the range.


It seems like none of the other comments here use or are even aware of `go generate`. Go has excellent code generation features [1].

I think parent should be using `stringer` [2] instead.

1: https://go.dev/blog/generate

2: https://pkg.go.dev/golang.org/x/tools/cmd/stringer


I'm well aware of Stringer but I don't again think it's a good replacement of having enums built in!


> I don't again think it's a good replacement of having enums built in!

I didn't say anything along those lines, in fact I was commenting generally about this issue that you guys and the other commenters mentioned.

I was just suggesting a solution to the the problem stated.


"We don't want a solution! We want to complain about what we are used to and dont have!"


Next day I have this (added one entry). I forgot to update the string list elsewhere however.

const ( Pending Status = iota InProgress Completed Cancelled Failed )

func (s Status) String() string { return [...]string{"Pending", "InProgress", "Completed", "Failed"}[s] }

func main() { var s Status = Cancelled fmt.Println(s) // Output: ??

If the compiler - not some linter - protests that the list of names is different from the number of items in the enum, then I think this is at least a half-decent design of an enum type. Not a great one (because the author still had to repeat the names), but at least something that isn't a fundamentally broken design of an enum type.

But if the compiler is silent, and the output of the Println(Cancelled) is "Failed" then I'm not angry, I'm disappointed.

Edit: https://go.dev/play/p/MMPMh7_U81-


OK, but I can set s to 1000, and it still compiles.


Also known as design hack, workaround for what other languages support natively since 1970's.

Only one step better than Assembly or Fortran.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: