Live data from Hacker News

Why Go Is Not Good (2014)

yager.io

61–70 of 466 posts

Re: Why Go Is Not Good (2014)

#61

Earlier quoted context omitted.

What do you think about goroutines and channels?

Using go for goroutines and channels is a bit like using Perl for regular expressions. The features have been added in a way that makes them easy to use and serves as a nice idiomatic platform, but fundamentally it's functionality other languages can provide via library support.

+1 on this. Clojure's core.async[0] is the perfect example of an implementation of CSP as a library.

Even JS can be used to implement such concepts via the use of generators[1].

[0] https://github.com/clojure/core.async

[1] https://github.com/ubolonton/js-csp

Re: Why Go Is Not Good (2014)

#62
post #12

I like this article and I agree with most of what was said there. Against that type of point-by-point criticism, fans of a language will usually use the argument: "but that language was not designed for that!". Then the question becomes: What was that language designed for? My impression was that Go was meant to be a slightly higher-level systems language with better constructs for concurrent programming. With that i…

Argument "that language was not designed for that!" is valid almost anytime anyone tries to criticize a programming language. Go was designed within Google for Google. Where your system has millions of lines of code and thousands of developers work on them constantly. So they thought about three things: compilation speed, memory management and concurrency. Go compiles fast, so you can iterate quickly. This requires giving up most of the compilation safety checks. They can be done by static analysis tools in parallel. Explicit memory management means, you can sometimes optimize this 0.05% memory on your program. This means a lot, when you run your code on million machines. Concurrency isn't hard in Go, but explicit memory management makes it harder than in Erlang for example (in Erlang, you have "share nothing" policy). Go is also very simple, so one developer won't be surprised by other developer using some obscure feature.

That being said. I wouldn't recommend using Go outside of Google, Facebook or Microsoft. It solves problems, that companies and developers usually don't have. If you need always running and quickly evolving software - there is Erlang and Elixir. If you need guarantees on correctness, use static typing from Haskell. If you can resign from some guarantees to have grater control on memory, there is Rust. If you are writing in browser, there is Elm. If you want to easily transition from OO to functional programming - try Scala. If you need to prototype app for your startup quickly - there is Ruby.

Every popular language has its purpose and its trade-offs. Rust isn't strictly better than Go, but with high probability, it is better than Go for your problem.

Re: Why Go Is Not Good (2014)

#63

Earlier quoted context omitted.

I think we're talking about different things. Can you give an example of how operator overloading improves one's ability to write a function that can be specialized on types that weren't specifically designed for such use?

Type 1 defines: .add(x) Type 2 defines: .plus(x) Type 3 defines: .vector_add(x) Now, implement a function 'average' that can work on any of these three types. If you can get everyone in the world to agree to a convention of how to express 'addition', then there is no difference, except we already have a convention for 500 years, and it is the '+' operator. Why you think the '+' operator is confusing but .plus() is no…

> Now, implement a function 'average' that can work on any of these three types.

I'm not convinced this is such a large problem that its solution is worth the myriad downsides that operator overloading is chained to. There's lots of schoolbook examples like this, but I've almost never seen operator overloading used well in practice. There's a few examples, like boost shared pointers are somewhat easier to read, but they're few and far between

Re: Why Go Is Not Good (2014)

#64

Earlier quoted context omitted.

I think we're talking about different things. Can you give an example of how operator overloading improves one's ability to write a function that can be specialized on types that weren't specifically designed for such use?

Type 1 defines: .add(x) Type 2 defines: .plus(x) Type 3 defines: .vector_add(x) Now, implement a function 'average' that can work on any of these three types. If you can get everyone in the world to agree to a convention of how to express 'addition', then there is no difference, except we already have a convention for 500 years, and it is the '+' operator. Why you think the '+' operator is confusing but .plus() is no…

At this point, operator overloading would simply be another convention, would it not? Your type would not work with mine if I used .add instead. You did not solve the problem of having to get everyone to agree on a convention.

Re: Why Go Is Not Good (2014)

#65
post #38

"Go does not support operator overloading or keyword extensibility." Very much working as intended, I believe. Experience from languages that support those features has shown that what we gain in the very few situations where those extensions make sense (such as defining mathematical operations on vectors using the same symbols that are used in vector mathematics), we lose in too many developers thinking they have a…

This is a well-written objection and I completely agree. Operator overloading is consistently one of the worst ideas I see in programming languages, C++ being the prime offender. Programmers think they're being clever when they write crap like boostfs::path path("/some/path"); path /= "yourfile.txt"; Meanwhile, reading your code without being familiar with boostfs::path, my brain grinds to a halt while I try to under…

> Operator overloading is consistently one of the worst ideas I see in programming languages

Except when not having it is the worst. Working with BigDecimal in Java is hell because it does not have operative overloading, meaning while you avoid

    boostfs::path path("/some/path");
    path /= "yourfile.txt";
you get saddled with bullshit like

    x.add(x.add(ONE).pow(2).subtract(x))

Re: Why Go Is Not Good (2014)

#66

Earlier quoted context omitted.

I think we're talking about different things. Can you give an example of how operator overloading improves one's ability to write a function that can be specialized on types that weren't specifically designed for such use?

Type 1 defines: .add(x) Type 2 defines: .plus(x) Type 3 defines: .vector_add(x) Now, implement a function 'average' that can work on any of these three types. If you can get everyone in the world to agree to a convention of how to express 'addition', then there is no difference, except we already have a convention for 500 years, and it is the '+' operator. Why you think the '+' operator is confusing but .plus() is no…

Ah, I see what you mean. You can see this issue in action in Go's math package, where "Min" is defined on only float64.

I was lumping this in under the general category of the "Go has no generics" issue; without generics, Go can't do this anyway (and the closest solution you would have would be to define an interface Algebraic that specifies functions algebraic types need to support, then implement operations like min and average atop those interfaces). I'm still of the personal opinion that (as other commenters noted) what you gain in being able to define operator+ you lose in boost developers getting clever and implementing operator/= on paths; even if we had generics, I'd personally find a Go-like solution of declaring the function package an algebraic type had to support (via an Interface) preferable.

Re: Why Go Is Not Good (2014)

#67

Earlier quoted context omitted.

I think we're talking about different things. Can you give an example of how operator overloading improves one's ability to write a function that can be specialized on types that weren't specifically designed for such use?

Type 1 defines: .add(x) Type 2 defines: .plus(x) Type 3 defines: .vector_add(x) Now, implement a function 'average' that can work on any of these three types. If you can get everyone in the world to agree to a convention of how to express 'addition', then there is no difference, except we already have a convention for 500 years, and it is the '+' operator. Why you think the '+' operator is confusing but .plus() is no…

operator overloading is just overriding a base class (interface), plus a special and aribtrary limited syntax, plus compiler optimizations.

Re: Why Go Is Not Good (2014)

#68
post #41

Earlier quoted context omitted.

>> Experience from languages that support those features has shown that what we gain in the very few situations where those extensions make sense Nope, this is just incorrect. The C++ is completely dominant in large swaths of the software industry largely because operator overloading allows the writing of generic algorithms (which allows you to write large scale software without losing C-like performance). Without op…

Could you go into more detail about why operator overloading enables generic functions in a way simple functions don't? I don't see it.

Without operator overloading, it's hard to make generic numeric algorithms palatable.

Compare (fake Go-with-Swift-generics syntax):

    func Distance(x N, y N) N where N Number {
        return x.Mul(x).Add(y.Mul(y)).Sqrt()
    }
Versus:

    func Distance(x N, y N) N where N Number {
        return Sqrt(x * x + y * y)
    }
If your reaction is "well, Distance doesn't look too bad like that", I can replace it with matrix multiplication or point-inside-triangle testing. Not having overloading quickly fails to scale.

Re: Why Go Is Not Good (2014)

#69
post #38

Earlier quoted context omitted.

This is a well-written objection and I completely agree. Operator overloading is consistently one of the worst ideas I see in programming languages, C++ being the prime offender. Programmers think they're being clever when they write crap like boostfs::path path("/some/path"); path /= "yourfile.txt"; Meanwhile, reading your code without being familiar with boostfs::path, my brain grinds to a halt while I try to under…

> Operator overloading is consistently one of the worst ideas I see in programming languages Except when not having it is the worst. Working with BigDecimal in Java is hell because it does not have operative overloading, meaning while you avoid boostfs::path path("/some/path"); path /= "yourfile.txt"; you get saddled with bullshit like x.add(x.add(ONE).pow(2).subtract(x))

Eh, there's already no language symbols for exponentiation (unless you're really going to overload XOR in which case you're already part of the problem).

Re: Why Go Is Not Good (2014)

#70

My essential issue with Go is how much it feels like cargo cult language design. Compared to other emerging languages [Rust, Clojure, Elixir, Julia...], it feels inconsistent, half-baked, uncertain what it's for or where it's going.

Cargo cult, copying what? Go is the evolution of a design that was started before any of those other languages were dreamed up.
Post reply on HN