Live data from Hacker News

I want off Mr. Golang’s Wild Ride (2020)

fasterthanli.me

261–270 of 477 posts

Re: I want off Mr. Golang’s Wild Ride (2020)

#261

Earlier quoted context omitted.

> For example, Go error handling is shit What is bad about it?

Errors as return values is only acceptable for code that is so performance-sensitive that you aren't allowed to do dynamic memory allocations. For everything else, conditions+restarts are the correct answer, because errors-as-values restricts you to a single error-handling strategy and couples high-level code to low-level code as a result.

> Errors as return values is only acceptable for code that is so performance-sensitive that you aren't allowed to do dynamic memory allocations.

Exceptions-based code can be zero-cost, if no errors occur, at an increased error-case cost. Using error values pessimises this, and increase branch prediction load (as every callsite is now a branch).

So in the common case where errors are extremely rare, exceptions-based error handling can be quite a bit faster than return-value error handling.

Which doesn't mean it's preferable, but beware thinking that return values are faster.

Re: I want off Mr. Golang’s Wild Ride (2020)

#262
This is a long blog post which is a huge rant, and honestly I find the whole tone extremely unproductive.

# Point 1: Judging a tool (programming language) out of context (project)

For some reason programmers really like to talk about the merits of programming languages without specifying anything about the context you're using it in. This article talks a lot about how Go handles its Windows support, yet the conclusion is not "I'm done using Go for projects that require Windows support". No, the conclusion is "Go is bad".

I've seen this "argumentation" so many times:

- "I used programming language X on project Y."

- "Programming language Z works much better for project Y."

- "Therefore Z is better than X."

We should talk more about when it makes sense to use a certain programming language instead, and less about trying to declare that a language is "stupid" or "worse than another".

# Point 2: Simplicity is about assumptions

The article has a nice catchy headline called "Simple is a lie". Ironically it immediately points out that the statement "Simple is a lie" is also a lie: "Or rather, it's a half-truth that conveniently covers up the fact that, when you make something simple, you move complexity elsewhere."

Go models the world from a Unix perspective, and it provides a compatibility layer for Windows. This means that …

… if you run it on Unix, everything will behave as expected.

… if you use the basic functionality on Windows, everything will behave as expected.

… if you use functionality which does not make sense on Windows, it will try to fake it and it will kinda make sense.

… you can't idiomatically take advantage of Windows-only features.

This is a simple model. And there's nothing about this simplification which is a "lie" or a "half-truth": It's simple for a programmer to program against this model.

This is of course not a universal model. It's a model which works great if you're only developing against modern Linux and MacOS. It's a model which works if you want to support basic functionality on Windows as well. It's a model which will cause your program to behave weirdly on Windows in many edge cases. And those "edge cases" might be more common in the real world than you think.

The article spends a lot time showing how Go's model break apart on Windows. And yes, that is indeed the cost of a simpler model: When you don't follow the assumptions then unexpected things will happen. At this point the conclusion could be "don't use Go if you need Windows support", but for some reason the article instead brings in another language (Rust) and starts showing how Rust is solving this "better" than Go. (Spoiler alert: They introduce their own abstraction instead.) And there's still no context: Are we only talking about programs that need to run on Windows? Are we talking about all programs that you can write in Go? Are they trying to demonstrate that Rust is a "better" language even when I'm concerned about a Unix command-line tool?

# Point 3: The monotonic clock

Turns out there's really hard for a programming language to guarantee a monotonic clock (see Rust). Go's take a simpler approach: If you need a monotonic clock then it's up to the OS to take care of it. Is it a good solution or a bad solution? I dunno. It seems pretty reasonable to expect that the OS can take care of it. I can't really come up with any project in Go where this has impacted me in any possible way.

Re: I want off Mr. Golang’s Wild Ride (2020)

#263

Earlier quoted context omitted.

I can't relate. Newline characters have never been burdensome to me, and they aid in visual structure (the control flow is represented by the visual structure of the program, not only for "good data" paths, but also for error paths). My programming problems are usually not related to localized keystroke boilerplate, but rather larger issues of abstraction and data modeling. > My current project is in the k8s ecosyste…

Well, if you don't know the structure of a resource ahead of time but know that it has a status.ready, I would think that would be a candidate for a generic? I haven't explored that much yet, but in retrospect I might even be able to convert all objects to a struct that has only status.ready without generics. I've only been in the ecosystem 6 months, but yeah larger abstractions are difficult too. I'm not a fan of th…

Go's interfaces work fine for this case (see below), and Go's generics wouldn't help you (generic constraints operate on methods, not fields).

    type Resource interface {
        Status() Status
    }

    type Status interface {
        Ready() bool
    }
> I'm not a fan of the lack of sub-classing. I like writing a base class and concrete one, and it's quite difficult in Go unless you want to make everything an interface.

I've written a lot of Python, C++, Java, etc in my life (I cut my teeth on OOP). I'm thoroughly persuaded that inheritance is almost never better than composition, even in those languages where inheritance is idiomatic. Indeed, the trend in most of those languages has been away from inheritance and toward composition. Certainly in Go you'll be fighting an uphill battle by trying to make everything maximally abstract (which is a big part of why the k8s framework is so complicated per my earlier post).

Re: I want off Mr. Golang’s Wild Ride (2020)

#264
post #252

Earlier quoted context omitted.

What an extremely convenient template to dismiss any nuanced argument against "worse is better". You even get to question my credentials a couple times! (I apparently pick metrics that are convenient to my argument, and fundamentally misunderstand programming language design). Even if I accept the premise that "I'm challenging Go on things it doesn't promise to deliver" (which is disingenuous to begin with — correctn…

Can you see the value in being able to create software more quickly, at the expense of the software's stability?

Yes, but that is definitely not achieved by checking for errors every second line.

Re: I want off Mr. Golang’s Wild Ride (2020)

#265
post #105
post #47

Earlier quoted context omitted.

It requires several additional lines of code just to bubble up an error, for starters, and there's nothing stopping you from ignoring errors and continuing with what could easily be corrupt data.

"there's nothing stopping you from ignoring errors and continuing with what could easily be corrupt data." In theory, this is a big deal. In practice, it doesn't seem to be a problem. I've neither hit this very often myself, nor have I seen even newbies have much problem with it. A lot of error handling procedures are based on reacting to C, which was awful. You could call a function, and then have to call another fu…

I've ran into bugs multiple times because I ignored an error result, or overwrote the "err" variable and swallowed an error. Errcheck helps a bit.

Other languages that have exceptions that bubble up the stack have a few advantages (easier to instrument with monitoring, stack traces and line numbers out of the box) but developers often misuse error handling as flow control

Re: I want off Mr. Golang’s Wild Ride (2020)

#266
post #72

Earlier quoted context omitted.

Rust's approach is definitely safer, but my point is that the concerns are overblown. The Go compiler raise an error if a variable (error) goes unused, and just ignoring this error by naming it "_" is obviously dangerous. Yes, Rust makes it easier to never ignore an error, but I don't think I've ever accidentally ignored an error that I shouldn't have in Go.

Golang gives you freedom. Rust gives you seat belts. It depends on you what you value more.

Yes nothing says "the language gives you freedom" like an unused import being a non-bypassable compilation error.

Re: I want off Mr. Golang’s Wild Ride (2020)

#267

Earlier quoted context omitted.

Go's equivalent of sub-classing is embedding

Yeah, and I kind of did that. But I've found it annoying and not great. For example in the base struct I had an interface and a ton of methods that use it. Then when I declared the concrete struct, I have to manually point the concrete type that matches that interface to the base class's interface. Composition doesn't really allow the same thing as inheritance. Composition typically means you'll have a motor and whee…

Seems pretty straightforward to me:

    type Car struct {
        Motor Motor
        Wheels [4]Wheel
    }

    type Motor interface {
        Rev()
    }

    type KiaMotor struct { ... }

    func (kia *KiaMotor) Rev() {}

    func NewKiaCar() Car {
        return Car{Motor: &KiaMotor{ ... }}
    }

Re: I want off Mr. Golang’s Wild Ride (2020)

#268
post #199

Earlier quoted context omitted.

Yes, you just needed to search for Lang NEXT 2014 and Rob Pike. Enjoy the video, https://youtu.be/YM7QYx-LPSA "The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software.…

> https://youtu.be/YM7QYx-LPSA That link is to a panel Rob Pike participated in at the same conference. I'm not sure if he makes similar remarks during that panel, but that "fairly young, fresh out of school" quote specifically comes from Rob Pike's presentation at the same conference titled From Parallel to Concurrent , which you can watch here: https://www.youtube.com/watch?v=iTrP_EmGNmw

You're right, thanks for the correction.

Re: I want off Mr. Golang’s Wild Ride (2020)

#269

Earlier quoted context omitted.

Then you wouldn't really be programming in Go. You'd be programming in whatever franenkstein's monster of a language your preprocessor is using. Preprocessors are a code smell, and indicate that the language you are using lacks the right abstractions for productive programming.

> and indicate that the language you are using lacks the right abstractions for productive programming. Indeed go did not have generics, in fact that's explicitly stated in the post I was responding to: "at the time the lack of generics made it so that you either had to use reflection - or implement the same function N times over to support the different numeric data types" So, you unthinking prat, what do you recomm…

> So, you unthinking prat, what do you recommend he should have done, carried on coding much near-duplicate code by hand or get the computer to do the repetitive job infinitely faster and more safely?

No, my recommendation would be to use a different language that doesn't need a preprocessor.

Use any more insults and I'm just going to flag you.

Re: I want off Mr. Golang’s Wild Ride (2020)

#270

Earlier quoted context omitted.

Serializing a request structure, making an IPC/network call, deserializing the request structure, serializing the response structure, sending it back, and deserializing it ... isn't really a solution when the purpose of an FFI call is typically to fix some performance issue. Lots of garbage-collected languages make FFI not only easy but plenty fast. Go does neither.

I started out thinking that fast and easy FFI was ideal and being disappointed that Go's FFI was neither. I've since changed my opinion as it's really nice that one can usually get away without pulling any C dependencies into their dependency tree. I wrote more in the sibling comment: https://news.ycombinator.com/item?id=31194347

> I've since changed my opinion as it's really nice that one can usually get away without pulling any C dependencies into their dependency tree.

That trophy is owned entirely by the Java ecosystem. Thanks to that, once Loom arrives, basically the whole ecosystem will automagically become reactive-aware.

Post reply on HN