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

In the end people realize you can actually build things up without paying this complexity tax with simpler languages. This is why languages like Go succeed.

Of course, you pay the tax somewhere else and that is code duplication. You see this in Go due to the lack of generics, which often results in duplication of code for different types or reliance on reflection (which is slower and can lead to runtime errors).

This is not a critique of Go, just to point out that it is a trade-off, and there isn't necessarily one right answer.



This exactly what I mean when I say that people underestimate simplicity and overestimate features. Yes, generics are a nice feature. Yes they help you to avoid code duplication. Yet, not having them is not a stopper at all. Programs are shipped without generics. Code bases remain clean enough without them. On the other hand, every time I read a generic function in C# or Java I feel I have to double think everything. That's the price of of adding an abstraction layer.

Don't get me wrong, I like generics. I think they would be a nice addition to Go. But I understand Go designers when they try to be conservative about it. I like that they only add features when it's absolutely obvious that the pros overcome the cons.


But that is so rarely an issue... You might encounter an occasional specific circumstance where you will need do some code duplication in Go, but I've written many thousands of lines of Go and have had to resort to duplicated code once (and in that particular case all that required was a couple copy-pastes and minor edits, and I'd have to go back and revisit it but it's possible I could have solved it more elegantly if I'd known Go better).


But that is so rarely an issue...

For you...

It depends on what kind of code you are working on. If you work a lot on numeric code (e.g. in machine learning), you want to make it easy to specialize on e.g. 32-bit or 64-bit floats.

Also, since only built-in types are generic, you cannot implement other containers (you never need binary search trees?) in a safe manner.

So, yes, the lack of generics is a frequent issue for me.


Yes, and that does not conflict with what I was saying. There are specific problem domains where generics would simplify matters, but in the overall universe of problems those domains are rare, i.e., most of the code that most programmers will write in Go will not involve duplicating code because of the absence of generics.


I think you slipped in a subtle but annoying mistruth here: "in the overall universe of problems those domains are rare" is just not true. What is true is that the kinds of programs Go programmers typically write may end up not needing this sort of polymorphism, which is very different from saying "domains where this sort of polymorphism is important are rare".

I only point this out because I've seen a lot of Go programmers defend Go by saying parametric polymorphism is only really important in particular niche domains, when really they want to say that Go only focuses on a particular niche domain where it isn't important.


I can't remember the last non-trivial c++ program I wrote that I didn't use generic containers like std::vector or std::unordered_set, or the last java program where I didn't use List.


Yeah, but aside from the singular issue of generics (which are not exactly cutting edge), I can't think of a single 'advanced' feature that would add nearly enough utility to pay for its additional complexity. Everyone who shows up complaining about how it isn't "moving forward" by embracing features of high complexity and dubious utility is really missing the point IMO.


What about sum types (discriminated unions)? Sounds like that would help make error handling a lot safer and easier.


How do sum types make error handling safer (without also adding exhaustive pattern matching) or easier (without adding do notation or macros)?

The point I am trying to make is that adding some features from other languages doesn't provide sufficient value without also adding other features. Adding all of them can make the language significantly more complex that you wonder whether the benefits gained are worth it.


The problem with omitting language features like this is that the programmer is then forced to implement them by hand in an error-prone way. It's the same issue with Python and tail call optimization. Guido refuses to implement tail call optimization, so the programmer has to implement it herself in terms of a loop. Go refuses to implement sum types, so programmers code them up by hand. In neither case is the code actually clearer.

Since proper error-checking in Go actually requires doing by hand what a pattern match would have done anyway you're not simplifying anything for anyone by omitting them; you're just making it harder for the compiler to provide compile-time checks.

A pattern match is basically a switch statement. Go already provides the latter so the language would not need to become more complicated.


Well, they're really missing the point of Go.

It's fine for languages to embrace those features, and be what they are, and it's fine for Go to reject those features, and be what it is. We don't need "one language to rule them all".



My low content response is that you are brutally correct.




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

Search: