Live data from Hacker News

Why Go Is Not Good

yager.io

121–130 of 367 posts

Re: Why Go Is Not Good

#121
This article presumes that everybody wants an elaborate type system. I'm not sure that is the case. I still see an elaborate type system as incidental complexity. I may be in the minority and I may not have worked in domains which benefit from such modeling. Maybe I'm stuck in a blub paradigm.

Here's my reasoning. I'm a fan of human language & domain ontologies. Word definitions are quite flexible & do not have an elaborate type system. I don't feel the need to have a provably correct logical system to have a useful conceptual tool (i.e. analogies). I enjoy ambiguity. Ambiguity can lead to paradoxes, which in turn leads to exploration & novelty.

Strongly typed systems, by default, give me the impression that the domain ontology is figured out on a highly precise level. That is never the case. You can almost always go deeper. Domain language precision is tough to model & express.

I prefer data structures to drive operations. I suppose that a schema is often useful, however I don't feel like I need the programming language to enforce the schema.

I also like to evolve the design, using tests. Tests are really examples to exercise the program's API with expected I/O.

People often equate an evolved programming language/paradigm as being better. In the case of Javascript, they point out that is was created in a few days as evidence that it's "bad". The thing about an evolved language/paradigm is it has evolved down a certain path. That often means restricting the freedom of the programmer to evolve the program down another path. I'm not picking one way to be better than another. However, I do see tradoffs to both approaches. I personally prefer a more flexible language. It can be evolved, as long as the evolution does not restrict my freedom to evolve the program.

Re: Why Go Is Not Good

#122
post #116
post #93

I just spent the weekend learning Go and writing a single writer multi-reader hashtable for threadsafe access. I picked it deliberately because it's against the philosophy of the language, which is to share by communicating instead of sharing data structures directly. It was painful to write: // Do NOT reorder this, otherwise parallel lookup could find key but see empty value atomic.StoreInt32((*int32)(unsafe.Pointer…

That map only works with keys and values both being int32, right?

Correct. I have to duplicate much of the code for in64 keys and values, the lack of generics hurts there.

Re: Why Go Is Not Good

#123
post #93

I just spent the weekend learning Go and writing a single writer multi-reader hashtable for threadsafe access. I picked it deliberately because it's against the philosophy of the language, which is to share by communicating instead of sharing data structures directly. It was painful to write: // Do NOT reorder this, otherwise parallel lookup could find key but see empty value atomic.StoreInt32((*int32)(unsafe.Pointer…

> Rust, C++, Haskell, Scala will never be good at that because they're too damn complicated (although each of them make the nasty parts a little less painful!) Why is Rust too complicated to allow you to do low-level hacking?

I mean too complicated for writing, reading, and maintaining and generally just working with from day to day. It costs too much time to do the same thing.

Re: Why Go Is Not Good

#124
post #123

Earlier quoted context omitted.

> Rust, C++, Haskell, Scala will never be good at that because they're too damn complicated (although each of them make the nasty parts a little less painful!) Why is Rust too complicated to allow you to do low-level hacking?

I mean too complicated for writing, reading, and maintaining and generally just working with from day to day. It costs too much time to do the same thing.

Again, what specifically?

I ask because this has not been my experience writing several hundreds of thousands of lines of Rust code, nor has this been the experience of anyone I have helped get up to speed. Moreover, I believe there is no feature in Rust that is not necessary to achieve safety without sacrificing performance.

Re: Why Go Is Not Good

#125
post #67
post #14

Haskell (with third party library) http://snapframework.com/docs/tutorials/snap-api main :: IO () main = quickHttpServe site site :: Snap () site = ifTop (writeBS "hello world") route [ ("foo", writeBS "bar") , ("echo/:echoparam", echoHandler) ] dir "static" (serveDirectory ".") echoHandler :: Snap () echoHandler = do param ----- Rust (with third party library) https://github.com/chris-morgan/rust-http/blob/master/sr…

Node.js, native: var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n'); }).listen(1337, '127.0.0.1'); What's the point here?

[deleted]

Re: Why Go Is Not Good

#126
post #117

Earlier quoted context omitted.

Exactly! Go makes the cost of generic code explicitly visible. Generics encourage over-generalizing behavior that runs counter to writing highly performant code. If you care about speed, you don't spend time making your code generic. You optimize closely to your use case.

>Go makes the cost of generic code explicitly visible. Generics encourage over-generalizing behavior that runs counter to writing highly performant code. I think you may be missing some info regarding generics in Rust and Haskell. As I mentioned in the article, there is zero runtime overhead for generic programming in Rust and Haskell. Zip. Zilch. Nada. That's why their constraint-based static generics system is awes…

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.

Re: Why Go Is Not Good

#127
post #54
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…

>But, for systems programming, abstractions suck. Could you clarify what you mean by "systems programming"? To me, that means working with embedded systems, which Go is certainly not appropriate for.

> Could you clarify what you mean by "systems programming"? To me, that means working with embedded systems, which Go is certainly not appropriate for.

The blunt but approximately correct version is that embedded means that you're running on hardware that isn't powerful enough to run a Linux kernel.

Systems programming just means you're working below the application layer. So if you take your laptop and write a device driver, or work on filesystem or networking code, you're doing systems programming without doing embedded.

Re: Why Go Is Not Good

#128
post #115

Earlier quoted context omitted.

I think comparisons to Haskell are not too far off the mark. Haskell is not that complicated of a language either. You can do all sorts of complicated things with it, but the language itself is relatively simple. It just has a lot of stuff that you're likely to have never seen before (extensive use of higher-order functions, higher-kinded types, etc), and its type system produces error messages that seem obscure from…

[deleted]

> Haskell is a research language; Rust is designed to be a practical language. It makes a lot of concessions to practicality, C-like syntax and imperative control flow being high among them.

Perhaps I wasn't clear in the post you're responding to: my point was that both Rust and Haskell are fairly "simple" programming languages which seem more complicated, because they introduce a lot of features which are likely to be new to those who are using it for the first time. I wasn't really comparing them as languages per se; that's a separate discussion.

> Common in any language, including Go.

Higher-order functions are common in most languages, but not in the way that Haskell does. Most languages use first-class functions as lists of instructions (do some stuff, and perform the steps in this argument). Haskell makes them truly first-class, such that they're positively ubiquitous: an example is currying, which is everywhere in Haskell and rare in most other languages; another example is monads, which are obviously a core part of Haskell and which require first-class functions (e.g. in >>=) to do anything useful. There are other examples.

> Rust does not have these.

I know; I was speaking about Haskell.

> This is because we want memory safety without performance tradeoffs (global concurrent garbage collection).

Right; it's a perfectly understandable thing to have, but it's not something that (to my knowledge) exists in any other mainstream language. It's an example of something in Rust which is obscure to newcomers.

> Could you elaborate?

I'd have to write some code and run the compiler to get the actual error message, but I recall getting errors about using some reference outside of a context or something. In my fuzzy recollection, it would be something like where I had written `match foo { a => b; c => d}` and I would get some error message which would be fixed by writing `let foo1 = foo; match foo1 {a => b; c => d}`. Unfortunately I don't remember the specifics, but long story short: compiling Rust code produces a lot of very strange error messages to someone unfamiliar with the language. :) In this way it's not dissimilar from Haskell.

> This is because dynamically-sized types are not yet implemented, but they will be for 1.0.

Great to know! If only there were a more helpful error message than "Bare str is not a type." :)

Re: Why Go Is Not Good

#129
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…

> 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."

These languages have built-in abstraction tools (templates) that you can use to create your own abstractions. What I like about Go is the abstraction tools are primitive and allow for consistent & precise expression. The expression may not be as concise in certain cases, however, you can build in the mechanisms into your architecture.

> 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 abstraction itself too. (Anyone who has ever seen a gcc compiler error for C++ knows how this feels.)

That is why custom abstractions to your problem domain are important. A framework or a language with lots of features will get you started quickly by providing out-of-the-box tools that you can hang your program architecture on. However, I prefer to have a custom architecture & idioms which are appropriate to the current domain & evolution of the domain.

Re: Why Go Is Not Good

#130

Earlier quoted context omitted.

If Go has a slogan that slogan is "Frictionless Development". It's easily the simplest, least annoying, and most "get out of your way" language I've ever used. I suspect this is where many philosophical differences in these discussions originate. I appreciate the value of having quick and easy tools, but for production software where I care about quality, I don't want the language to get out of my way if I'm doing so…

I doubt that null pointers lead to security vulnerabilities. Panics, yes; worse performance, yes; vulnerabilities, unlikely. Null pointers are not dangling or wild pointers, which are the problematic ones.

You might want to google dereference null pointer code execution. Go regresses language design, because it allows constructs that have been proven to fail and are already fixed in other languages.

This has nothing to do with shiny features of the newest language or whether language A or B is someone's favorite. This has to do with program correctness.

Post reply on HN