Live data from Hacker News

Why Go Is Not Good

yager.io

251–260 of 367 posts

Re: Why Go Is Not Good

#251
post #159

Earlier quoted context omitted.

To understand a language, one must know what problem it was designed to solve. It isn't always obvious, or what it initially looks like it was designed to solve, or even what the community thinks it was designed to solve. Erlang, for instance, isn't about concurrency. It's about reliability. Go, I think, is also not about concurrency. It's about building a language that can be sanely used by reasonably large groups o…

I have the same line of thinking as you do.. is the difference in use something you like and can work, and choose something you can use in a bigger group.. HN crowd are top smart.. things like Rust and Haskell are a breeze for people here.. but this is not the reality of the tech field.. the majority of people i know in tech, cant handle more powerful languages.. its too much for them In the end is just that.. know h…

Rust and Haskell are made to reduce the amount of problems you have.

I've seen newbie programmers learn Haskell as a first language in under a term. So I don't believe the marketing from the Google people that their language is worse because it is simpler.

Choosing something because marketing told you it was easier is just as silly as choosing something because of ego. Calling people egoists when they choose a tool because of reasoned arguments based on evidence is simply anti-intellectual, and rude.

Re: Why Go Is Not Good

#252
post #202

Earlier quoted context omitted.

I recommend Dijkstra's paper: "On the foolishness of "natural language programming" [1]. It explains how natural language is a very poor way to express programs, and how it held back science and progress for many centuries. Strong types describe your code precisely. If your code doesn't match the model yet, that's fine. But your code has invariants in it. Things like: "this variable can never be nil, that variable ca…

> It explains how natural language is a very poor way to express programs, and how it held back science and progress for many centuries. I'm not interested in using natural language to implement the software (write code). I'm interested in using natural/technical language to create an ontology for the architecture. This is where things get gray. When I think of an architecture, I think of something that evolves over…

> I usually use guard clauses to protect against nulls.

An interesting (to me) insight was that in a language with a flexible type system, the types are effectively just a set of assertions at the start and return of every function, that say that the inputs and outputs have certain properties. With a compact syntax and zero runtime overhead, which is nice.

I do think that some strongly typed languages make it too difficult to step outside the type system; in Scala I have to do something like (x.asInstanceOf[{def foo(): String}]).foo() whereas in Python I can just write x.foo(). But once I started seeing the type system not as a fixed piece of the language but as a framework for encoding my own assertions, it became useful enough that I can't stand to live without it.

Re: Why Go Is Not Good

#253
post #188

We've seen this same article re-written countless ways. Seriously, this is (intentionally or not) a rewording of every existing criticism of Go, by people who complain that it isn't a language that it isn't. No, Go's solution to generics is not interface{}. The moment you say that, you have lost . You are trying to fight Go and make it a language that it is not. Always remarkable that such critiques always focus on t…

Haskell makes Go's concurrency and composition look primitive and restrictive while also giving you safer code with generics. This isn't an area that Go wins at unless you're comparing it with C, not anything modern. The lack of generics is also not a primitive issue, neither is the ease at which people can write unsafe code. You can write as unsafe code as you like in Haskell, but the pat5h of least resistance also…

Haskell uses less code to do the same thing.

Haskell holds your hand and checks more things for you.

Haskell code runs from two times, to five times faster for CPU based code, and lets you scale to insanely higher concurrent workload in a safer way.

Why Go? Because marketing.

Re: Why Go Is Not Good

#254

Earlier quoted context omitted.

Lack of generics is part of the reason why Go is easier to learn and the Go compiler is faster than, say, Rust. Sure, generics don't have runtime overhead in Rust and Haskell but they have other costs. You always pay for abstractions some way.

> Lack of generics is part of the reason why…the Go compiler is faster than, say, Rust. The speed of the Rust compiler has little to do with generics and everything to do with LLVM and its optimizations and code generation. (Run with -Z time-passes if you don't believe me.)

I don't know if it has to do with generics, but you can't blame it on LLVM.

    /usr/src/rust/src/libsyntax % time /usr/src/rust/x/x86_64-apple-darwin/stage2/bin/rustc lib.rs -o /tmp/x.dylib --crate-type dylib -C prefer-dynamic -Z time-passes
    [most output removed...]
    time: 6.186 s	type checking
    time: 5.084 s	translation
    time: 7.221 s	LLVM passes
    /usr/src/rust/x/x86_64-apple-darwin/stage2/bin/rustc lib.rs -o /tmp/x.dylib    22.44s user 0.76s system 99% cpu 23.301 total
First of all: no more than 1/3 to 1/2 of the time is spent in LLVM in this particular example. Okay, that's cheating because there is no -O, as I'm guessing your statement supposed, but 22 seconds is already a huge amount of time to compile 30,000 lines of code, so unoptimized builds are relevant to claims that rustc is slow. The other points apply regardless of optimization setting.

Second: rustc will take this long every time to recompile libsyntax every time anything in it changes. If this were written in C, most changes would only require recompiling one source file, even though, again, header files are not treated well (something that Rust does not need to replicate). In practice this means that typical latency between changing something and seeing the output in a C/C++ program is an order of magnitude faster.

Third: The same separation that makes incremental compilation work in C/C++ allows parallelism (make -j) in full builds. rustc uses only one core per crate. Again, headers reduce the gains but Rust doesn't have that problem.

Fourth: If we compare to C rather than C++, we're off by sometimes an order of magnitude regardless of parallelism. Here is some random C program (Apple as), a total of 26929 lines, compiling in 0.90 seconds:

    clang -o foo -I ../include -I ../include/gnu -I. -DNeXT_MOD -DI386 -Di486      0.73s user 0.16s system 98% cpu 0.904 total
(With optimizations it is 2.426 seconds.)

Or libpng, 32433 lines in 0.83 seconds:

    clang -o png *.c -I. -lz  0.70s user 0.12s system 98% cpu 0.831 total
With the Linux kernel, compiled without -j and at -O1 using GCC (both of which make it slower), it's not an order of magnitude off, but it's still significantly faster than Rust: make ARCH=arm zImage 540.25s user 73.71s system 96% cpu 10:33.81 total

It compiled 1572713 lines of code; normalizing to 30,000 gives us about 12 seconds.

On the Rust side, linking libstd, about the same size, takes 6 seconds, but librustc, three times the size, took 216 seconds (10 times as long as libsyntax) to get to linking. So it varies, but I guess libsyntax is representative.

I do not know enough to have a definitive opinion of why this difference exists, but judging from the difference between C and C++, I wouldn't be surprised if it were related to Rust's complexity, which includes generics.

Re: Why Go Is Not Good

#255
post #154

Earlier quoted context omitted.

What is Go demonstrating about programming without generics that Lisp, Java (pre-2004), Python and tons of other languages haven't already demonstrated?

Nothing, thats the point.. its not language that the creators did because they are vain, or want to prove they are smart, or know what beauty is.. its a language that are created to get things done! the beauty of it its the same beauty that we see in Unix or C.. its simplicity.. Dear God.. I dont know why so many programming languages anyway to do the same thing all over again.. just because of the sake of the sintax…

>its a language that are created to get things done

And the hundreds of other languages serve what purpose then ?

Re: Why Go Is Not Good

#256

Earlier quoted context omitted.

Since concurrency and composition are important, why doesn't Go have support for immutable variables and monitoring/linking ? These are features proven to make it easier to reason about concurrent systems and to manage failures in a distributed system. From what I can tell it is completely impossible to implement supervisors in Go.

Immutable values will complicate a type system and implementation. The Go creators are very strict about adding features to the language without enough justification, which is one of the biggest features of the language imo. There are more synchronization features than channels in Go. Channels and switches solve most problems very well. However when another synchronization method is just simply required, check out: h…

It is fine to say you want a simple language, but then please do not talk up how great it is at concurrency. It lacks basic features common to every other language with a good concurrency story.

Re: Why Go Is Not Good

#257
post #81

Earlier quoted context omitted.

Doesn't Go have a GC? How can you then "picture what the C equivalent would look like"? Yes there are GCs for C, but is anyone successfully doing "systems programming" (whatever that may be) in C with GCs?

I don't agree with the GP, but if Go were very similar to C and the only big difference would be that C has no GC it would pretty easy to picture what the C equivalent of Go code would be. Exactly the same but with calls to `free()` at the end of some functions. (or preempted between instructions at unpredictable places) Don't make GC's a bigger deal then they are. They are a tool to remove the need to call `free()`…

> They are a tool to remove the need to call `free()` at the right time, with the downside that you don't get to control what the GC thinks is a right time instead.

That's not actually true. They also allow you to do things that you otherwise couldn't. Try implementing persistent [1] maps or sets without a GC.

[1] http://en.wikipedia.org/wiki/Persistent_data_structure

Re: Why Go Is Not Good

#258
post #50

There's something very seductive about languages like Rust or Scala or Haskell or even C++. These languages whisper in our ears "you are brilliant and here's a blank canvas where you can design the most perfect abstraction the world has ever seen." But, for systems programming, abstractions suck. They always, always have a cost. When abstractions break, you not only have to deal with a broken system but the broken ab…

I'm not writing the following to make people pick another language - if Go is suitable for your project in terms of features, runtime, tools and community, then by all means use Go. It's a fairly decent platform to target and it can further evolve to meet more stringent needs. But if we are talking about the cost of abstractions , the biggest elephant in the room is that Go's GC is NOT optional, which makes it unsuit…

> I wish developers would stop equating "complicated" to things "I don't understand".

Rich Hickey's presentation on this topic should be required viewing for everyone: http://www.infoq.com/presentations/Simple-Made-Easy

Re: Why Go Is Not Good

#259
post #50

There's something very seductive about languages like Rust or Scala or Haskell or even C++. These languages whisper in our ears "you are brilliant and here's a blank canvas where you can design the most perfect abstraction the world has ever seen." But, for systems programming, abstractions suck. They always, always have a cost. When abstractions break, you not only have to deal with a broken system but the broken ab…

I'm not writing the following to make people pick another language - if Go is suitable for your project in terms of features, runtime, tools and community, then by all means use Go. It's a fairly decent platform to target and it can further evolve to meet more stringent needs. But if we are talking about the cost of abstractions , the biggest elephant in the room is that Go's GC is NOT optional, which makes it unsuit…

>I wish developers would stop equating "complicated" to things "I don't understand".

The argument is a bit more about evolved than that, but flawed nonetheless. The argument usually invoked for Go is that, by eschewing selected language features, it prevents developers shooting themselves in the foot with unneeded complexity introduced by faulty abstractions.

I get the argument. I have seen my fair share of dug-out-from-hell complex projects. What the argument misses though is that not all abstractions are faulty. Computer science, as most science, is a game of ever increasingly abstract reasoning. If implemented correctly, the more abstract the better. The endgame is "Computer, build me a Mars round-trip ship".

Abstractions are good, when well written. They allow us to think on a higher level. Think of them as a fixed learning cost replacing a variable development cost.

Go kind of throws out the baby with the bathwater.

Re: Why Go Is Not Good

#260
post #69

Earlier quoted context omitted.

These two statements made me cringe: > But, for systems programming, abstractions suck. They always, always have a cost. > Generics? Here's another if statement, put it inside your for loop. If you care about speed (and many systems programmers do), this is exactly the opposite of what you want to do. Unlike your proposal of putting potentially-costly if-statements inside of for loops, generics/templates in c++ provi…

If you truly care about speed you'll have different optimizations for int32 and int64. Depending on who you are working with, the lack of generics is a blessing. Some developers can't restrain themselves and create over-complex abstractions that are used only once.

Generics generally simplify code, you know. Plus, generic code tend to make guarantees non-generic code cannot.

Picture this function:

  foo :: (a -> b) -> (b -> c) -> (a -> c)
What does it do?

As you can see this function takes 2 arguments, which appears to be functions. It also returns a function. The argument and return type of these functions are unknown, so you can't manipulate them. You can just pass them around directly. This puts really tight constraints on your code. So, assuming nothing fancy happens, there is only one correct body of code for this type signature:

  foo f g = \x -> g (f x)
In other words, function composition.

---

Generic functions have more guarantees than non-generic functions. Therefore, you are more likely to know what a generic function is actually doing.

Post reply on HN